add wallet to wallethistorystatusevent and filter updates

This commit is contained in:
Craig Raw 2020-11-13 12:44:27 +02:00
parent 0b9052dee9
commit bf6fbebd9e
7 changed files with 67 additions and 51 deletions

View file

@ -38,18 +38,21 @@ public class CoinTreeTable extends TreeTableView<Entry> {
}
public void updateHistoryStatus(WalletHistoryStatusEvent event) {
Platform.runLater(() -> {
if(event.getErrorMessage() != null) {
setPlaceholder(new Label("Error loading transactions: " + event.getErrorMessage()));
} else if(event.isLoading()) {
if(event.getStatusMessage() != null) {
setPlaceholder(new Label(event.getStatusMessage() + "..."));
Entry entry = getRoot().getValue();
if(entry != null && event.getWallet() != null && entry.getWallet() == event.getWallet()) {
Platform.runLater(() -> {
if(event.getErrorMessage() != null) {
setPlaceholder(new Label("Error loading transactions: " + event.getErrorMessage()));
} else if(event.isLoading()) {
if(event.getStatusMessage() != null) {
setPlaceholder(new Label(event.getStatusMessage() + "..."));
} else {
setPlaceholder(new Label("Loading transactions..."));
}
} else {
setPlaceholder(new Label("Loading transactions..."));
setPlaceholder(new Label("No transactions"));
}
} else {
setPlaceholder(new Label("No transactions"));
}
});
});
}
}
}

View file

