mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
add layer of indirection to avoid copying tx data
This commit is contained in:
parent
ebc2f9442e
commit
6b12888111
11 changed files with 177 additions and 190 deletions
|
@ -619,14 +619,21 @@ public class AppController implements Initializable {
|
||||||
tab.setContent(transactionLoader.load());
|
tab.setContent(transactionLoader.load());
|
||||||
TransactionController controller = transactionLoader.getController();
|
TransactionController controller = transactionLoader.getController();
|
||||||
|
|
||||||
controller.setPSBT(psbt);
|
if(psbt != null) {
|
||||||
controller.setBlockTransaction(blockTransaction);
|
controller.setPSBT(psbt);
|
||||||
|
} else if(blockTransaction != null) {
|
||||||
|
controller.setBlockTransaction(blockTransaction);
|
||||||
|
} else {
|
||||||
|
controller.setTransaction(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
if(initialView != null) {
|
if(initialView != null) {
|
||||||
controller.setInitialView(initialView, initialIndex);
|
controller.setInitialView(initialView, initialIndex);
|
||||||
}
|
}
|
||||||
controller.setTransaction(transaction);
|
|
||||||
|
|
||||||
|
controller.initializeView();
|
||||||
tabs.getTabs().add(tab);
|
tabs.getTabs().add(tab);
|
||||||
|
|
||||||
return tab;
|
return tab;
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class HeadersForm extends TransactionForm {
|
public class HeadersForm extends TransactionForm {
|
||||||
public HeadersForm(PSBT psbt) {
|
public HeadersForm(TransactionData txdata) {
|
||||||
super(psbt);
|
super(txdata);
|
||||||
}
|
|
||||||
|
|
||||||
public HeadersForm(BlockTransaction blockTransaction) {
|
|
||||||
super(blockTransaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeadersForm(Transaction transaction) {
|
|
||||||
super(transaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,24 +1,10 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
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 {
|
public abstract class IndexedTransactionForm extends TransactionForm {
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
||||||
public IndexedTransactionForm(PSBT psbt, int index) {
|
public IndexedTransactionForm(TransactionData txdata, int index) {
|
||||||
super(psbt);
|
super(txdata);
|
||||||
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;
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionInput;
|
import com.sparrowwallet.drongo.protocol.TransactionInput;
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
import com.sparrowwallet.drongo.psbt.PSBTInput;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
import com.sparrowwallet.sparrow.io.ElectrumServer;
|
||||||
|
@ -16,19 +14,14 @@ public class InputForm extends IndexedTransactionForm {
|
||||||
private final TransactionInput transactionInput;
|
private final TransactionInput transactionInput;
|
||||||
private PSBTInput psbtInput;
|
private PSBTInput psbtInput;
|
||||||
|
|
||||||
public InputForm(PSBT psbt, PSBTInput psbtInput) {
|
public InputForm(TransactionData txdata, PSBTInput psbtInput) {
|
||||||
super(psbt, psbt.getPsbtInputs().indexOf(psbtInput));
|
super(txdata, txdata.getPsbt().getPsbtInputs().indexOf(psbtInput));
|
||||||
this.transactionInput = psbt.getTransaction().getInputs().get(psbt.getPsbtInputs().indexOf(psbtInput));
|
this.transactionInput = txdata.getPsbt().getTransaction().getInputs().get(txdata.getPsbt().getPsbtInputs().indexOf(psbtInput));
|
||||||
this.psbtInput = psbtInput;
|
this.psbtInput = psbtInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputForm(BlockTransaction blockTransaction, TransactionInput transactionInput) {
|
public InputForm(TransactionData txdata, TransactionInput transactionInput) {
|
||||||
super(blockTransaction, blockTransaction.getTransaction().getInputs().indexOf(transactionInput));
|
super(txdata, txdata.getTransaction().getInputs().indexOf(transactionInput));
|
||||||
this.transactionInput = transactionInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputForm(Transaction transaction, TransactionInput transactionInput) {
|
|
||||||
super(transaction, transaction.getInputs().indexOf(transactionInput));
|
|
||||||
this.transactionInput = transactionInput;
|
this.transactionInput = transactionInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class InputsForm extends TransactionForm {
|
public class InputsForm extends TransactionForm {
|
||||||
public InputsForm(PSBT psbt) {
|
public InputsForm(TransactionData txdata) {
|
||||||
super(psbt);
|
super(txdata);
|
||||||
}
|
|
||||||
|
|
||||||
public InputsForm(BlockTransaction blockTransaction) {
|
|
||||||
super(blockTransaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputsForm(Transaction transaction) {
|
|
||||||
super(transaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package com.sparrowwallet.sparrow.transaction;
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
|
||||||
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
import com.sparrowwallet.drongo.protocol.TransactionOutput;
|
||||||
import com.sparrowwallet.drongo.psbt.PSBT;
|
|
||||||
import com.sparrowwallet.drongo.psbt.PSBTOutput;
|
import com.sparrowwallet.drongo.psbt.PSBTOutput;
|
||||||
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
|
@ -14,19 +11,14 @@ 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(TransactionData txdata, PSBTOutput psbtOutput) {
|
||||||
super(psbt, psbt.getPsbtOutputs().indexOf(psbtOutput));
|
super(txdata, txdata.getPsbt().getPsbtOutputs().indexOf(psbtOutput));
|
||||||
this.transactionOutput = psbt.getTransaction().getOutputs().get(psbt.getPsbtOutputs().indexOf(psbtOutput));
|
this.transactionOutput = txdata.getPsbt().getTransaction().getOutputs().get(txdata.getPsbt().getPsbtOutputs().indexOf(psbtOutput));
|
||||||
this.psbtOutput = psbtOutput;
|
this.psbtOutput = psbtOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputForm(BlockTransaction blockTransaction, TransactionOutput transactionOutput) {
|
public OutputForm(TransactionData txdata, TransactionOutput transactionOutput) {
|
||||||
super(blockTransaction, blockTransaction.getTransaction().getOutputs().indexOf(transactionOutput));
|
super(txdata, txdata.getTransaction().getOutputs().indexOf(transactionOutput));
|
||||||
this.transactionOutput = transactionOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OutputForm(Transaction transaction, TransactionOutput transactionOutput) {
|
|
||||||
super(transaction, transaction.getOutputs().indexOf(transactionOutput));
|
|
||||||
this.transactionOutput = transactionOutput;
|
this.transactionOutput = transactionOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,8 @@ import javafx.scene.Node;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class OutputsForm extends TransactionForm {
|
public class OutputsForm extends TransactionForm {
|
||||||
public OutputsForm(PSBT psbt) {
|
public OutputsForm(TransactionData txdata) {
|
||||||
super(psbt);
|
super(txdata);
|
||||||
}
|
|
||||||
|
|
||||||
public OutputsForm(BlockTransaction blockTransaction) {
|
|
||||||
super(blockTransaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OutputsForm(Transaction transaction) {
|
|
||||||
super(transaction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,7 +13,7 @@ public class PageForm extends IndexedTransactionForm {
|
||||||
private final int pageEnd;
|
private final int pageEnd;
|
||||||
|
|
||||||
public PageForm(TransactionView view, int pageStart, int pageEnd) {
|
public PageForm(TransactionView view, int pageStart, int pageEnd) {
|
||||||
super(ElectrumServer.UNFETCHABLE_BLOCK_TRANSACTION, pageStart);
|
super(new TransactionData(ElectrumServer.UNFETCHABLE_BLOCK_TRANSACTION), pageStart);
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.pageStart = pageStart;
|
this.pageStart = pageStart;
|
||||||
this.pageEnd = pageEnd;
|
this.pageEnd = pageEnd;
|
||||||
|
|
|
@ -46,9 +46,7 @@ public class TransactionController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private CodeArea txhex;
|
private CodeArea txhex;
|
||||||
|
|
||||||
private Transaction transaction;
|
private TransactionData txdata;
|
||||||
private PSBT psbt;
|
|
||||||
private BlockTransaction blockTransaction;
|
|
||||||
|
|
||||||
private TransactionView initialView;
|
private TransactionView initialView;
|
||||||
private Integer initialIndex;
|
private Integer initialIndex;
|
||||||
|
@ -64,9 +62,9 @@ public class TransactionController implements Initializable {
|
||||||
EventManager.get().register(this);
|
EventManager.get().register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeView() {
|
public void initializeView() {
|
||||||
highestInputIndex = Math.min(transaction.getInputs().size(), PageForm.PAGE_SIZE);
|
highestInputIndex = Math.min(getTransaction().getInputs().size(), PageForm.PAGE_SIZE);
|
||||||
highestOutputIndex = Math.min(transaction.getOutputs().size(), PageForm.PAGE_SIZE);
|
highestOutputIndex = Math.min(getTransaction().getOutputs().size(), PageForm.PAGE_SIZE);
|
||||||
|
|
||||||
initializeTxTree();
|
initializeTxTree();
|
||||||
transactionMasterDetail.setShowDetailNode(AppController.showTxHexProperty);
|
transactionMasterDetail.setShowDetailNode(AppController.showTxHexProperty);
|
||||||
|
@ -76,15 +74,15 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTxTree() {
|
private void initializeTxTree() {
|
||||||
HeadersForm headersForm = (psbt != null ? new HeadersForm(psbt) : (blockTransaction != null ? new HeadersForm(blockTransaction) : new HeadersForm(transaction)));
|
HeadersForm headersForm = new HeadersForm(txdata);
|
||||||
TreeItem<TransactionForm> rootItem = new TreeItem<>(headersForm);
|
TreeItem<TransactionForm> rootItem = new TreeItem<>(headersForm);
|
||||||
rootItem.setExpanded(true);
|
rootItem.setExpanded(true);
|
||||||
|
|
||||||
InputsForm inputsForm = (psbt != null ? new InputsForm(psbt) : (blockTransaction != null ? new InputsForm(blockTransaction) : new InputsForm(transaction)));
|
InputsForm inputsForm = new InputsForm(txdata);
|
||||||
TreeItem<TransactionForm> inputsItem = new TreeItem<>(inputsForm);
|
TreeItem<TransactionForm> inputsItem = new TreeItem<>(inputsForm);
|
||||||
inputsItem.setExpanded(true);
|
inputsItem.setExpanded(true);
|
||||||
boolean inputPagingAdded = false;
|
boolean inputPagingAdded = false;
|
||||||
for(int i = 0; i < transaction.getInputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getInputs().size(); i++) {
|
||||||
if(i < PageForm.PAGE_SIZE || (TransactionView.INPUT.equals(initialView) && i == initialIndex)) {
|
if(i < PageForm.PAGE_SIZE || (TransactionView.INPUT.equals(initialView) && i == initialIndex)) {
|
||||||
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
TreeItem<TransactionForm> inputItem = createInputTreeItem(i);
|
||||||
inputsItem.getChildren().add(inputItem);
|
inputsItem.getChildren().add(inputItem);
|
||||||
|
@ -96,11 +94,11 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputsForm outputsForm = (psbt != null ? new OutputsForm(psbt) : (blockTransaction != null ? new OutputsForm(blockTransaction) : new OutputsForm(transaction)));
|
OutputsForm outputsForm = new OutputsForm(txdata);
|
||||||
TreeItem<TransactionForm> outputsItem = new TreeItem<>(outputsForm);
|
TreeItem<TransactionForm> outputsItem = new TreeItem<>(outputsForm);
|
||||||
outputsItem.setExpanded(true);
|
outputsItem.setExpanded(true);
|
||||||
boolean outputPagingAdded = false;
|
boolean outputPagingAdded = false;
|
||||||
for(int i = 0; i < transaction.getOutputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getOutputs().size(); i++) {
|
||||||
if(i < PageForm.PAGE_SIZE || (TransactionView.OUTPUT.equals(initialView) && i == initialIndex)) {
|
if(i < PageForm.PAGE_SIZE || (TransactionView.OUTPUT.equals(initialView) && i == initialIndex)) {
|
||||||
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
TreeItem<TransactionForm> outputItem = createOutputTreeItem(i);
|
||||||
outputsItem.getChildren().add(outputItem);
|
outputsItem.getChildren().add(outputItem);
|
||||||
|
@ -139,7 +137,7 @@ public class TransactionController implements Initializable {
|
||||||
TreeItem<TransactionForm> parentItem = optParentItem.get();
|
TreeItem<TransactionForm> parentItem = optParentItem.get();
|
||||||
parentItem.getChildren().remove(selectedItem);
|
parentItem.getChildren().remove(selectedItem);
|
||||||
|
|
||||||
int max = pageForm.getView().equals(TransactionView.INPUT) ? transaction.getInputs().size() : transaction.getOutputs().size();
|
int max = pageForm.getView().equals(TransactionView.INPUT) ? getTransaction().getInputs().size() : getTransaction().getOutputs().size();
|
||||||
for(int i = pageForm.getPageStart(); i < max && i < pageForm.getPageEnd(); i++) {
|
for(int i = pageForm.getPageStart(); i < max && i < pageForm.getPageEnd(); i++) {
|
||||||
TreeItem<TransactionForm> newItem = pageForm.getView().equals(TransactionView.INPUT) ? createInputTreeItem(i) : createOutputTreeItem(i);
|
TreeItem<TransactionForm> newItem = pageForm.getView().equals(TransactionView.INPUT) ? createInputTreeItem(i) : createOutputTreeItem(i);
|
||||||
parentItem.getChildren().add(newItem);
|
parentItem.getChildren().add(newItem);
|
||||||
|
@ -202,22 +200,22 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeItem<TransactionForm> createInputTreeItem(int inputIndex) {
|
private TreeItem<TransactionForm> createInputTreeItem(int inputIndex) {
|
||||||
TransactionInput txInput = transaction.getInputs().get(inputIndex);
|
TransactionInput txInput = getTransaction().getInputs().get(inputIndex);
|
||||||
PSBTInput psbtInput = null;
|
PSBTInput psbtInput = null;
|
||||||
if (psbt != null && psbt.getPsbtInputs().size() > txInput.getIndex()) {
|
if(getPSBT() != null && getPSBT().getPsbtInputs().size() > txInput.getIndex()) {
|
||||||
psbtInput = psbt.getPsbtInputs().get(txInput.getIndex());
|
psbtInput = getPSBT().getPsbtInputs().get(txInput.getIndex());
|
||||||
}
|
}
|
||||||
InputForm inputForm = (psbt != null ? new InputForm(psbt, psbtInput) : (blockTransaction != null ? new InputForm(blockTransaction, txInput) : new InputForm(transaction, txInput)));
|
InputForm inputForm = (getPSBT() != null ? new InputForm(txdata, psbtInput) : new InputForm(txdata, txInput));
|
||||||
return new TreeItem<>(inputForm);
|
return new TreeItem<>(inputForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeItem<TransactionForm> createOutputTreeItem(int outputIndex) {
|
private TreeItem<TransactionForm> createOutputTreeItem(int outputIndex) {
|
||||||
TransactionOutput txOutput = transaction.getOutputs().get(outputIndex);
|
TransactionOutput txOutput = getTransaction().getOutputs().get(outputIndex);
|
||||||
PSBTOutput psbtOutput = null;
|
PSBTOutput psbtOutput = null;
|
||||||
if (psbt != null && psbt.getPsbtOutputs().size() > txOutput.getIndex()) {
|
if (getPSBT() != null && getPSBT().getPsbtOutputs().size() > txOutput.getIndex()) {
|
||||||
psbtOutput = psbt.getPsbtOutputs().get(txOutput.getIndex());
|
psbtOutput = getPSBT().getPsbtOutputs().get(txOutput.getIndex());
|
||||||
}
|
}
|
||||||
OutputForm outputForm = (psbt != null ? new OutputForm(psbt, psbtOutput) : (blockTransaction != null ? new OutputForm(blockTransaction, txOutput) : new OutputForm(transaction, txOutput)));
|
OutputForm outputForm = (getPSBT() != null ? new OutputForm(txdata, psbtOutput) : new OutputForm(txdata, txOutput));
|
||||||
return new TreeItem<>(outputForm);
|
return new TreeItem<>(outputForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +249,7 @@ public class TransactionController implements Initializable {
|
||||||
String hex = "";
|
String hex = "";
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
transaction.bitcoinSerializeToStream(baos);
|
getTransaction().bitcoinSerializeToStream(baos);
|
||||||
hex = Utils.bytesToHex(baos.toByteArray());
|
hex = Utils.bytesToHex(baos.toByteArray());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IllegalStateException("Can't happen");
|
throw new IllegalStateException("Can't happen");
|
||||||
|
@ -262,7 +260,7 @@ public class TransactionController implements Initializable {
|
||||||
//Version
|
//Version
|
||||||
cursor = addText(hex, cursor, 8, "version");
|
cursor = addText(hex, cursor, 8, "version");
|
||||||
|
|
||||||
if (transaction.hasWitnesses()) {
|
if(getTransaction().hasWitnesses()) {
|
||||||
//Segwit marker
|
//Segwit marker
|
||||||
cursor = addText(hex, cursor, 2, "segwit-marker");
|
cursor = addText(hex, cursor, 2, "segwit-marker");
|
||||||
//Segwit flag
|
//Segwit flag
|
||||||
|
@ -270,16 +268,16 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Number of inputs
|
//Number of inputs
|
||||||
VarInt numInputs = new VarInt(transaction.getInputs().size());
|
VarInt numInputs = new VarInt(getTransaction().getInputs().size());
|
||||||
cursor = addText(hex, cursor, numInputs.getSizeInBytes() * 2, "num-inputs");
|
cursor = addText(hex, cursor, numInputs.getSizeInBytes() * 2, "num-inputs");
|
||||||
|
|
||||||
//Inputs
|
//Inputs
|
||||||
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getInputs().size(); i++) {
|
||||||
if(i == highestInputIndex) {
|
if(i == highestInputIndex) {
|
||||||
txhex.append("...", "");
|
txhex.append("...", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionInput input = transaction.getInputs().get(i);
|
TransactionInput input = getTransaction().getInputs().get(i);
|
||||||
boolean skip = (i >= highestInputIndex);
|
boolean skip = (i >= highestInputIndex);
|
||||||
cursor = addText(hex, cursor, 32 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "hash"), skip);
|
cursor = addText(hex, cursor, 32 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "hash"), skip);
|
||||||
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "index"), skip);
|
cursor = addText(hex, cursor, 4 * 2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "index"), skip);
|
||||||
|
@ -290,16 +288,16 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Number of outputs
|
//Number of outputs
|
||||||
VarInt numOutputs = new VarInt(transaction.getOutputs().size());
|
VarInt numOutputs = new VarInt(getTransaction().getOutputs().size());
|
||||||
cursor = addText(hex, cursor, numOutputs.getSizeInBytes() * 2, "num-outputs");
|
cursor = addText(hex, cursor, numOutputs.getSizeInBytes() * 2, "num-outputs");
|
||||||
|
|
||||||
//Outputs
|
//Outputs
|
||||||
for (int i = 0; i < transaction.getOutputs().size(); i++) {
|
for(int i = 0; i < getTransaction().getOutputs().size(); i++) {
|
||||||
if(i == highestOutputIndex) {
|
if(i == highestOutputIndex) {
|
||||||
txhex.append("...", "");
|
txhex.append("...", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionOutput output = transaction.getOutputs().get(i);
|
TransactionOutput output = getTransaction().getOutputs().get(i);
|
||||||
boolean skip = (i >= highestOutputIndex);
|
boolean skip = (i >= highestOutputIndex);
|
||||||
cursor = addText(hex, cursor, 8 * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "value"), skip);
|
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);
|
||||||
|
@ -307,13 +305,13 @@ public class TransactionController implements Initializable {
|
||||||
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript"), skip);
|
cursor = addText(hex, cursor, (int) scriptLen.value * 2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript"), skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transaction.hasWitnesses()) {
|
if(getTransaction().hasWitnesses()) {
|
||||||
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
for (int i = 0; i < getTransaction().getInputs().size(); i++) {
|
||||||
if(i == highestInputIndex) {
|
if(i == highestInputIndex) {
|
||||||
txhex.append("...", "");
|
txhex.append("...", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionInput input = transaction.getInputs().get(i);
|
TransactionInput input = getTransaction().getInputs().get(i);
|
||||||
boolean skip = (i >= highestInputIndex);
|
boolean skip = (i >= highestInputIndex);
|
||||||
if (input.hasWitness()) {
|
if (input.hasWitness()) {
|
||||||
TransactionWitness witness = input.getWitness();
|
TransactionWitness witness = input.getWitness();
|
||||||
|
@ -337,15 +335,15 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchThisAndInputBlockTransactions(int indexStart, int indexEnd) {
|
private void fetchThisAndInputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if(AppController.isOnline() && indexStart < transaction.getInputs().size()) {
|
if(AppController.isOnline() && indexStart < getTransaction().getInputs().size()) {
|
||||||
Set<Sha256Hash> references = new HashSet<>();
|
Set<Sha256Hash> references = new HashSet<>();
|
||||||
if (psbt == null) {
|
if(getPSBT() == null) {
|
||||||
references.add(transaction.getTxId());
|
references.add(getTransaction().getTxId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxIndex = Math.min(transaction.getInputs().size(), indexEnd);
|
int maxIndex = Math.min(getTransaction().getInputs().size(), indexEnd);
|
||||||
for(int i = indexStart; i < maxIndex; i++) {
|
for(int i = indexStart; i < maxIndex; i++) {
|
||||||
TransactionInput input = transaction.getInputs().get(i);
|
TransactionInput input = getTransaction().getInputs().get(i);
|
||||||
if(!input.isCoinBase()) {
|
if(!input.isCoinBase()) {
|
||||||
references.add(input.getOutpoint().getHash());
|
references.add(input.getOutpoint().getHash());
|
||||||
}
|
}
|
||||||
|
@ -362,7 +360,7 @@ public class TransactionController implements Initializable {
|
||||||
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(transaction.getTxId())) {
|
if (txid.equals(getTransaction().getTxId())) {
|
||||||
thisBlockTx = blockTx;
|
thisBlockTx = blockTx;
|
||||||
} else {
|
} else {
|
||||||
inputTransactions.put(txid, blockTx);
|
inputTransactions.put(txid, blockTx);
|
||||||
|
@ -370,7 +368,7 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
references.remove(transaction.getTxId());
|
references.remove(getTransaction().getTxId());
|
||||||
if (!references.isEmpty()) {
|
if (!references.isEmpty()) {
|
||||||
System.out.println("Failed to retrieve all referenced input transactions, aborting transaction fetch");
|
System.out.println("Failed to retrieve all referenced input transactions, aborting transaction fetch");
|
||||||
return;
|
return;
|
||||||
|
@ -378,7 +376,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, indexStart, maxIndex));
|
EventManager.get().post(new BlockTransactionFetchedEvent(getTransaction().getTxId(), blockTx, inputTransactions, indexStart, maxIndex));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
transactionReferenceService.setOnFailed(failedEvent -> {
|
transactionReferenceService.setOnFailed(failedEvent -> {
|
||||||
|
@ -389,13 +387,13 @@ public class TransactionController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
private void fetchOutputBlockTransactions(int indexStart, int indexEnd) {
|
||||||
if(AppController.isOnline() && psbt == null && indexStart < transaction.getOutputs().size()) {
|
if(AppController.isOnline() && getPSBT() == null && indexStart < getTransaction().getOutputs().size()) {
|
||||||
int maxIndex = Math.min(transaction.getOutputs().size(), indexEnd);
|
int maxIndex = Math.min(getTransaction().getOutputs().size(), indexEnd);
|
||||||
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(transaction, indexStart, maxIndex);
|
ElectrumServer.TransactionOutputsReferenceService transactionOutputsReferenceService = new ElectrumServer.TransactionOutputsReferenceService(getTransaction(), 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, indexStart, maxIndex));
|
EventManager.get().post(new BlockTransactionOutputsFetchedEvent(getTransaction().getTxId(), outputTransactions, indexStart, maxIndex));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
transactionOutputsReferenceService.setOnFailed(failedEvent -> {
|
transactionOutputsReferenceService.setOnFailed(failedEvent -> {
|
||||||
|
@ -425,18 +423,28 @@ public class TransactionController implements Initializable {
|
||||||
return cursor + length;
|
return cursor + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransaction(Transaction transaction) {
|
public Transaction getTransaction() {
|
||||||
this.transaction = transaction;
|
return txdata.getTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
initializeView();
|
public void setTransaction(Transaction transaction) {
|
||||||
|
this.txdata = new TransactionData(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PSBT getPSBT() {
|
||||||
|
return txdata.getPsbt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPSBT(PSBT psbt) {
|
public void setPSBT(PSBT psbt) {
|
||||||
this.psbt = psbt;
|
this.txdata = new TransactionData(psbt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockTransaction getBlockTransaction() {
|
||||||
|
return txdata.getBlockTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockTransaction(BlockTransaction blockTransaction) {
|
public void setBlockTransaction(BlockTransaction blockTransaction) {
|
||||||
this.blockTransaction = blockTransaction;
|
this.txdata = new TransactionData(blockTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInitialView(TransactionView initialView, Integer initialIndex) {
|
public void setInitialView(TransactionView initialView, Integer initialIndex) {
|
||||||
|
@ -446,7 +454,7 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void transactionChanged(TransactionChangedEvent event) {
|
public void transactionChanged(TransactionChangedEvent event) {
|
||||||
if (event.getTransaction().equals(transaction)) {
|
if(event.getTransaction().equals(getTransaction())) {
|
||||||
refreshTxHex();
|
refreshTxHex();
|
||||||
txtree.refresh();
|
txtree.refresh();
|
||||||
}
|
}
|
||||||
|
@ -464,47 +472,29 @@ public class TransactionController implements Initializable {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
public void blockTransactionFetched(BlockTransactionFetchedEvent event) {
|
||||||
if (event.getTxId().equals(transaction.getTxId())) {
|
if(event.getTxId().equals(getTransaction().getTxId())) {
|
||||||
setBlockTransaction(txtree.getRoot(), event);
|
txdata.setBlockTransaction(event.getBlockTransaction());
|
||||||
}
|
if(txdata.getInputTransactions() == null) {
|
||||||
}
|
txdata.setInputTransactions(event.getInputTransactions());
|
||||||
|
} else {
|
||||||
private void setBlockTransaction(TreeItem<TransactionForm> treeItem, BlockTransactionFetchedEvent event) {
|
txdata.getInputTransactions().putAll(event.getInputTransactions());
|
||||||
TransactionForm form = treeItem.getValue();
|
}
|
||||||
form.setBlockTransaction(event.getBlockTransaction());
|
|
||||||
if(form.getInputTransactions() == null) {
|
|
||||||
form.setInputTransactions(event.getInputTransactions());
|
|
||||||
} else {
|
|
||||||
form.getInputTransactions().putAll(event.getInputTransactions());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TreeItem<TransactionForm> childItem : treeItem.getChildren()) {
|
|
||||||
setBlockTransaction(childItem, event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void blockTransactionOutputsFetched(BlockTransactionOutputsFetchedEvent event) {
|
public void blockTransactionOutputsFetched(BlockTransactionOutputsFetchedEvent event) {
|
||||||
if (event.getTxId().equals(transaction.getTxId())) {
|
if (event.getTxId().equals(getTransaction().getTxId())) {
|
||||||
setBlockTransactionOutputs(txtree.getRoot(), event);
|
if(txdata.getOutputTransactions() == null) {
|
||||||
}
|
txdata.setOutputTransactions(event.getOutputTransactions());
|
||||||
}
|
} else {
|
||||||
|
for(int i = 0; i < event.getOutputTransactions().size(); i++) {
|
||||||
private void setBlockTransactionOutputs(TreeItem<TransactionForm> treeItem, BlockTransactionOutputsFetchedEvent event) {
|
BlockTransaction outputTransaction = event.getOutputTransactions().get(i);
|
||||||
TransactionForm form = treeItem.getValue();
|
if(outputTransaction != null) {
|
||||||
if(form.getOutputTransactions() == null) {
|
txdata.getOutputTransactions().set(i, outputTransaction);
|
||||||
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()) {
|
|
||||||
setBlockTransactionOutputs(childItem, event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.sparrowwallet.sparrow.transaction;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
|
import com.sparrowwallet.drongo.psbt.PSBT;
|
||||||
|
import com.sparrowwallet.drongo.wallet.BlockTransaction;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TransactionData {
|
||||||
|
private final Transaction transaction;
|
||||||
|
private PSBT psbt;
|
||||||
|
private BlockTransaction blockTransaction;
|
||||||
|
private Map<Sha256Hash, BlockTransaction> inputTransactions;
|
||||||
|
private List<BlockTransaction> outputTransactions;
|
||||||
|
|
||||||
|
public TransactionData(PSBT psbt) {
|
||||||
|
this.transaction = psbt.getTransaction();
|
||||||
|
this.psbt = psbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionData(BlockTransaction blockTransaction) {
|
||||||
|
this.transaction = blockTransaction.getTransaction();
|
||||||
|
this.blockTransaction = blockTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionData(Transaction transaction) {
|
||||||
|
this.transaction = transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction getTransaction() {
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PSBT getPsbt() {
|
||||||
|
return psbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockTransaction getBlockTransaction() {
|
||||||
|
return blockTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBlockTransaction(BlockTransaction blockTransaction) {
|
||||||
|
this.blockTransaction = blockTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Sha256Hash, BlockTransaction> getInputTransactions() {
|
||||||
|
return inputTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputTransactions(Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
||||||
|
this.inputTransactions = inputTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BlockTransaction> getOutputTransactions() {
|
||||||
|
return outputTransactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutputTransactions(List<BlockTransaction> outputTransactions) {
|
||||||
|
this.outputTransactions = outputTransactions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,60 +11,46 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class TransactionForm {
|
public abstract class TransactionForm {
|
||||||
private final Transaction transaction;
|
private final TransactionData txdata;
|
||||||
private PSBT psbt;
|
|
||||||
private BlockTransaction blockTransaction;
|
|
||||||
private Map<Sha256Hash, BlockTransaction> inputTransactions;
|
|
||||||
private List<BlockTransaction> outputTransactions;
|
|
||||||
|
|
||||||
public TransactionForm(PSBT psbt) {
|
public TransactionForm(TransactionData txdata) {
|
||||||
this.transaction = psbt.getTransaction();
|
this.txdata = txdata;
|
||||||
this.psbt = psbt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransactionForm(BlockTransaction blockTransaction) {
|
|
||||||
this.transaction = blockTransaction.getTransaction();
|
|
||||||
this.blockTransaction = blockTransaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransactionForm(Transaction transaction) {
|
|
||||||
this.transaction = transaction;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction getTransaction() {
|
public Transaction getTransaction() {
|
||||||
return transaction;
|
return txdata.getTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PSBT getPsbt() {
|
public PSBT getPsbt() {
|
||||||
return psbt;
|
return txdata.getPsbt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockTransaction getBlockTransaction() {
|
public BlockTransaction getBlockTransaction() {
|
||||||
return blockTransaction;
|
return txdata.getBlockTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockTransaction(BlockTransaction blockTransaction) {
|
public void setBlockTransaction(BlockTransaction blockTransaction) {
|
||||||
this.blockTransaction = blockTransaction;
|
txdata.setBlockTransaction(blockTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Sha256Hash, BlockTransaction> getInputTransactions() {
|
public Map<Sha256Hash, BlockTransaction> getInputTransactions() {
|
||||||
return inputTransactions;
|
return txdata.getInputTransactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInputTransactions(Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
public void setInputTransactions(Map<Sha256Hash, BlockTransaction> inputTransactions) {
|
||||||
this.inputTransactions = inputTransactions;
|
txdata.setInputTransactions(inputTransactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BlockTransaction> getOutputTransactions() {
|
public List<BlockTransaction> getOutputTransactions() {
|
||||||
return outputTransactions;
|
return txdata.getOutputTransactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOutputTransactions(List<BlockTransaction> outputTransactions) {
|
public void setOutputTransactions(List<BlockTransaction> outputTransactions) {
|
||||||
this.outputTransactions = outputTransactions;
|
txdata.setOutputTransactions(outputTransactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEditable() {
|
public boolean isEditable() {
|
||||||
return blockTransaction == null;
|
return txdata.getBlockTransaction() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Node getContents() throws IOException;
|
public abstract Node getContents() throws IOException;
|
||||||
|
|
Loading…
Reference in a new issue