mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-25 17:46:44 +00:00
ensure unique stonewall input txids for entire tx (not just per set)
This commit is contained in:
parent
d1088fe9ee
commit
20f4ac9657
1 changed files with 19 additions and 16 deletions
|
@ -21,18 +21,31 @@ public class StonewallUtxoSelector implements UtxoSelector {
|
||||||
public List<Collection<BlockTransactionHashIndex>> selectSets(long targetValue, Collection<OutputGroup> candidates) {
|
public List<Collection<BlockTransactionHashIndex>> selectSets(long targetValue, Collection<OutputGroup> candidates) {
|
||||||
long actualTargetValue = targetValue + noInputsFee;
|
long actualTargetValue = targetValue + noInputsFee;
|
||||||
|
|
||||||
List<OutputGroup> preferredCandidates = candidates.stream().filter(outputGroup -> outputGroup.getScriptType().equals(preferredScriptType)).collect(Collectors.toList());
|
List<OutputGroup> uniqueCandidates = new ArrayList<>();
|
||||||
|
for(OutputGroup candidate : candidates) {
|
||||||
|
OutputGroup existingTxGroup = getTransactionAlreadySelected(uniqueCandidates, candidate);
|
||||||
|
if(existingTxGroup != null) {
|
||||||
|
if(candidate.getValue() > existingTxGroup.getValue()) {
|
||||||
|
uniqueCandidates.remove(existingTxGroup);
|
||||||
|
uniqueCandidates.add(candidate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uniqueCandidates.add(candidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OutputGroup> preferredCandidates = uniqueCandidates.stream().filter(outputGroup -> outputGroup.getScriptType().equals(preferredScriptType)).collect(Collectors.toList());
|
||||||
List<Collection<BlockTransactionHashIndex>> preferredSets = selectSets(targetValue, preferredCandidates, actualTargetValue);
|
List<Collection<BlockTransactionHashIndex>> preferredSets = selectSets(targetValue, preferredCandidates, actualTargetValue);
|
||||||
if(!preferredSets.isEmpty()) {
|
if(!preferredSets.isEmpty()) {
|
||||||
return preferredSets;
|
return preferredSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectSets(targetValue, candidates, actualTargetValue);
|
return selectSets(targetValue, uniqueCandidates, actualTargetValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Collection<BlockTransactionHashIndex>> selectSets(long targetValue, Collection<OutputGroup> candidates, long actualTargetValue) {
|
private List<Collection<BlockTransactionHashIndex>> selectSets(long targetValue, List<OutputGroup> uniqueCandidates, long actualTargetValue) {
|
||||||
for(int i = 0; i < 10; i++) {
|
for(int i = 0; i < 15; i++) {
|
||||||
List<OutputGroup> randomized = new ArrayList<>(candidates);
|
List<OutputGroup> randomized = new ArrayList<>(uniqueCandidates);
|
||||||
Collections.shuffle(randomized, random);
|
Collections.shuffle(randomized, random);
|
||||||
|
|
||||||
List<OutputGroup> set1 = new ArrayList<>();
|
List<OutputGroup> set1 = new ArrayList<>();
|
||||||
|
@ -53,17 +66,7 @@ public class StonewallUtxoSelector implements UtxoSelector {
|
||||||
long selectedValue = 0;
|
long selectedValue = 0;
|
||||||
while(selectedValue <= targetValue && !randomized.isEmpty()) {
|
while(selectedValue <= targetValue && !randomized.isEmpty()) {
|
||||||
OutputGroup candidate = randomized.remove(0);
|
OutputGroup candidate = randomized.remove(0);
|
||||||
|
selectedSet.add(candidate);
|
||||||
OutputGroup existingTxGroup = getTransactionAlreadySelected(selectedSet, candidate);
|
|
||||||
if(existingTxGroup != null) {
|
|
||||||
if(candidate.getValue() > existingTxGroup.getValue()) {
|
|
||||||
selectedSet.remove(existingTxGroup);
|
|
||||||
selectedSet.add(candidate);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
selectedSet.add(candidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedValue = selectedSet.stream().mapToLong(OutputGroup::getEffectiveValue).sum();
|
selectedValue = selectedSet.stream().mapToLong(OutputGroup::getEffectiveValue).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue