mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
various fixes, better non-electrumx support
This commit is contained in:
parent
2b48b4cd6e
commit
c814b8e350
15 changed files with 93 additions and 33 deletions
|
@ -118,7 +118,7 @@ jlink {
|
||||||
jpackage {
|
jpackage {
|
||||||
imageName = "Sparrow"
|
imageName = "Sparrow"
|
||||||
installerName = "Sparrow"
|
installerName = "Sparrow"
|
||||||
appVersion = "0.6"
|
appVersion = "0.9.1"
|
||||||
skipInstaller = true
|
skipInstaller = true
|
||||||
imageOptions = []
|
imageOptions = []
|
||||||
installerOptions = [
|
installerOptions = [
|
||||||
|
|
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit 5d456a10df1375b41e6159efc540b3d90cfbfc4d
|
Subproject commit 446eac3483229fc4c798e82f367ca9d8f797d16e
|
|
@ -54,7 +54,7 @@ public class ConfirmationProgressIndicator extends StackPane {
|
||||||
arcLengthTimeline.getKeyFrames().add(arcLengthFrame);
|
arcLengthTimeline.getKeyFrames().add(arcLengthFrame);
|
||||||
sequence.getChildren().add(arcLengthTimeline);
|
sequence.getChildren().add(arcLengthTimeline);
|
||||||
|
|
||||||
if(newValue.intValue() == BlockTransactionHash.BLOCKS_TO_CONFIRM) {
|
if(newValue.intValue() >= BlockTransactionHash.BLOCKS_TO_CONFIRM) {
|
||||||
Timeline arcRadiusTimeline = new Timeline();
|
Timeline arcRadiusTimeline = new Timeline();
|
||||||
KeyValue arcRadiusXValue = new KeyValue(arc.radiusXProperty(), 0.0);
|
KeyValue arcRadiusXValue = new KeyValue(arc.radiusXProperty(), 0.0);
|
||||||
KeyValue arcRadiusYValue = new KeyValue(arc.radiusYProperty(), 0.0);
|
KeyValue arcRadiusYValue = new KeyValue(arc.radiusYProperty(), 0.0);
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class MnemonicKeystoreImportPane extends TitledDescriptionPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MnemonicKeystoreImportPane(Keystore keystore) {
|
public MnemonicKeystoreImportPane(Keystore keystore) {
|
||||||
super(keystore.getSeed().getType().getName(), keystore.getSeed().needsPassphrase() ? "Passphrase enabled" : "Passphrase disabled", "", "image/" + WalletModel.SEED + ".png");
|
super(keystore.getSeed().getType().getName(), keystore.getSeed().needsPassphrase() ? "Passphrase enabled" : "Passphrase disabled", "", "image/" + WalletModel.SEED.getType() + ".png");
|
||||||
this.wallet = null;
|
this.wallet = null;
|
||||||
this.importer = null;
|
this.importer = null;
|
||||||
showHideLink.setVisible(false);
|
showHideLink.setVisible(false);
|
||||||
|
|
|
@ -40,4 +40,8 @@ public class WalletNodeHistoryChangedEvent {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getScriptHash() {
|
||||||
|
return scriptHash;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ public class BatchedElectrumServerRpc implements ElectrumServerRpc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids) {
|
public Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids, String scriptHash) {
|
||||||
JsonRpcClient client = new JsonRpcClient(transport);
|
JsonRpcClient client = new JsonRpcClient(transport);
|
||||||
BatchRequestBuilder<String, VerboseTransaction> batchRequest = client.createBatchRequest().keysType(String.class).returnType(VerboseTransaction.class);
|
BatchRequestBuilder<String, VerboseTransaction> batchRequest = client.createBatchRequest().keysType(String.class).returnType(VerboseTransaction.class);
|
||||||
for(String txid : txids) {
|
for(String txid : txids) {
|
||||||
|
|
|
@ -479,13 +479,13 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Sha256Hash, BlockTransaction> getReferencedTransactions(Set<Sha256Hash> references) throws ServerException {
|
public Map<Sha256Hash, BlockTransaction> getReferencedTransactions(Set<Sha256Hash> references, String scriptHash) throws ServerException {
|
||||||
Set<String> txids = new LinkedHashSet<>(references.size());
|
Set<String> txids = new LinkedHashSet<>(references.size());
|
||||||
for(Sha256Hash reference : references) {
|
for(Sha256Hash reference : references) {
|
||||||
txids.add(reference.toString());
|
txids.add(reference.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, VerboseTransaction> result = electrumServerRpc.getVerboseTransactions(getTransport(), txids);
|
Map<String, VerboseTransaction> result = electrumServerRpc.getVerboseTransactions(getTransport(), txids, scriptHash);
|
||||||
|
|
||||||
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
|
Map<Sha256Hash, BlockTransaction> transactionMap = new HashMap<>();
|
||||||
for(String txid : result.keySet()) {
|
for(String txid : result.keySet()) {
|
||||||
|
@ -715,6 +715,7 @@ public class ElectrumServer {
|
||||||
|
|
||||||
public static class TransactionReferenceService extends Service<Map<Sha256Hash, BlockTransaction>> {
|
public static class TransactionReferenceService extends Service<Map<Sha256Hash, BlockTransaction>> {
|
||||||
private final Set<Sha256Hash> references;
|
private final Set<Sha256Hash> references;
|
||||||
|
private String scriptHash;
|
||||||
|
|
||||||
public TransactionReferenceService(Transaction transaction) {
|
public TransactionReferenceService(Transaction transaction) {
|
||||||
references = new HashSet<>();
|
references = new HashSet<>();
|
||||||
|
@ -724,6 +725,11 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransactionReferenceService(Set<Sha256Hash> references, String scriptHash) {
|
||||||
|
this(references);
|
||||||
|
this.scriptHash = scriptHash;
|
||||||
|
}
|
||||||
|
|
||||||
public TransactionReferenceService(Set<Sha256Hash> references) {
|
public TransactionReferenceService(Set<Sha256Hash> references) {
|
||||||
this.references = references;
|
this.references = references;
|
||||||
}
|
}
|
||||||
|
@ -733,7 +739,7 @@ public class ElectrumServer {
|
||||||
return new Task<>() {
|
return new Task<>() {
|
||||||
protected Map<Sha256Hash, BlockTransaction> call() throws ServerException {
|
protected Map<Sha256Hash, BlockTransaction> call() throws ServerException {
|
||||||
ElectrumServer electrumServer = new ElectrumServer();
|
ElectrumServer electrumServer = new ElectrumServer();
|
||||||
return electrumServer.getReferencedTransactions(references);
|
return electrumServer.getReferencedTransactions(references, scriptHash);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public interface ElectrumServerRpc {
|
||||||
|
|
||||||
Map<String, String> getTransactions(Transport transport, Set<String> txids);
|
Map<String, String> getTransactions(Transport transport, Set<String> txids);
|
||||||
|
|
||||||
Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids);
|
Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids, String scriptHash);
|
||||||
|
|
||||||
Map<Integer, Double> getFeeEstimates(Transport transport, List<Integer> targetBlocks);
|
Map<Integer, Double> getFeeEstimates(Transport transport, List<Integer> targetBlocks);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.sparrowwallet.sparrow.net;
|
package com.sparrowwallet.sparrow.net;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
|
|
||||||
import com.github.arteam.simplejsonrpc.client.JsonRpcClient;
|
import com.github.arteam.simplejsonrpc.client.JsonRpcClient;
|
||||||
import com.github.arteam.simplejsonrpc.client.Transport;
|
import com.github.arteam.simplejsonrpc.client.Transport;
|
||||||
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcException;
|
import com.github.arteam.simplejsonrpc.client.exception.JsonRpcException;
|
||||||
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
|
import com.sparrowwallet.sparrow.AppController;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -17,6 +19,7 @@ import static com.sparrowwallet.drongo.protocol.Transaction.DUST_RELAY_TX_FEE;
|
||||||
|
|
||||||
public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SimpleElectrumServerRpc.class);
|
private static final Logger log = LoggerFactory.getLogger(SimpleElectrumServerRpc.class);
|
||||||
|
private static final int MAX_TARGET_BLOCKS = 25;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ping(Transport transport) {
|
public void ping(Transport transport) {
|
||||||
|
@ -156,7 +159,7 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids) {
|
public Map<String, VerboseTransaction> getVerboseTransactions(Transport transport, Set<String> txids, String scriptHash) {
|
||||||
JsonRpcClient client = new JsonRpcClient(transport);
|
JsonRpcClient client = new JsonRpcClient(transport);
|
||||||
|
|
||||||
Map<String, VerboseTransaction> result = new LinkedHashMap<>();
|
Map<String, VerboseTransaction> result = new LinkedHashMap<>();
|
||||||
|
@ -166,6 +169,27 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
result.put(txid, verboseTransaction);
|
result.put(txid, verboseTransaction);
|
||||||
} catch(IllegalStateException | IllegalArgumentException e) {
|
} catch(IllegalStateException | IllegalArgumentException e) {
|
||||||
log.warn("Error retrieving transaction: " + txid + " (" + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()) + ")");
|
log.warn("Error retrieving transaction: " + txid + " (" + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()) + ")");
|
||||||
|
String rawTxHex = client.createRequest().returnAs(String.class).method("blockchain.transaction.get").id(txid).params(txid).execute();
|
||||||
|
Transaction tx = new Transaction(Utils.hexToBytes(rawTxHex));
|
||||||
|
String id = tx.getTxId().toString();
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
if(scriptHash != null) {
|
||||||
|
ScriptHashTx[] scriptHashTxes = client.createRequest().returnAs(ScriptHashTx[].class).method("blockchain.scripthash.get_history").id(id).params(scriptHash).execute();
|
||||||
|
for(ScriptHashTx scriptHashTx : scriptHashTxes) {
|
||||||
|
if(scriptHashTx.tx_hash.equals(id)) {
|
||||||
|
height = scriptHashTx.height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerboseTransaction verboseTransaction = new VerboseTransaction();
|
||||||
|
verboseTransaction.txid = id;
|
||||||
|
verboseTransaction.hex = rawTxHex;
|
||||||
|
verboseTransaction.confirmations = (height <= 0 ? 0 : AppController.getCurrentBlockHeight() - height + 1);
|
||||||
|
verboseTransaction.blockhash = Sha256Hash.ZERO_HASH.toString();
|
||||||
|
result.put(txid, verboseTransaction);
|
||||||
} catch(JsonRpcException e) {
|
} catch(JsonRpcException e) {
|
||||||
log.warn("Error retrieving transaction: " + txid + " (" + e.getErrorMessage() + ")");
|
log.warn("Error retrieving transaction: " + txid + " (" + e.getErrorMessage() + ")");
|
||||||
}
|
}
|
||||||
|
@ -180,15 +204,19 @@ public class SimpleElectrumServerRpc implements ElectrumServerRpc {
|
||||||
|
|
||||||
Map<Integer, Double> result = new LinkedHashMap<>();
|
Map<Integer, Double> result = new LinkedHashMap<>();
|
||||||
for(Integer targetBlock : targetBlocks) {
|
for(Integer targetBlock : targetBlocks) {
|
||||||
|
if(targetBlock <= MAX_TARGET_BLOCKS) {
|
||||||
try {
|
try {
|
||||||
Double targetBlocksFeeRateBtcKb = client.createRequest().returnAs(Double.class).method("blockchain.estimatefee").id(targetBlock).params(targetBlock).execute();
|
Double targetBlocksFeeRateBtcKb = client.createRequest().returnAs(Double.class).method("blockchain.estimatefee").id(targetBlock).params(targetBlock).execute();
|
||||||
result.put(targetBlock, targetBlocksFeeRateBtcKb);
|
result.put(targetBlock, targetBlocksFeeRateBtcKb);
|
||||||
} catch(IllegalStateException | IllegalArgumentException e) {
|
} catch(IllegalStateException | IllegalArgumentException e) {
|
||||||
log.warn("Failed to retrieve fee rate for target blocks: " + targetBlock + " (" + e.getMessage() + ")");
|
log.warn("Failed to retrieve fee rate for target blocks: " + targetBlock + " (" + e.getMessage() + ")");
|
||||||
result.put(targetBlock, DUST_RELAY_TX_FEE);
|
result.put(targetBlock, 1d);
|
||||||
} catch(JsonRpcException e) {
|
} catch(JsonRpcException e) {
|
||||||
throw new ElectrumServerRpcException("Failed to retrieve fee rate for target blocks: " + targetBlock, e);
|
throw new ElectrumServerRpcException("Failed to retrieve fee rate for target blocks: " + targetBlock, e);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
result.put(targetBlock, 1d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -5,6 +5,8 @@ import com.github.arteam.simplejsonrpc.server.JsonRpcServer;
|
||||||
import com.google.common.net.HostAndPort;
|
import com.google.common.net.HostAndPort;
|
||||||
import com.sparrowwallet.sparrow.io.Config;
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -12,6 +14,8 @@ import java.net.Socket;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class TcpTransport implements Transport, Closeable {
|
public class TcpTransport implements Transport, Closeable {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(TcpTransport.class);
|
||||||
|
|
||||||
public static final int DEFAULT_PORT = 50001;
|
public static final int DEFAULT_PORT = 50001;
|
||||||
|
|
||||||
protected final HostAndPort server;
|
protected final HostAndPort server;
|
||||||
|
@ -24,6 +28,7 @@ public class TcpTransport implements Transport, Closeable {
|
||||||
private final ReentrantLock clientRequestLock = new ReentrantLock();
|
private final ReentrantLock clientRequestLock = new ReentrantLock();
|
||||||
private boolean running = false;
|
private boolean running = false;
|
||||||
private boolean reading = true;
|
private boolean reading = true;
|
||||||
|
private boolean firstRead = true;
|
||||||
|
|
||||||
private final JsonRpcServer jsonRpcServer = new JsonRpcServer();
|
private final JsonRpcServer jsonRpcServer = new JsonRpcServer();
|
||||||
private final SubscriptionService subscriptionService = new SubscriptionService();
|
private final SubscriptionService subscriptionService = new SubscriptionService();
|
||||||
|
@ -53,6 +58,11 @@ public class TcpTransport implements Transport, Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized String readResponse() throws IOException {
|
private synchronized String readResponse() throws IOException {
|
||||||
|
if(firstRead) {
|
||||||
|
notifyAll();
|
||||||
|
firstRead = false;
|
||||||
|
}
|
||||||
|
|
||||||
while(reading) {
|
while(reading) {
|
||||||
try {
|
try {
|
||||||
wait();
|
wait();
|
||||||
|
@ -63,7 +73,7 @@ public class TcpTransport implements Transport, Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastException != null) {
|
if(lastException != null) {
|
||||||
throw new IOException("Error reading response", lastException);
|
throw new IOException("Error reading response: " + lastException.getMessage(), lastException);
|
||||||
}
|
}
|
||||||
|
|
||||||
reading = true;
|
reading = true;
|
||||||
|
@ -73,6 +83,13 @@ public class TcpTransport implements Transport, Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void readInputLoop() throws ServerException {
|
public synchronized void readInputLoop() throws ServerException {
|
||||||
|
try {
|
||||||
|
//Don't start reading until first RPC request is sent
|
||||||
|
wait();
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
while(running) {
|
while(running) {
|
||||||
try {
|
try {
|
||||||
String received = readInputStream();
|
String received = readInputStream();
|
||||||
|
@ -95,7 +112,7 @@ public class TcpTransport implements Transport, Closeable {
|
||||||
reading = false;
|
reading = false;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
//Allow this thread to terminate as we will need to reconnect with a new transport anyway
|
//Allow this thread to terminate as we will need to reconnect with a new transport anyway
|
||||||
throw new ServerException(e);
|
running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,7 +469,10 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
private void updateBlockchainForm(BlockTransaction blockTransaction, Integer currentHeight) {
|
private void updateBlockchainForm(BlockTransaction blockTransaction, Integer currentHeight) {
|
||||||
blockchainForm.setVisible(true);
|
blockchainForm.setVisible(true);
|
||||||
|
|
||||||
if(currentHeight == null) {
|
if(Sha256Hash.ZERO_HASH.equals(blockTransaction.getBlockHash()) && blockTransaction.getHeight() == 0 && headersForm.getSigningWallet() == null) {
|
||||||
|
//A zero block hash indicates that this blocktransaction is incomplete and the height is likely incorrect if we are not sending a tx
|
||||||
|
blockStatus.setText("Unknown");
|
||||||
|
} else if(currentHeight == null) {
|
||||||
blockStatus.setText(blockTransaction.getHeight() > 0 ? "Confirmed" : "Unconfirmed");
|
blockStatus.setText(blockTransaction.getHeight() > 0 ? "Confirmed" : "Unconfirmed");
|
||||||
} else {
|
} else {
|
||||||
int confirmations = blockTransaction.getHeight() > 0 ? currentHeight - blockTransaction.getHeight() + 1 : 0;
|
int confirmations = blockTransaction.getHeight() > 0 ? currentHeight - blockTransaction.getHeight() + 1 : 0;
|
||||||
|
@ -512,7 +515,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
blockTimestampField.setVisible(false);
|
blockTimestampField.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blockTransaction.getBlockHash() != null) {
|
if(blockTransaction.getBlockHash() != null && !blockTransaction.getBlockHash().equals(Sha256Hash.ZERO_HASH)) {
|
||||||
blockHashField.setVisible(true);
|
blockHashField.setVisible(true);
|
||||||
blockHash.setText(blockTransaction.getBlockHash().toString());
|
blockHash.setText(blockTransaction.getBlockHash().toString());
|
||||||
blockHash.setContextMenu(new BlockHeightContextMenu(blockTransaction.getBlockHash()));
|
blockHash.setContextMenu(new BlockHeightContextMenu(blockTransaction.getBlockHash()));
|
||||||
|
@ -796,7 +799,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||||
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
if(event.getTxId().equals(headersForm.getTransaction().getTxId())) {
|
||||||
if(event.getBlockTransaction() != null) {
|
if(event.getBlockTransaction() != null && (!Sha256Hash.ZERO_HASH.equals(event.getBlockTransaction().getBlockHash()) || headersForm.getBlockTransaction() == null)) {
|
||||||
updateBlockchainForm(event.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
updateBlockchainForm(event.getBlockTransaction(), AppController.getCurrentBlockHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,7 +940,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
public void walletNodeHistoryChanged(WalletNodeHistoryChangedEvent event) {
|
public void walletNodeHistoryChanged(WalletNodeHistoryChangedEvent event) {
|
||||||
if(headersForm.getSigningWallet() != null && event.getWalletNode(headersForm.getSigningWallet()) != null) {
|
if(headersForm.getSigningWallet() != null && event.getWalletNode(headersForm.getSigningWallet()) != null) {
|
||||||
Sha256Hash txid = headersForm.getTransaction().getTxId();
|
Sha256Hash txid = headersForm.getTransaction().getTxId();
|
||||||
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(Set.of(txid));
|
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(Set.of(txid), event.getScriptHash());
|
||||||
transactionReferenceService.setOnSucceeded(successEvent -> {
|
transactionReferenceService.setOnSucceeded(successEvent -> {
|
||||||
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
||||||
BlockTransaction blockTransaction = transactionMap.get(txid);
|
BlockTransaction blockTransaction = transactionMap.get(txid);
|
||||||
|
|
|
@ -319,9 +319,9 @@ public class TransactionController implements Initializable {
|
||||||
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
||||||
BlockTransaction thisBlockTx = null;
|
BlockTransaction thisBlockTx = null;
|
||||||
Map<Sha256Hash, BlockTransaction> inputTransactions = new HashMap<>();
|
Map<Sha256Hash, BlockTransaction> inputTransactions = new HashMap<>();
|
||||||
for (Sha256Hash txid : transactionMap.keySet()) {
|
for(Sha256Hash txid : transactionMap.keySet()) {
|
||||||
BlockTransaction blockTx = transactionMap.get(txid);
|
BlockTransaction blockTx = transactionMap.get(txid);
|
||||||
if (txid.equals(getTransaction().getTxId())) {
|
if(txid.equals(getTransaction().getTxId())) {
|
||||||
thisBlockTx = blockTx;
|
thisBlockTx = blockTx;
|
||||||
} else {
|
} else {
|
||||||
inputTransactions.put(txid, blockTx);
|
inputTransactions.put(txid, blockTx);
|
||||||
|
@ -456,7 +456,9 @@ public class TransactionController implements Initializable {
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||||
if(event.getTxId().equals(getTransaction().getTxId())) {
|
if(event.getTxId().equals(getTransaction().getTxId())) {
|
||||||
|
if(event.getBlockTransaction() != null && (!Sha256Hash.ZERO_HASH.equals(event.getBlockTransaction().getBlockHash()) || txdata.getBlockTransaction() == null)) {
|
||||||
txdata.setBlockTransaction(event.getBlockTransaction());
|
txdata.setBlockTransaction(event.getBlockTransaction());
|
||||||
|
}
|
||||||
if(txdata.getInputTransactions() == null) {
|
if(txdata.getInputTransactions() == null) {
|
||||||
txdata.setInputTransactions(event.getInputTransactions());
|
txdata.setInputTransactions(event.getInputTransactions());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
<Separator styleClass="form-separator" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="1" />
|
<Separator styleClass="form-separator" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="1" />
|
||||||
|
|
||||||
<Form GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="2">
|
<Form GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="2">
|
||||||
<Fieldset inputGrow="SOMETIMES" text="Required Script">
|
<Fieldset inputGrow="SOMETIMES" text="Required ScriptPubKey">
|
||||||
<Field text="ScriptPubKey">
|
<Field text="Script:">
|
||||||
<VirtualizedScrollPane>
|
<VirtualizedScrollPane>
|
||||||
<content>
|
<content>
|
||||||
<ScriptArea fx:id="scriptPubKeyArea" editable="false" wrapText="true" prefHeight="42" maxHeight="42" styleClass="uneditable-codearea" />
|
<ScriptArea fx:id="scriptPubKeyArea" editable="false" wrapText="true" prefHeight="42" maxHeight="42" styleClass="uneditable-codearea" />
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount-unit {
|
.amount-unit {
|
||||||
-fx-min-width: 70px;
|
-fx-min-width: 75px;
|
||||||
-fx-max-width: 70px;
|
-fx-max-width: 75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#feeRatesChart {
|
#feeRatesChart {
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
</Form>
|
</Form>
|
||||||
<Form GridPane.columnIndex="0" GridPane.rowIndex="1">
|
<Form GridPane.columnIndex="0" GridPane.rowIndex="1">
|
||||||
<Fieldset inputGrow="SOMETIMES" text="Fee">
|
<Fieldset inputGrow="SOMETIMES" text="Fee">
|
||||||
<Field text="Block target:">
|
<Field text="Block target">
|
||||||
<Slider fx:id="targetBlocks" snapToTicks="true" showTickLabels="true" showTickMarks="true" />
|
<Slider fx:id="targetBlocks" snapToTicks="true" showTickLabels="true" showTickMarks="true" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field fx:id="feeRateField" text="Rate:">
|
<Field fx:id="feeRateField" text="Rate:">
|
||||||
|
|
Loading…
Reference in a new issue