From 9c9836147ab77b28fed9b6bdc8eb1e14fd1e1217 Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Tue, 3 Nov 2020 13:52:55 +0200 Subject: [PATCH] support partially finalized psbts --- .../com/sparrowwallet/drongo/psbt/PSBT.java | 36 ++++++++++++++----- .../sparrowwallet/drongo/psbt/PSBTInput.java | 12 +++++-- .../sparrowwallet/drongo/wallet/Wallet.java | 6 +++- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java index 15e7a5a..b234729 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBT.java @@ -253,7 +253,9 @@ public class PSBT { } } - log.debug("Calculated fee at " + getFee()); + if(log.isDebugEnabled()) { + log.debug("Calculated fee at " + getFee()); + } } private void parseGlobalEntries(List globalEntries) throws PSBTParseException { @@ -395,12 +397,12 @@ public class PSBT { public boolean isFinalized() { for(PSBTInput psbtInput : getPsbtInputs()) { - if(psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { - return true; + if(!psbtInput.isFinalized()) { + return false; } } - return false; + return true; } private List getGlobalEntries() { @@ -499,9 +501,6 @@ public class PSBT { public Transaction extractTransaction() { boolean hasWitness = false; for(PSBTInput psbtInput : getPsbtInputs()) { - if(psbtInput.getFinalScriptSig() == null) { - return null; - } if(psbtInput.getFinalScriptWitness() != null) { hasWitness = true; } @@ -516,7 +515,7 @@ public class PSBT { for(int i = 0; i < finalTransaction.getInputs().size(); i++) { TransactionInput txInput = finalTransaction.getInputs().get(i); PSBTInput psbtInput = getPsbtInputs().get(i); - txInput.setScriptBytes(psbtInput.getFinalScriptSig().getProgram()); + txInput.setScriptBytes(psbtInput.getFinalScriptSig() == null ? new byte[0] : psbtInput.getFinalScriptSig().getProgram()); if(hasWitness) { if(psbtInput.getFinalScriptWitness() != null) { @@ -530,6 +529,27 @@ public class PSBT { return finalTransaction; } + public PSBT getPublicCopy() { + try { + PSBT publicCopy = new PSBT(serialize()); + publicCopy.extendedPublicKeys.clear(); + for(PSBTInput psbtInput : publicCopy.getPsbtInputs()) { + psbtInput.clearPrivateFields(); + } + for(PSBTOutput psbtOutput : publicCopy.getPsbtOutputs()) { + psbtOutput.getDerivedPublicKeys().clear(); + psbtOutput.getProprietary().clear(); + } + if(publicCopy.isFinalized()) { + publicCopy.transaction = publicCopy.extractTransaction(); + } + + return publicCopy; + } catch(PSBTParseException e) { + throw new IllegalStateException("Could not parse PSBT", e); + } + } + public List getPsbtInputs() { return psbtInputs; } diff --git a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java index 67308da..8179408 100644 --- a/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java +++ b/src/main/java/com/sparrowwallet/drongo/psbt/PSBTInput.java @@ -386,7 +386,7 @@ public class PSBTInput { return false; } } else { - return getFinalScriptSig() != null; + return isFinalized(); } } @@ -525,12 +525,20 @@ public class PSBTInput { return signingScript; } + public boolean isFinalized() { + return getFinalScriptSig() != null || getFinalScriptWitness() != null; + } + + public TransactionInput getInput() { + return transaction.getInputs().get(index); + } + public TransactionOutput getUtxo() { int vout = (int)transaction.getInputs().get(index).getOutpoint().getIndex(); return getWitnessUtxo() != null ? getWitnessUtxo() : (getNonWitnessUtxo() != null ? getNonWitnessUtxo().getOutputs().get(vout) : null); } - public void clearFinalised() { + public void clearPrivateFields() { partialSignatures.clear(); sigHash = null; redeemScript = null; diff --git a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java index 843bb78..1e53dd8 100644 --- a/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java +++ b/src/main/java/com/sparrowwallet/drongo/wallet/Wallet.java @@ -713,6 +713,10 @@ public class Wallet { TransactionInput txInput = psbt.getTransaction().getInputs().get(i); PSBTInput psbtInput = psbt.getPsbtInputs().get(i); + if(psbtInput.isFinalized()) { + continue; + } + WalletNode signingNode = signingNodes.get(psbtInput); //Transaction parent on PSBT utxo might be null in a witness tx, so get utxo tx hash and utxo index from PSBT tx input @@ -760,7 +764,7 @@ public class Wallet { psbtInput.setFinalScriptSig(finalizedTxInput.getScriptSig()); psbtInput.setFinalScriptWitness(finalizedTxInput.getWitness()); - psbtInput.clearFinalised(); + psbtInput.clearPrivateFields(); } } }