mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-11-02 20:36:44 +00:00
reduce server calls on opening a transaction tab by using open wallet history when performing spent output lookup
This commit is contained in:
parent
57dba5d6ae
commit
02a0a3277b
2 changed files with 66 additions and 20 deletions
|
@ -504,19 +504,19 @@ public class ElectrumServer {
|
|||
}
|
||||
}
|
||||
|
||||
public List<Set<BlockTransactionHash>> getOutputTransactionReferences(Transaction transaction, int indexStart, int indexEnd) throws ServerException {
|
||||
public List<Set<BlockTransactionHash>> getOutputTransactionReferences(Transaction transaction, int indexStart, int indexEnd, List<Set<BlockTransactionHash>> blockTransactionHashes) throws ServerException {
|
||||
try {
|
||||
Map<String, String> pathScriptHashes = new LinkedHashMap<>();
|
||||
for(int i = indexStart; i < transaction.getOutputs().size() && i < indexEnd; i++) {
|
||||
if(blockTransactionHashes.get(i) == null) {
|
||||
TransactionOutput output = transaction.getOutputs().get(i);
|
||||
pathScriptHashes.put(Integer.toString(i), getScriptHash(output));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, ScriptHashTx[]> result = electrumServerRpc.getScriptHashHistory(getTransport(), null, pathScriptHashes, false);
|
||||
|
||||
List<Set<BlockTransactionHash>> blockTransactionHashes = new ArrayList<>(transaction.getOutputs().size());
|
||||
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||
blockTransactionHashes.add(null);
|
||||
Map<String, ScriptHashTx[]> result = new HashMap<>();
|
||||
if(!pathScriptHashes.isEmpty()) {
|
||||
result = electrumServerRpc.getScriptHashHistory(getTransport(), null, pathScriptHashes, false);
|
||||
}
|
||||
|
||||
for(String index : result.keySet()) {
|
||||
|
@ -1571,17 +1571,26 @@ public class ElectrumServer {
|
|||
private final Transaction transaction;
|
||||
private final int indexStart;
|
||||
private final int indexEnd;
|
||||
|
||||
public TransactionOutputsReferenceService(Transaction transaction) {
|
||||
this.transaction = transaction;
|
||||
this.indexStart = 0;
|
||||
this.indexEnd = transaction.getOutputs().size();
|
||||
}
|
||||
private final List<Set<BlockTransactionHash>> blockTransactionHashes;
|
||||
private final Map<Sha256Hash, BlockTransaction> transactionMap;
|
||||
|
||||
public TransactionOutputsReferenceService(Transaction transaction, int indexStart, int indexEnd) {
|
||||
this.transaction = transaction;
|
||||
this.indexStart = Math.min(transaction.getOutputs().size(), indexStart);
|
||||
this.indexEnd = Math.min(transaction.getOutputs().size(), indexEnd);
|
||||
this.blockTransactionHashes = new ArrayList<>(transaction.getOutputs().size());
|
||||
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||
blockTransactionHashes.add(null);
|
||||
}
|
||||
this.transactionMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public TransactionOutputsReferenceService(Transaction transaction, int indexStart, int indexEnd, List<Set<BlockTransactionHash>> blockTransactionHashes, Map<Sha256Hash, BlockTransaction> transactionMap) {
|
||||
this.transaction = transaction;
|
||||
this.indexStart = Math.min(transaction.getOutputs().size(), indexStart);
|
||||
this.indexEnd = Math.min(transaction.getOutputs().size(), indexEnd);
|
||||
this.blockTransactionHashes = blockTransactionHashes;
|
||||
this.transactionMap = transactionMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1589,7 +1598,7 @@ public class ElectrumServer {
|
|||
return new Task<>() {
|
||||
protected List<BlockTransaction> call() throws ServerException {
|
||||
ElectrumServer electrumServer = new ElectrumServer();
|
||||
List<Set<BlockTransactionHash>> outputTransactionReferences = electrumServer.getOutputTransactionReferences(transaction, indexStart, indexEnd);
|
||||
List<Set<BlockTransactionHash>> outputTransactionReferences = electrumServer.getOutputTransactionReferences(transaction, indexStart, indexEnd, blockTransactionHashes);
|
||||
|
||||
Set<BlockTransactionHash> setReferences = new HashSet<>();
|
||||
for(Set<BlockTransactionHash> outputReferences : outputTransactionReferences) {
|
||||
|
@ -1599,16 +1608,16 @@ public class ElectrumServer {
|
|||
}
|
||||
setReferences.remove(null);
|
||||
setReferences.remove(UNFETCHABLE_BLOCK_TRANSACTION);
|
||||
setReferences.removeIf(ref -> transactionMap.get(ref.getHash()) != null);
|
||||
|
||||
List<BlockTransaction> blockTransactions = new ArrayList<>(transaction.getOutputs().size());
|
||||
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||
blockTransactions.add(null);
|
||||
}
|
||||
|
||||
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
|
||||
if(!setReferences.isEmpty()) {
|
||||
Map<Integer, BlockHeader> blockHeaderMap = electrumServer.getBlockHeaders(null, setReferences);
|
||||
transactionMap = electrumServer.getTransactions(null, setReferences, blockHeaderMap);
|
||||
transactionMap.putAll(electrumServer.getTransactions(null, setReferences, blockHeaderMap));
|
||||
}
|
||||
|
||||
for(int i = 0; i < outputTransactionReferences.size(); i++) {
|
||||
|
|
|
@ -5,8 +5,7 @@ import com.sparrowwallet.drongo.protocol.*;
|
|||
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||
import com.sparrowwallet.drongo.psbt.PSBTOutput;
|
||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.drongo.wallet.*;
|
||||
import com.sparrowwallet.sparrow.AppServices;
|
||||
import com.sparrowwallet.sparrow.EventManager;
|
||||
import com.sparrowwallet.sparrow.TransactionTabData;
|
||||
|
@ -33,6 +32,7 @@ import java.io.IOException;
|
|||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class TransactionController implements Initializable {
|
||||
private static final Logger log = LoggerFactory.getLogger(TransactionController.class);
|
||||
|
@ -426,7 +426,44 @@ public class TransactionController implements Initializable {
|
|||
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
||||
if(AppServices.isConnected() && getPSBT() == null && indexStart < getTransaction().getOutputs().size()) {
|
||||
int maxIndex = Math.min(getTransaction().getOutputs().size(), indexEnd);
|
||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), indexStart, maxIndex);
|
||||
|
||||
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
|
||||
List<Set<BlockTransactionHash>> blockTransactionHashes = new ArrayList<>(getTransaction().getOutputs().size());
|
||||
for(int i = 0; i < getTransaction().getOutputs().size(); i++) {
|
||||
blockTransactionHashes.add(null);
|
||||
}
|
||||
|
||||
Map<Script, WalletNode> openWalletOutputScripts = new HashMap<>();
|
||||
for(Wallet wallet : AppServices.get().getOpenWallets().keySet()) {
|
||||
openWalletOutputScripts.putAll(wallet.getWalletOutputScripts());
|
||||
for(Wallet childWallet : wallet.getChildWallets()) {
|
||||
if(!childWallet.isNested()) {
|
||||
openWalletOutputScripts.putAll(childWallet.getWalletOutputScripts());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = indexStart; i < getTransaction().getOutputs().size() && i < maxIndex; i++) {
|
||||
TransactionOutput output = getTransaction().getOutputs().get(i);
|
||||
List<ScriptChunk> chunks = output.getScript().getChunks();
|
||||
if(!chunks.isEmpty() && chunks.get(0).isOpCode() && chunks.get(0).getOpcode() == ScriptOpCodes.OP_RETURN) {
|
||||
blockTransactionHashes.set(i, Collections.emptySet());
|
||||
} else if(openWalletOutputScripts.get(output.getScript()) != null) {
|
||||
WalletNode walletNode = openWalletOutputScripts.get(output.getScript());
|
||||
if(walletNode != null) {
|
||||
Set<BlockTransactionHash> references = walletNode.getTransactionOutputs().stream().flatMap(txo -> txo.isSpent() ? Stream.of(txo.getSpentBy()) : Stream.empty()).collect(Collectors.toCollection(TreeSet::new));
|
||||
blockTransactionHashes.set(i, references);
|
||||
for(BlockTransactionHash reference : references) {
|
||||
BlockTransaction blkTx = walletNode.getWallet().getWalletTransaction(reference.getHash());
|
||||
if(blkTx != null) {
|
||||
transactionMap.put(reference.getHash(), blkTx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), indexStart, maxIndex, blockTransactionHashes, transactionMap);
|
||||
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
||||
List<BlockTransaction> outputTransactions = transactionOutputsReferenceService.getValue();
|
||||
Platform.runLater(() -> {
|
||||
|
|
Loading…
Reference in a new issue