@ -1,28 +1,38 @@
package com.sparrowwallet.sparrow.event;
import com.sparrowwallet.drongo.wallet.Wallet;
public class WalletHistoryStatusEvent {
private final Wallet wallet;
private final boolean loaded;
private final String statusMessage;
private final String errorMessage;
public WalletHistoryStatusEvent(boolean loaded) {
public WalletHistoryStatusEvent(Wallet wallet, boolean loaded) {
this.wallet = wallet;
this.loaded = loaded;
this.statusMessage = null;
this.errorMessage = null;
}
public WalletHistoryStatusEvent(boolean loaded, String statusMessage) {
public WalletHistoryStatusEvent(Wallet wallet,boolean loaded, String statusMessage) {
this.wallet = wallet;
this.loaded = false;
this.statusMessage = statusMessage;
this.errorMessage = null;
}
public WalletHistoryStatusEvent(String errorMessage) {
public WalletHistoryStatusEvent(Wallet wallet,String errorMessage) {
this.wallet = wallet;
this.loaded = false;
this.statusMessage = null;
this.errorMessage = errorMessage;
}
public Wallet getWallet() {
return wallet;
}
public boolean isLoading() {
return !loaded;
}

View file

@ -6,6 +6,7 @@ import com.github.arteam.simplejsonrpc.client.builder.BatchRequestBuilder;
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcBatchException;
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcException;
import com.sparrowwallet.drongo.protocol.Sha256Hash;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
import org.slf4j.Logger;
@ -69,10 +70,10 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
@Override
@SuppressWarnings("unchecked")
public Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError) {
public Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError) {
JsonRpcClient client = new JsonRpcClient(transport);
BatchRequestBuilder<String, ScriptHashTx[]> batchRequest = client.createBatchRequest().keysType(String.class).returnType(ScriptHashTx[].class);
EventManager.get().post(new WalletHistoryStatusEvent(false, "Loading transactions"));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Loading transactions"));
for(String path : pathScriptHashes.keySet()) {
batchRequest.add(path, "blockchain.scripthash.get_history", pathScriptHashes.get(path));
@ -98,7 +99,7 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
@Override
@SuppressWarnings("unchecked")
public Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError) {
public Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError) {
JsonRpcClient client = new JsonRpcClient(transport);
BatchRequestBuilder<String, ScriptHashTx[]> batchRequest = client.createBatchRequest().keysType(String.class).returnType(ScriptHashTx[].class);
@ -125,10 +126,10 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<String, String> subscribeScriptHashes(Transport transport, Map<String, String> pathScriptHashes) {
public Map<String, String> subscribeScriptHashes(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes) {
JsonRpcClient client = new JsonRpcClient(transport);
BatchRequestBuilder<String, String> batchRequest = client.createBatchRequest().keysType(String.class).returnType(String.class);
EventManager.get().post(new WalletHistoryStatusEvent(false, "Finding transactions"));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Finding transactions"));
for(String path : pathScriptHashes.keySet()) {
batchRequest.add(path, "blockchain.scripthash.subscribe", pathScriptHashes.get(path));
@ -146,10 +147,10 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
@Override
@SuppressWarnings("unchecked")
public Map<Integer, String> getBlockHeaders(Transport transport, Set<Integer> blockHeights) {
public Map<Integer, String> getBlockHeaders(Transport transport, Wallet wallet, Set<Integer> blockHeights) {
JsonRpcClient client = new JsonRpcClient(transport);
BatchRequestBuilder<Integer, String> batchRequest = client.createBatchRequest().keysType(Integer.class).returnType(String.class);
EventManager.get().post(new WalletHistoryStatusEvent(false, "Retrieving blocks"));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Retrieving blocks"));
for(Integer height : blockHeights) {
batchRequest.add(height, "blockchain.block.header", height);
@ -166,10 +167,10 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
@Override
@SuppressWarnings("unchecked")
public Map<String, String> getTransactions(Transport transport, Set<String> txids) {
public Map<String, String> getTransactions(Transport transport, Wallet wallet, Set<String> txids) {
JsonRpcClient client = new JsonRpcClient(transport);
BatchRequestBuilder<String, String> batchRequest = client.createBatchRequest().keysType(String.class).returnType(String.class);
EventManager.get().post(new WalletHistoryStatusEvent(false, "Retrieving transactions"));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Retrieving transactions"));
for(String txid : txids) {
batchRequest.add(txid, "blockchain.transaction.get", txid);

View file

@ -224,7 +224,7 @@ public class ElectrumServer {
}
//Even if we have some successes, failure to retrieve all references will result in an incomplete wallet history. Don't proceed if that's the case.
Map<String, ScriptHashTx[]> result = electrumServerRpc.getScriptHashHistory(getTransport(), pathScriptHashes, true);
Map<String, ScriptHashTx[]> result = electrumServerRpc.getScriptHashHistory(getTransport(), wallet, pathScriptHashes, true);
for(String path : result.keySet()) {
ScriptHashTx[] txes = result.get(path);
@ -298,7 +298,7 @@ public class ElectrumServer {
return;
}
Map<String, String> result = electrumServerRpc.subscribeScriptHashes(getTransport(), pathScriptHashes);
Map<String, String> result = electrumServerRpc.subscribeScriptHashes(getTransport(), wallet, pathScriptHashes);
for(String path : result.keySet()) {
String status = result.get(path);
@ -332,7 +332,7 @@ public class ElectrumServer {
pathScriptHashes.put(Integer.toString(i), getScriptHash(output));
}
Map<String, ScriptHashTx[]> result = electrumServerRpc.getScriptHashHistory(getTransport(), pathScriptHashes, false);
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++) {
@ -384,8 +384,8 @@ public class ElectrumServer {
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
if(!references.isEmpty()) {
Map<Integer, BlockHeader> blockHeaderMap = getBlockHeaders(references);
transactionMap = getTransactions(references, blockHeaderMap);
Map<Integer, BlockHeader> blockHeaderMap = getBlockHeaders(wallet, references);
transactionMap = getTransactions(wallet, references, blockHeaderMap);
}
if(!transactionMap.equals(wallet.getTransactions())) {
@ -393,7 +393,7 @@ public class ElectrumServer {
}
}
public Map<Integer, BlockHeader> getBlockHeaders(Set<BlockTransactionHash> references) throws ServerException {
public Map<Integer, BlockHeader> getBlockHeaders(Wallet wallet, Set<BlockTransactionHash> references) throws ServerException {
try {
Set<Integer> blockHeights = new TreeSet<>();
for(BlockTransactionHash reference : references) {
@ -406,7 +406,7 @@ public class ElectrumServer {
return Collections.emptyMap();
}
Map<Integer, String> result = electrumServerRpc.getBlockHeaders(getTransport(), blockHeights);
Map<Integer, String> result = electrumServerRpc.getBlockHeaders(getTransport(), wallet, blockHeights);
Map<Integer, BlockHeader> blockHeaderMap = new TreeMap<>();
for(Integer height : result.keySet()) {
@ -428,7 +428,7 @@ public class ElectrumServer {
}
}
public Map<Sha256Hash, BlockTransaction> getTransactions(Set<BlockTransactionHash> references, Map<Integer, BlockHeader> blockHeaderMap) throws ServerException {
public Map<Sha256Hash, BlockTransaction> getTransactions(Wallet wallet, Set<BlockTransactionHash> references, Map<Integer, BlockHeader> blockHeaderMap) throws ServerException {
try {
Set<BlockTransactionHash> checkReferences = new TreeSet<>(references);
@ -437,7 +437,7 @@ public class ElectrumServer {
txids.add(reference.getHashAsString());
}
Map<String, String> result = electrumServerRpc.getTransactions(getTransport(), txids);
Map<String, String> result = electrumServerRpc.getTransactions(getTransport(), wallet, txids);
String strErrorTx = Sha256Hash.ZERO_HASH.toString();
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
@ -946,8 +946,8 @@ public class ElectrumServer {
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
if(!setReferences.isEmpty()) {
Map<Integer, BlockHeader> blockHeaderMap = electrumServer.getBlockHeaders(setReferences);
transactionMap = electrumServer.getTransactions(setReferences, blockHeaderMap);
Map<Integer, BlockHeader> blockHeaderMap = electrumServer.getBlockHeaders(null, setReferences);
transactionMap = electrumServer.getTransactions(null, setReferences, blockHeaderMap);
}
for(int i = 0; i < outputTransactionReferences.size(); i++) {

View file

@ -1,6 +1,7 @@
package com.sparrowwallet.sparrow.net;
import com.github.arteam.simplejsonrpc.client.Transport;
import com.sparrowwallet.drongo.wallet.Wallet;
import java.util.List;
import java.util.Map;
@ -15,15 +16,15 @@ public interface ElectrumServerRpc {
BlockHeaderTip subscribeBlockHeaders(Transport transport);
Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError);
Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError);
Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError);
Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError);
Map<String, String> subscribeScriptHashes(Transport transport, Map<String, String> pathScriptHashes);
Map<String, String> subscribeScriptHashes(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes);
Map<Integer, String> getBlockHeaders(Transport transport, Set<Integer> blockHeights);
Map<Integer, String> getBlockHeaders(Transport transport, Wallet wallet, Set<Integer> blockHeights);
Map<String, String> getTransactions(Transport transport, Set<String> txids);
Map<String, String> getTransactions(Transport transport, Wallet wallet, Set<String> txids);
Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids, String scriptHash);

View file

@ -6,6 +6,7 @@ import com.github.arteam.simplejsonrpc.client.exception.JsonRpcException;
import com.sparrowwallet.drongo.Utils;
import com.sparrowwallet.drongo.protocol.Sha256Hash;
import com.sparrowwallet.drongo.protocol.Transaction;
import com.sparrowwallet.drongo.wallet.Wallet;
import com.sparrowwallet.sparrow.AppController;
import com.sparrowwallet.sparrow.EventManager;
import com.sparrowwallet.sparrow.event.WalletHistoryStatusEvent;
@ -69,12 +70,12 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError) {
public Map<String, ScriptHashTx[]> getScriptHashHistory(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError) {
JsonRpcClient client = new JsonRpcClient(transport);
Map<String, ScriptHashTx[]> result = new LinkedHashMap<>();
for(String path : pathScriptHashes.keySet()) {
EventManager.get().post(new WalletHistoryStatusEvent(false, "Loading transactions for " + path));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Loading transactions for " + path));
try {
ScriptHashTx[] scriptHashTxes = new RetryLogic<ScriptHashTx[]>(MAX_RETRIES, RETRY_DELAY, List.of(IllegalStateException.class, IllegalArgumentException.class)).getResult(() ->
client.createRequest().returnAs(ScriptHashTx[].class).method("blockchain.scripthash.get_history").id(path + "-" + idCounter.incrementAndGet()).params(pathScriptHashes.get(path)).execute());
@ -92,7 +93,7 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Map<String, String> pathScriptHashes, boolean failOnError) {
public Map<String, ScriptHashTx[]> getScriptHashMempool(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes, boolean failOnError) {
JsonRpcClient client = new JsonRpcClient(transport);
Map<String, ScriptHashTx[]> result = new LinkedHashMap<>();
@ -114,12 +115,12 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<String, String> subscribeScriptHashes(Transport transport, Map<String, String> pathScriptHashes) {
public Map<String, String> subscribeScriptHashes(Transport transport, Wallet wallet, Map<String, String> pathScriptHashes) {
JsonRpcClient client = new JsonRpcClient(transport);
Map<String, String> result = new LinkedHashMap<>();
for(String path : pathScriptHashes.keySet()) {
EventManager.get().post(new WalletHistoryStatusEvent(false, "Finding transactions for " + path));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Finding transactions for " + path));
try {
String scriptHash = new RetryLogic<String>(MAX_RETRIES, RETRY_DELAY, List.of(IllegalStateException.class, IllegalArgumentException.class)).getResult(() ->
client.createRequest().returnAs(String.class).method("blockchain.scripthash.subscribe").id(path + "-" + idCounter.incrementAndGet()).params(pathScriptHashes.get(path)).executeNullable());
@ -134,12 +135,12 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<Integer, String> getBlockHeaders(Transport transport, Set<Integer> blockHeights) {
public Map<Integer, String> getBlockHeaders(Transport transport, Wallet wallet, Set<Integer> blockHeights) {
JsonRpcClient client = new JsonRpcClient(transport);
Map<Integer, String> result = new LinkedHashMap<>();
for(Integer blockHeight : blockHeights) {
EventManager.get().post(new WalletHistoryStatusEvent(false, "Retrieving block at height " + blockHeight));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Retrieving block at height " + blockHeight));
try {
String blockHeader = new RetryLogic<String>(MAX_RETRIES, RETRY_DELAY, List.of(IllegalStateException.class, IllegalArgumentException.class)).getResult(() ->
client.createRequest().returnAs(String.class).method("blockchain.block.header").id(idCounter.incrementAndGet()).params(blockHeight).execute());
@ -155,12 +156,12 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
}
@Override
public Map<String, String> getTransactions(Transport transport, Set<String> txids) {
public Map<String, String> getTransactions(Transport transport, Wallet wallet, Set<String> txids) {
JsonRpcClient client = new JsonRpcClient(transport);
Map<String, String> result = new LinkedHashMap<>();
for(String txid : txids) {
EventManager.get().post(new WalletHistoryStatusEvent(false, "Retrieving transaction [" + txid.substring(0, 6) + "]"));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false, "Retrieving transaction [" + txid.substring(0, 6) + "]"));
try {
String rawTxHex = new RetryLogic<String>(MAX_RETRIES, RETRY_DELAY, List.of(IllegalStateException.class, IllegalArgumentException.class)).getResult(() ->
client.createRequest().returnAs(String.class).method("blockchain.transaction.get").id(idCounter.incrementAndGet()).params(txid).execute());

View file

@ -79,14 +79,14 @@ public class WalletForm {
log.debug(node == null ? "Refreshing full wallet history" : "Requesting node wallet history for " + node.getDerivationPath());
ElectrumServer.TransactionHistoryService historyService = new ElectrumServer.TransactionHistoryService(wallet, getWalletTransactionNodes(node));
historyService.setOnSucceeded(workerStateEvent -> {
EventManager.get().post(new WalletHistoryStatusEvent(true));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, true));
updateWallet(previousWallet, blockHeight);
});
historyService.setOnFailed(workerStateEvent -> {
log.error("Error retrieving wallet history", workerStateEvent.getSource().getException());
EventManager.get().post(new WalletHistoryStatusEvent(workerStateEvent.getSource().getException().getMessage()));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, workerStateEvent.getSource().getException().getMessage()));
});
EventManager.get().post(new WalletHistoryStatusEvent(false));
EventManager.get().post(new WalletHistoryStatusEvent(wallet, false));
historyService.start();
}
}