mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 05:06:45 +00:00
transaction view paging support initial commit
This commit is contained in:
parent
51b2608abc
commit
ebc2f9442e
13 changed files with 329 additions and 91 deletions
|
@ -621,13 +621,10 @@ public class AppController implements Initializable {
|
||||||
|
|
||||||
controller.setPSBT(psbt);
|
controller.setPSBT(psbt);
|
||||||
controller.setBlockTransaction(blockTransaction);
|
controller.setBlockTransaction(blockTransaction);
|
||||||
controller.setTransaction(transaction);
|
|
||||||
|
|
||||||
if(initialView != null) {
|
if(initialView != null) {
|
||||||
controller.setTreeSelection(initialView, initialIndex);
|
controller.setInitialView(initialView, initialIndex);
|
||||||
} else {
|
|
||||||
controller.setTreeSelection(TransactionView.HEADERS, null);
|
|
||||||
}
|
}
|
||||||
|
controller.setTransaction(transaction);
|
||||||
|
|
||||||
tabs.getTabs().add(tab);
|
tabs.getTabs().add(tab);
|
||||||
return tab;
|
return tab;
|
||||||
|
|
|
@ -5,12 +5,17 @@ import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BlockTransactionFetchedEvent {
|
public class BlockTransactionFetchedEvent extends PagedEvent {
|
||||||
private final Sha256Hash txId;
|
private final Sha256Hash txId;
|
||||||
private final BlockTransaction blockTransaction;
|
private final BlockTransaction blockTransaction;
|
||||||
private final Map<Sha256Hash, BlockTransaction> inputTransactions;
|
private final Map<Sha256Hash, BlockTransaction> inputTransactions;
|
||||||
|
|
||||||
public BlockTransactionFetchedEvent(Sha256Hash txId, BlockTransaction blockTransaction, Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
public BlockTransactionFetchedEvent(Sha256Hash txId, BlockTransaction blockTransaction, Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
||||||
|
this(txId, blockTransaction, inputTransactions, 0, blockTransaction.getTransaction().getInputs().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockTransactionFetchedEvent(Sha256Hash txId, BlockTransaction blockTransaction, Map<Sha256Hash, BlockTransaction> inputTransactions, int pageStart, int pageEnd) {
|
||||||
|
super(pageStart, pageEnd);
|
||||||
this.txId = txId;
|
this.txId = txId;
|
||||||
this.blockTransaction = blockTransaction;
|
this.blockTransaction = blockTransaction;
|
||||||
this.inputTransactions = inputTransactions;
|
this.inputTransactions = inputTransactions;
|
||||||
|
|
|
@ -5,11 +5,12 @@ import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockTransactionOutputsFetchedEvent {
|
public class BlockTransactionOutputsFetchedEvent extends PagedEvent {
|
||||||
private final Sha256Hash txId;
|
private final Sha256Hash txId;
|
||||||
private final List<BlockTransaction> outputTransactions;
|
private final List<BlockTransaction> outputTransactions;
|
||||||
|
|
||||||
public BlockTransactionOutputsFetchedEvent(Sha256Hash txId, List<BlockTransaction> outputTransactions) {
|
public BlockTransactionOutputsFetchedEvent(Sha256Hash txId, List<BlockTransaction> outputTransactions, int pageStart, int pageEnd) {
|
||||||
|
super(pageStart, pageEnd);
|
||||||
this.txId = txId;
|
this.txId = txId;
|
||||||
this.outputTransactions = outputTransactions;
|
this.outputTransactions = outputTransactions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.sparrowwallet.sparrow.event;
|
||||||
|
|
||||||
|
public class PagedEvent {
|
||||||
|
private final int pageStart;
|
||||||
|
private final int pageEnd;
|
||||||
|
|
||||||
|
public PagedEvent(int pageStart, int pageEnd) {
|
||||||
|
this.pageStart = pageStart;
|
||||||
|
this.pageEnd = pageEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageStart() {
|
||||||
|
return pageStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageEnd() {
|
||||||
|
return pageEnd;
|
||||||
|
}
|
||||||
|
}
|
|
@ -200,11 +200,11 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<Set<BlockTransactionHash>> getOutputTransactionReferences(Transaction transaction) throws ServerException {
|
public List<Set<BlockTransactionHash>> getOutputTransactionReferences(Transaction transaction, int indexStart, int indexEnd) throws ServerException {
|
||||||
try {
|
try {
|
||||||
JsonRpcClient client = new JsonRpcClient(getTransport());
|
JsonRpcClient client = new JsonRpcClient(getTransport());
|
||||||
BatchRequestBuilder<Integer, ScriptHashTx[]> batchRequest = client.createBatchRequest().keysType(Integer.class).returnType(ScriptHashTx[].class);
|
BatchRequestBuilder<Integer, ScriptHashTx[]> batchRequest = client.createBatchRequest().keysType(Integer.class).returnType(ScriptHashTx[].class);
|
||||||
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
for(int i = indexStart; i < transaction.getOutputs().size() && i < indexEnd; i++) {
|
||||||
TransactionOutput output = transaction.getOutputs().get(i);
|
TransactionOutput output = transaction.getOutputs().get(i);
|
||||||
batchRequest.add(i, "blockchain.scripthash.get_history", getScriptHash(output));
|
batchRequest.add(i, "blockchain.scripthash.get_history", getScriptHash(output));
|
||||||
}
|
}
|
||||||
|
@ -910,9 +910,19 @@ public class ElectrumServer {
|
||||||
|
|
||||||
public static class TransactionOutputsReferenceService extends Service<List<BlockTransaction>> {
|
public static class TransactionOutputsReferenceService extends Service<List<BlockTransaction>> {
|
||||||
private final Transaction transaction;
|
private final Transaction transaction;
|
||||||
|
private final int indexStart;
|
||||||
|
private final int indexEnd;
|
||||||
|
|
||||||
public TransactionOutputsReferenceService(Transaction transaction) {
|
public TransactionOutputsReferenceService(Transaction transaction) {
|
||||||
this.transaction = transaction;
|
this.transaction = transaction;
|
||||||
|
this.indexStart = 0;
|
||||||
|
this.indexEnd = transaction.getOutputs().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -920,7 +930,7 @@ public class ElectrumServer {
|
||||||
return new Task<>() {
|
return new Task<>() {
|
||||||
protected List<BlockTransaction> call() throws ServerException {
|
protected List<BlockTransaction> call() throws ServerException {
|
||||||
ElectrumServer electrumServer = new ElectrumServer();
|
ElectrumServer electrumServer = new ElectrumServer();
|
||||||
List<Set<BlockTransactionHash>> outputTransactionReferences = electrumServer.getOutputTransactionReferences(transaction);
|
List<Set<BlockTransactionHash>> outputTransactionReferences = electrumServer.getOutputTransactionReferences(transaction, indexStart, indexEnd);
|
||||||
|
|
||||||
Set<BlockTransactionHash> setReferences = new HashSet<>();
|
Set<BlockTransactionHash> setReferences = new HashSet<>();
|
||||||
for(Set<BlockTransactionHash> outputReferences : outputTransactionReferences) {
|
for(Set<BlockTransactionHash> outputReferences : outputTransactionReferences) {
|
||||||
|
|
|
@ -228,7 +228,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long calculateFee(Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
private Long calculateFee(Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
||||||
long feeAmt = 0L;
|
long feeAmt = 0L;
|
||||||
for(TransactionInput input : headersForm.getTransaction().getInputs()) {
|
for(TransactionInput input : headersForm.getTransaction().getInputs()) {
|
||||||
if(input.isCoinBase()) {
|
if(input.isCoinBase()) {
|
||||||
|
@ -237,7 +237,8 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
|
|
||||||
BlockTransaction inputTx = inputTransactions.get(input.getOutpoint().getHash());
|
BlockTransaction inputTx = inputTransactions.get(input.getOutpoint().getHash());
|
||||||
if(inputTx == null) {
|
if(inputTx == null) {
|
||||||
throw new IllegalStateException("Cannot find transaction for hash " + input.getOutpoint().getHash());
|
System.out.println("Cannot find transaction for hash " + input.getOutpoint().getHash() + ", still paging?");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
feeAmt += inputTx.getTransaction().getOutputs().get((int)input.getOutpoint().getIndex()).getValue();
|
feeAmt += inputTx.getTransaction().getOutputs().get((int)input.getOutpoint().getIndex()).getValue();
|
||||||
|
@ -319,7 +320,10 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
updateBlockchainForm(event.getBlockTransaction());
|
updateBlockchainForm(event.getBlockTransaction());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFee(calculateFee(event.getInputTransactions()));
|
Long feeAmt = calculateFee(event.getInputTransactions());
|
||||||
|
if(feeAmt != null) {
|
||||||
|
updateFee(feeAmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
|
||||||
|
public abstract class IndexedTransactionForm extends TransactionForm {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public IndexedTransactionForm(PSBT psbt, int index) {
|
||||||
|
super(psbt);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexedTransactionForm(BlockTransaction blockTransaction, int index) {
|
||||||
|
super(blockTransaction);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexedTransactionForm(Transaction transaction, int index) {
|
||||||
|
super(transaction);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
|
@ -191,6 +191,11 @@ public class InputController extends TransactionFormController implements Initia
|
||||||
TransactionInput txInput = inputForm.getTransactionInput();
|
TransactionInput txInput = inputForm.getTransactionInput();
|
||||||
if(!txInput.isCoinBase()) {
|
if(!txInput.isCoinBase()) {
|
||||||
BlockTransaction blockTransaction = inputTransactions.get(txInput.getOutpoint().getHash());
|
BlockTransaction blockTransaction = inputTransactions.get(txInput.getOutpoint().getHash());
|
||||||
|
if(blockTransaction == null) {
|
||||||
|
System.out.println("Could not retrieve block transaction for input #" + inputForm.getIndex());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TransactionOutput output = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex());
|
TransactionOutput output = blockTransaction.getTransaction().getOutputs().get((int)txInput.getOutpoint().getIndex());
|
||||||
updateSpends(output);
|
updateSpends(output);
|
||||||
}
|
}
|
||||||
|
@ -464,7 +469,7 @@ public class InputController extends TransactionFormController implements Initia
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||||
if(event.getTxId().equals(inputForm.getTransaction().getTxId())) {
|
if(event.getTxId().equals(inputForm.getTransaction().getTxId()) && inputForm.getIndex() >= event.getPageStart() && inputForm.getIndex() < event.getPageEnd()) {
|
||||||
updateOutpoint(event.getInputTransactions());
|
updateOutpoint(event.getInputTransactions());
|
||||||
if(inputForm.getPsbt() == null) {
|
if(inputForm.getPsbt() == null) {
|
||||||
updateSpends(event.getInputTransactions());
|
updateSpends(event.getInputTransactions());
|
||||||
|
|
|
@ -12,23 +12,23 @@ import javafx.scene.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class InputForm extends TransactionForm {
|
public class InputForm extends IndexedTransactionForm {
|
||||||
private TransactionInput transactionInput;
|
private final TransactionInput transactionInput;
|
||||||
private PSBTInput psbtInput;
|
private PSBTInput psbtInput;
|
||||||
|
|
||||||
public InputForm(PSBT psbt, PSBTInput psbtInput) {
|
public InputForm(PSBT psbt, PSBTInput psbtInput) {
|
||||||
super(psbt);
|
super(psbt, psbt.getPsbtInputs().indexOf(psbtInput));
|
||||||
this.transactionInput = psbt.getTransaction().getInputs().get(psbt.getPsbtInputs().indexOf(psbtInput));
|
this.transactionInput = psbt.getTransaction().getInputs().get(psbt.getPsbtInputs().indexOf(psbtInput));
|
||||||
this.psbtInput = psbtInput;
|
this.psbtInput = psbtInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputForm(BlockTransaction blockTransaction, TransactionInput transactionInput) {
|
public InputForm(BlockTransaction blockTransaction, TransactionInput transactionInput) {
|
||||||
super(blockTransaction);
|
super(blockTransaction, blockTransaction.getTransaction().getInputs().indexOf(transactionInput));
|
||||||
this.transactionInput = transactionInput;
|
this.transactionInput = transactionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputForm(Transaction transaction, TransactionInput transactionInput) {
|
public InputForm(Transaction transaction, TransactionInput transactionInput) {
|
||||||
super(transaction);
|
super(transaction, transaction.getInputs().indexOf(transactionInput));
|
||||||
this.transactionInput = transactionInput;
|
this.transactionInput = transactionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class OutputController extends TransactionFormController implements Initi
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionOutputsFetched(BlockTransactionOutputsFetchedEvent event) {
|
public void blockTransactionOutputsFetched(BlockTransactionOutputsFetchedEvent event) {
|
||||||
if(event.getTxId().equals(outputForm.getTransaction().getTxId()) && outputForm.getPsbt() == null) {
|
if(event.getTxId().equals(outputForm.getTransaction().getTxId()) && outputForm.getPsbt() == null && outputForm.getIndex() >= event.getPageStart() && outputForm.getIndex() < event.getPageEnd()) {
|
||||||
updateSpent(event.getOutputTransactions());
|
updateSpent(event.getOutputTransactions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,23 @@ import javafx.scene.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class OutputForm extends TransactionForm {
|
public class OutputForm extends IndexedTransactionForm {
|
||||||
private final TransactionOutput transactionOutput;
|
private final TransactionOutput transactionOutput;
|
||||||
private PSBTOutput psbtOutput;
|
private PSBTOutput psbtOutput;
|
||||||
|
|
||||||
public OutputForm(PSBT psbt, PSBTOutput psbtOutput) {
|
public OutputForm(PSBT psbt, PSBTOutput psbtOutput) {
|
||||||
super(psbt);
|
super(psbt, psbt.getPsbtOutputs().indexOf(psbtOutput));
|
||||||
this.transactionOutput = psbt.getTransaction().getOutputs().get(psbt.getPsbtOutputs().indexOf(psbtOutput));
|
this.transactionOutput = psbt.getTransaction().getOutputs().get(psbt.getPsbtOutputs().indexOf(psbtOutput));
|
||||||
this.psbtOutput = psbtOutput;
|
this.psbtOutput = psbtOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputForm(BlockTransaction blockTransaction, TransactionOutput transactionOutput) {
|
public OutputForm(BlockTransaction blockTransaction, TransactionOutput transactionOutput) {
|
||||||
super(blockTransaction);
|
super(blockTransaction, blockTransaction.getTransaction().getOutputs().indexOf(transactionOutput));
|
||||||
this.transactionOutput = transactionOutput;
|
this.transactionOutput = transactionOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputForm(Transaction transaction, TransactionOutput transactionOutput) {
|
public OutputForm(Transaction transaction, TransactionOutput transactionOutput) {
|
||||||
super(transaction);
|
super(transaction, transaction.getOutputs().indexOf(transactionOutput));
|
||||||
this.transactionOutput = transactionOutput;
|
this.transactionOutput = transactionOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
|
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class PageForm extends IndexedTransactionForm {
|
||||||
|
public static final int PAGE_SIZE = 50;
|
||||||
|
|
||||||
|
private final TransactionView view;
|
||||||
|
private final int pageStart;
|
||||||
|
private final int pageEnd;
|
||||||
|
|
||||||
|
public PageForm(TransactionView view, int pageStart, int pageEnd) {
|
||||||
|
super(ElectrumServer.UNFETCHABLE_BLOCK_TRANSACTION, pageStart);
|
||||||
|
this.view = view;
|
||||||
|
this.pageStart = pageStart;
|
||||||
|
this.pageEnd = pageEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getContents() throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransactionView getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageStart() {
|
||||||
|
return pageStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPageEnd() {
|
||||||
|
return pageEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Load More...";
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,20 +50,29 @@ public class TransactionController implements Initializable {
|
||||||
private PSBT psbt;
|
private PSBT psbt;
|
||||||
private BlockTransaction blockTransaction;
|
private BlockTransaction blockTransaction;
|
||||||
|
|
||||||
|
private TransactionView initialView;
|
||||||
|
private Integer initialIndex;
|
||||||
|
|
||||||
private int selectedInputIndex = -1;
|
private int selectedInputIndex = -1;
|
||||||
private int selectedOutputIndex = -1;
|
private int selectedOutputIndex = -1;
|
||||||
|
|
||||||
|
private int highestInputIndex;
|
||||||
|
private int highestOutputIndex;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeView() {
|
private void initializeView() {
|
||||||
|
highestInputIndex = Math.min(transaction.getInputs().size(), PageForm.PAGE_SIZE);
|
||||||
|
highestOutputIndex = Math.min(transaction.getOutputs().size(), PageForm.PAGE_SIZE);
|
||||||
|
|
||||||
initializeTxTree();
|
initializeTxTree();
|
||||||
transactionMasterDetail.setShowDetailNode(AppController.showTxHexProperty);
|
transactionMasterDetail.setShowDetailNode(AppController.showTxHexProperty);
|
||||||
refreshTxHex();
|
refreshTxHex();
|
||||||
fetchThisAndInputBlockTransactions();
|
fetchThisAndInputBlockTransactions(0, highestInputIndex);
|
||||||
fetchOutputBlockTransactions();
|
fetchOutputBlockTransactions(0, highestOutputIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTxTree() {
|
private void initializeTxTree() {
|
||||||
|
@ -74,27 +83,33 @@ public class TransactionController implements Initializable {
|
||||||
InputsForm inputsForm = (psbt != null ? new InputsForm(psbt) : (blockTransaction != null ? new InputsForm(blockTransaction) : new InputsForm(transaction)));
|
InputsForm inputsForm = (psbt != null ? new InputsForm(psbt) : (blockTransaction != null ? new InputsForm(blockTransaction) : new InputsForm(transaction)));
|
||||||
TreeItem<TransactionForm> inputsItem = new TreeItem<>(inputsForm);
|
TreeItem<TransactionForm> inputsItem = new TreeItem<>(inputsForm);
|
||||||
inputsItem.setExpanded(true);
|
inputsItem.setExpanded(true);
|
||||||
for (TransactionInput txInput : transaction.getInputs()) {
|
boolean inputPagingAdded = false;
|
||||||
PSBTInput psbtInput = null;
|
for(int i = 0; i < transaction.getInputs().size(); i++) {
|
||||||
if (psbt != null && psbt.getPsbtInputs().size() > txInput.getIndex()) {
|
if(i < PageForm.PAGE_SIZE || (TransactionView.INPUT.equals(initialView) && i == initialIndex)) {
|
||||||
psbtInput = psbt.getPsbtInputs().get(txInput.getIndex());
|
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
||||||
}
|
|
||||||
InputForm inputForm = (psbt != null ? new InputForm(psbt, psbtInput) : (blockTransaction != null ? new InputForm(blockTransaction, txInput) : new InputForm(transaction, txInput)));
|
|
||||||
TreeItem<TransactionForm> inputItem = new TreeItem<>(inputForm);
|
|
||||||
inputsItem.getChildren().add(inputItem);
|
inputsItem.getChildren().add(inputItem);
|
||||||
|
} else if(!inputPagingAdded) {
|
||||||
|
PageForm pageForm = new PageForm(TransactionView.INPUT, i, i + PageForm.PAGE_SIZE);
|
||||||
|
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
||||||
|
inputsItem.getChildren().add(pageItem);
|
||||||
|
inputPagingAdded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputsForm outputsForm = (psbt != null ? new OutputsForm(psbt) : (blockTransaction != null ? new OutputsForm(blockTransaction) : new OutputsForm(transaction)));
|
OutputsForm outputsForm = (psbt != null ? new OutputsForm(psbt) : (blockTransaction != null ? new OutputsForm(blockTransaction) : new OutputsForm(transaction)));
|
||||||
TreeItem<TransactionForm> outputsItem = new TreeItem<>(outputsForm);
|
TreeItem<TransactionForm> outputsItem = new TreeItem<>(outputsForm);
|
||||||
outputsItem.setExpanded(true);
|
outputsItem.setExpanded(true);
|
||||||
for (TransactionOutput txOutput : transaction.getOutputs()) {
|
boolean outputPagingAdded = false;
|
||||||
PSBTOutput psbtOutput = null;
|
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||||
if (psbt != null && psbt.getPsbtOutputs().size() > txOutput.getIndex()) {
|
if(i < PageForm.PAGE_SIZE || (TransactionView.OUTPUT.equals(initialView) && i == initialIndex)) {
|
||||||
psbtOutput = psbt.getPsbtOutputs().get(txOutput.getIndex());
|
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
||||||
}
|
|
||||||
OutputForm outputForm = (psbt != null ? new OutputForm(psbt, psbtOutput) : (blockTransaction != null ? new OutputForm(blockTransaction, txOutput) : new OutputForm(transaction, txOutput)));
|
|
||||||
TreeItem<TransactionForm> outputItem = new TreeItem<>(outputForm);
|
|
||||||
outputsItem.getChildren().add(outputItem);
|
outputsItem.getChildren().add(outputItem);
|
||||||
|
} else if(!outputPagingAdded) {
|
||||||
|
PageForm pageForm = new PageForm(TransactionView.OUTPUT, i, i + PageForm.PAGE_SIZE);
|
||||||
|
TreeItem<TransactionForm> pageItem = new TreeItem<>(pageForm);
|
||||||
|
outputsItem.getChildren().add(pageItem);
|
||||||
|
outputPagingAdded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootItem.getChildren().add(inputsItem);
|
rootItem.getChildren().add(inputsItem);
|
||||||
|
@ -113,8 +128,44 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
txtree.getSelectionModel().selectedItemProperty().addListener((observable, old_val, new_val) -> {
|
txtree.getSelectionModel().selectedItemProperty().addListener((observable, old_val, selectedItem) -> {
|
||||||
TransactionForm transactionForm = new_val.getValue();
|
TransactionForm transactionForm = selectedItem.getValue();
|
||||||
|
if(transactionForm instanceof PageForm) {
|
||||||
|
PageForm pageForm = (PageForm)transactionForm;
|
||||||
|
Optional<TreeItem<TransactionForm>> optParentItem = txtree.getRoot().getChildren().stream()
|
||||||
|
.filter(item -> item.getValue().getView().equals(pageForm.getView().equals(TransactionView.INPUT) ? TransactionView.INPUTS : TransactionView.OUTPUTS)).findFirst();
|
||||||
|
|
||||||
|
if(optParentItem.isPresent()) {
|
||||||
|
TreeItem<TransactionForm> parentItem = optParentItem.get();
|
||||||
|
parentItem.getChildren().remove(selectedItem);
|
||||||
|
|
||||||
|
int max = pageForm.getView().equals(TransactionView.INPUT) ? transaction.getInputs().size() : transaction.getOutputs().size();
|
||||||
|
for(int i = pageForm.getPageStart(); i < max && i < pageForm.getPageEnd(); i++) {
|
||||||
|
TreeItem<TransactionForm> newItem = pageForm.getView().equals(TransactionView.INPUT) ? createInputTreeItem(i) : createOutputTreeItem(i);
|
||||||
|
parentItem.getChildren().add(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pageForm.getPageEnd() < max) {
|
||||||
|
PageForm nextPageForm = new PageForm(pageForm.getView(), pageForm.getPageStart() + PageForm.PAGE_SIZE, pageForm.getPageEnd() + PageForm.PAGE_SIZE);
|
||||||
|
TreeItem<TransactionForm> nextPageItem = new TreeItem<>(nextPageForm);
|
||||||
|
parentItem.getChildren().add(nextPageItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pageForm.getView().equals(TransactionView.INPUT)) {
|
||||||
|
highestInputIndex = Math.min(max, pageForm.getPageEnd());
|
||||||
|
fetchThisAndInputBlockTransactions(pageForm.getPageStart(), Math.min(max, pageForm.getPageEnd()));
|
||||||
|
} else {
|
||||||
|
highestOutputIndex = Math.min(max, pageForm.getPageEnd());
|
||||||
|
fetchOutputBlockTransactions(pageForm.getPageStart(), Math.min(max, pageForm.getPageEnd()));
|
||||||
|
}
|
||||||
|
|
||||||
|
setTreeSelection(pageForm.getView(), pageForm.getPageStart());
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
txtree.scrollTo(pageForm.getPageStart());
|
||||||
|
refreshTxHex();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
Node node = transactionForm.getContents();
|
Node node = transactionForm.getContents();
|
||||||
txpane.getChildren().clear();
|
txpane.getChildren().clear();
|
||||||
|
@ -140,19 +191,45 @@ public class TransactionController implements Initializable {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IllegalStateException("Can't find pane", e);
|
throw new IllegalStateException("Can't find pane", e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(initialView != null) {
|
||||||
|
setTreeSelection(initialView, initialIndex);
|
||||||
|
} else {
|
||||||
txtree.getSelectionModel().select(txtree.getRoot());
|
txtree.getSelectionModel().select(txtree.getRoot());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeItem<TransactionForm> createInputTreeItem(int inputIndex) {
|
||||||
|
TransactionInput txInput = transaction.getInputs().get(inputIndex);
|
||||||
|
PSBTInput psbtInput = null;
|
||||||
|
if (psbt != null && psbt.getPsbtInputs().size() > txInput.getIndex()) {
|
||||||
|
psbtInput = psbt.getPsbtInputs().get(txInput.getIndex());
|
||||||
|
}
|
||||||
|
InputForm inputForm = (psbt != null ? new InputForm(psbt, psbtInput) : (blockTransaction != null ? new InputForm(blockTransaction, txInput) : new InputForm(transaction, txInput)));
|
||||||
|
return new TreeItem<>(inputForm);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TreeItem<TransactionForm> createOutputTreeItem(int outputIndex) {
|
||||||
|
TransactionOutput txOutput = transaction.getOutputs().get(outputIndex);
|
||||||
|
PSBTOutput psbtOutput = null;
|
||||||
|
if (psbt != null && psbt.getPsbtOutputs().size() > txOutput.getIndex()) {
|
||||||
|
psbtOutput = psbt.getPsbtOutputs().get(txOutput.getIndex());
|
||||||
|
}
|
||||||
|
OutputForm outputForm = (psbt != null ? new OutputForm(psbt, psbtOutput) : (blockTransaction != null ? new OutputForm(blockTransaction, txOutput) : new OutputForm(transaction, txOutput)));
|
||||||
|
return new TreeItem<>(outputForm);
|
||||||
|
}
|
||||||
|
|
||||||
public void setTreeSelection(TransactionView view, Integer index) {
|
public void setTreeSelection(TransactionView view, Integer index) {
|
||||||
select(txtree.getRoot(), view, index);
|
select(txtree.getRoot(), view, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void select(TreeItem<TransactionForm> treeItem, TransactionView view, Integer index) {
|
private void select(TreeItem<TransactionForm> treeItem, TransactionView view, Integer index) {
|
||||||
if (treeItem.getValue().getView().equals(view)) {
|
if(treeItem.getValue().getView().equals(view)) {
|
||||||
if (view.equals(TransactionView.INPUT) || view.equals(TransactionView.OUTPUT)) {
|
if(view.equals(TransactionView.INPUT) || view.equals(TransactionView.OUTPUT)) {
|
||||||
if (treeItem.getParent().getChildren().indexOf(treeItem) == index) {
|
IndexedTransactionForm txForm = (IndexedTransactionForm)treeItem.getValue();
|
||||||
|
if(txForm.getIndex() == index) {
|
||||||
txtree.getSelectionModel().select(treeItem);
|
txtree.getSelectionModel().select(treeItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +239,7 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
for(TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
||||||
select(childItem, view, index);
|
select(childItem, view, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,13 +275,18 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
//Inputs
|
//Inputs
|
||||||
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
||||||
|
if(i == highestInputIndex) {
|
||||||
|
txhex.append("...", "");
|
||||||
|
}
|
||||||
|
|
||||||
TransactionInput input = transaction.getInputs().get(i);
|
TransactionInput input = transaction.getInputs().get(i);
|
||||||
cursor = addText(hex, cursor, 32 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "hash"));
|
boolean skip = (i >= highestInputIndex);
|
||||||
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "index"));
|
cursor = addText(hex, cursor, 32 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "hash"), skip);
|
||||||
|
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "index"), skip);
|
||||||
VarInt scriptLen = new VarInt(input.getScriptBytes().length);
|
VarInt scriptLen = new VarInt(input.getScriptBytes().length);
|
||||||
cursor = addText(hex, cursor, scriptLen.getSizeInBytes() * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript-length"));
|
cursor = addText(hex, cursor, scriptLen.getSizeInBytes() * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript-length"), skip);
|
||||||
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript"));
|
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript"), skip);
|
||||||
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sequence"));
|
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sequence"), skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Number of outputs
|
//Number of outputs
|
||||||
|
@ -213,24 +295,34 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
//Outputs
|
//Outputs
|
||||||
for (int i = 0; i < transaction.getOutputs().size(); i++) {
|
for (int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||||
|
if(i == highestOutputIndex) {
|
||||||
|
txhex.append("...", "");
|
||||||
|
}
|
||||||
|
|
||||||
TransactionOutput output = transaction.getOutputs().get(i);
|
TransactionOutput output = transaction.getOutputs().get(i);
|
||||||
cursor = addText(hex, cursor, 8 * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "value"));
|
boolean skip = (i >= highestOutputIndex);
|
||||||
|
cursor = addText(hex, cursor, 8 * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "value"), skip);
|
||||||
VarInt scriptLen = new VarInt(output.getScriptBytes().length);
|
VarInt scriptLen = new VarInt(output.getScriptBytes().length);
|
||||||
cursor = addText(hex, cursor, scriptLen.getSizeInBytes() * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript-length"));
|
cursor = addText(hex, cursor, scriptLen.getSizeInBytes() * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript-length"), skip);
|
||||||
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript"));
|
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript"), skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transaction.hasWitnesses()) {
|
if (transaction.hasWitnesses()) {
|
||||||
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
||||||
|
if(i == highestInputIndex) {
|
||||||
|
txhex.append("...", "");
|
||||||
|
}
|
||||||
|
|
||||||
TransactionInput input = transaction.getInputs().get(i);
|
TransactionInput input = transaction.getInputs().get(i);
|
||||||
|
boolean skip = (i >= highestInputIndex);
|
||||||
if (input.hasWitness()) {
|
if (input.hasWitness()) {
|
||||||
TransactionWitness witness = input.getWitness();
|
TransactionWitness witness = input.getWitness();
|
||||||
VarInt witnessCount = new VarInt(witness.getPushCount());
|
VarInt witnessCount = new VarInt(witness.getPushCount());
|
||||||
cursor = addText(hex, cursor, witnessCount.getSizeInBytes() * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "count"));
|
cursor = addText(hex, cursor, witnessCount.getSizeInBytes() * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "count"), skip);
|
||||||
for (byte[] push : witness.getPushes()) {
|
for (byte[] push : witness.getPushes()) {
|
||||||
VarInt witnessLen = new VarInt(push.length);
|
VarInt witnessLen = new VarInt(push.length);
|
||||||
cursor = addText(hex, cursor, witnessLen.getSizeInBytes() * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "length"));
|
cursor = addText(hex, cursor, witnessLen.getSizeInBytes() * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "length"), skip);
|
||||||
cursor = addText(hex, cursor, (int) witnessLen.value * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "data"));
|
cursor = addText(hex, cursor, (int) witnessLen.value * 2, "witness-" + getIndexedStyleClass(i, selectedInputIndex, "data"), skip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,23 +331,30 @@ public class TransactionController implements Initializable {
|
||||||
//Locktime
|
//Locktime
|
||||||
cursor = addText(hex, cursor, 8, "locktime");
|
cursor = addText(hex, cursor, 8, "locktime");
|
||||||
|
|
||||||
if (cursor != hex.length()) {
|
if(cursor != hex.length()) {
|
||||||
throw new IllegalStateException("Cursor position does not match transaction serialisation " + cursor + ": " + hex.length());
|
throw new IllegalStateException("Cursor position does not match transaction serialisation " + cursor + ": " + hex.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchThisAndInputBlockTransactions() {
|
private void fetchThisAndInputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if (AppController.isOnline()) {
|
if(AppController.isOnline() && indexStart < transaction.getInputs().size()) {
|
||||||
Set<Sha256Hash> references = new HashSet<>();
|
Set<Sha256Hash> references = new HashSet<>();
|
||||||
if (psbt == null) {
|
if (psbt == null) {
|
||||||
references.add(transaction.getTxId());
|
references.add(transaction.getTxId());
|
||||||
}
|
}
|
||||||
for (TransactionInput input : transaction.getInputs()) {
|
|
||||||
|
int maxIndex = Math.min(transaction.getInputs().size(), indexEnd);
|
||||||
|
for(int i = indexStart; i < maxIndex; i++) {
|
||||||
|
TransactionInput input = transaction.getInputs().get(i);
|
||||||
if(!input.isCoinBase()) {
|
if(!input.isCoinBase()) {
|
||||||
references.add(input.getOutpoint().getHash());
|
references.add(input.getOutpoint().getHash());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(references.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(references);
|
ElectrumServer.TransactionReferenceService transactionReferenceService = new ElectrumServer.TransactionReferenceService(references);
|
||||||
transactionReferenceService.setOnSucceeded(successEvent -> {
|
transactionReferenceService.setOnSucceeded(successEvent -> {
|
||||||
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
Map<Sha256Hash, BlockTransaction> transactionMap = transactionReferenceService.getValue();
|
||||||
|
@ -279,7 +378,7 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
final BlockTransaction blockTx = thisBlockTx;
|
final BlockTransaction blockTx = thisBlockTx;
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
EventManager.get().post(new BlockTransactionFetchedEvent(transaction.getTxId(), blockTx, inputTransactions));
|
EventManager.get().post(new BlockTransactionFetchedEvent(transaction.getTxId(), blockTx, inputTransactions, indexStart, maxIndex));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
transactionReferenceService.setOnFailed(failedEvent -> {
|
transactionReferenceService.setOnFailed(failedEvent -> {
|
||||||
|
@ -289,13 +388,14 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchOutputBlockTransactions() {
|
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if (AppController.isOnline() && psbt == null) {
|
if(AppController.isOnline() && psbt == null && indexStart < transaction.getOutputs().size()) {
|
||||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(transaction);
|
int maxIndex = Math.min(transaction.getOutputs().size(), indexEnd);
|
||||||
|
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(transaction, indexStart, maxIndex);
|
||||||
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
transactionOutputsReferenceService.setOnSucceeded(successEvent -> {
|
||||||
List<BlockTransaction> outputTransactions = transactionOutputsReferenceService.getValue();
|
List<BlockTransaction> outputTransactions = transactionOutputsReferenceService.getValue();
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
EventManager.get().post(new BlockTransactionOutputsFetchedEvent(transaction.getTxId(), outputTransactions));
|
EventManager.get().post(new BlockTransactionOutputsFetchedEvent(transaction.getTxId(), outputTransactions, indexStart, maxIndex));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
transactionOutputsReferenceService.setOnFailed(failedEvent -> {
|
transactionOutputsReferenceService.setOnFailed(failedEvent -> {
|
||||||
|
@ -314,8 +414,15 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int addText(String hex, int cursor, int length, String styleClass) {
|
private int addText(String hex, int cursor, int length, String styleClass) {
|
||||||
txhex.append(hex.substring(cursor, cursor += length), styleClass);
|
return addText(hex, cursor, length, styleClass, false);
|
||||||
return cursor;
|
}
|
||||||
|
|
||||||
|
private int addText(String hex, int cursor, int length, String styleClass, boolean skip) {
|
||||||
|
if(!skip) {
|
||||||
|
txhex.append(hex.substring(cursor, cursor + length), styleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransaction(Transaction transaction) {
|
public void setTransaction(Transaction transaction) {
|
||||||
|
@ -332,6 +439,11 @@ public class TransactionController implements Initializable {
|
||||||
this.blockTransaction = blockTransaction;
|
this.blockTransaction = blockTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInitialView(TransactionView initialView, Integer initialIndex) {
|
||||||
|
this.initialView = initialView;
|
||||||
|
this.initialIndex = initialIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void transactionChanged(TransactionChangedEvent event) {
|
public void transactionChanged(TransactionChangedEvent event) {
|
||||||
if (event.getTransaction().equals(transaction)) {
|
if (event.getTransaction().equals(transaction)) {
|
||||||
|
@ -360,7 +472,11 @@ public class TransactionController implements Initializable {
|
||||||
private void setBlockTransaction(TreeItem<TransactionForm> treeItem, BlockTransactionFetchedEvent event) {
|
private void setBlockTransaction(TreeItem<TransactionForm> treeItem, BlockTransactionFetchedEvent event) {
|
||||||
TransactionForm form = treeItem.getValue();
|
TransactionForm form = treeItem.getValue();
|
||||||
form.setBlockTransaction(event.getBlockTransaction());
|
form.setBlockTransaction(event.getBlockTransaction());
|
||||||
|
if(form.getInputTransactions() == null) {
|
||||||
form.setInputTransactions(event.getInputTransactions());
|
form.setInputTransactions(event.getInputTransactions());
|
||||||
|
} else {
|
||||||
|
form.getInputTransactions().putAll(event.getInputTransactions());
|
||||||
|
}
|
||||||
|
|
||||||
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
||||||
setBlockTransaction(childItem, event);
|
setBlockTransaction(childItem, event);
|
||||||
|
@ -376,7 +492,16 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
private void setBlockTransactionOutputs(TreeItem<TransactionForm> treeItem, BlockTransactionOutputsFetchedEvent event) {
|
private void setBlockTransactionOutputs(TreeItem<TransactionForm> treeItem, BlockTransactionOutputsFetchedEvent event) {
|
||||||
TransactionForm form = treeItem.getValue();
|
TransactionForm form = treeItem.getValue();
|
||||||
|
if(form.getOutputTransactions() == null) {
|
||||||
form.setOutputTransactions(event.getOutputTransactions());
|
form.setOutputTransactions(event.getOutputTransactions());
|
||||||
|
} else {
|
||||||
|
for(int i = 0; i < event.getOutputTransactions().size(); i++) {
|
||||||
|
BlockTransaction outputTransaction = event.getOutputTransactions().get(i);
|
||||||
|
if(outputTransaction != null) {
|
||||||
|
form.getOutputTransactions().set(i, outputTransaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
||||||
setBlockTransactionOutputs(childItem, event);
|
setBlockTransactionOutputs(childItem, event);
|
||||||
|
|
Loading…
Reference in a new issue