support partially finalized psbts

This commit is contained in:
Craig Raw 2020-11-03 13:52:55 +02:00
parent 8541348b5b
commit 9c9836147a
3 changed files with 43 additions and 11 deletions

View file

@ -253,8 +253,10 @@ public class PSBT {
} }
} }
if(log.isDebugEnabled()) {
log.debug("Calculated fee at " + getFee()); log.debug("Calculated fee at " + getFee());
} }
}
private void parseGlobalEntries(List<PSBTEntry> globalEntries) throws PSBTParseException { private void parseGlobalEntries(List<PSBTEntry> globalEntries) throws PSBTParseException {
PSBTEntry duplicate = findDuplicateKey(globalEntries); PSBTEntry duplicate = findDuplicateKey(globalEntries);
@ -395,12 +397,12 @@ public class PSBT {
public boolean isFinalized() { public boolean isFinalized() {
for(PSBTInput psbtInput : getPsbtInputs()) { for(PSBTInput psbtInput : getPsbtInputs()) {
if(psbtInput.getFinalScriptSig() != null || psbtInput.getFinalScriptWitness() != null) { if(!psbtInput.isFinalized()) {
return true; return false;
} }
} }
return false; return true;
} }
private List<PSBTEntry> getGlobalEntries() { private List<PSBTEntry> getGlobalEntries() {
@ -499,9 +501,6 @@ public class PSBT {
public Transaction extractTransaction() { public Transaction extractTransaction() {
boolean hasWitness = false; boolean hasWitness = false;
for(PSBTInput psbtInput : getPsbtInputs()) { for(PSBTInput psbtInput : getPsbtInputs()) {
if(psbtInput.getFinalScriptSig() == null) {
return null;
}
if(psbtInput.getFinalScriptWitness() != null) { if(psbtInput.getFinalScriptWitness() != null) {
hasWitness = true; hasWitness = true;
} }
@ -516,7 +515,7 @@ public class PSBT {
for(int i = 0; i < finalTransaction.getInputs().size(); i++) { for(int i = 0; i < finalTransaction.getInputs().size(); i++) {
TransactionInput txInput = finalTransaction.getInputs().get(i); TransactionInput txInput = finalTransaction.getInputs().get(i);
PSBTInput psbtInput = getPsbtInputs().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(hasWitness) {
if(psbtInput.getFinalScriptWitness() != null) { if(psbtInput.getFinalScriptWitness() != null) {
@ -530,6 +529,27 @@ public class PSBT {
return finalTransaction; 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<PSBTInput> getPsbtInputs() { public List<PSBTInput> getPsbtInputs() {
return psbtInputs; return psbtInputs;
} }

View file

@ -386,7 +386,7 @@ public class PSBTInput {
return false; return false;
} }
} else { } else {
return getFinalScriptSig() != null; return isFinalized();
} }
} }
@ -525,12 +525,20 @@ public class PSBTInput {
return signingScript; return signingScript;
} }
public boolean isFinalized() {
return getFinalScriptSig() != null || getFinalScriptWitness() != null;
}
public TransactionInput getInput() {
return transaction.getInputs().get(index);
}
public TransactionOutput getUtxo() { public TransactionOutput getUtxo() {
int vout = (int)transaction.getInputs().get(index).getOutpoint().getIndex(); int vout = (int)transaction.getInputs().get(index).getOutpoint().getIndex();
return getWitnessUtxo() != null ? getWitnessUtxo() : (getNonWitnessUtxo() != null ? getNonWitnessUtxo().getOutputs().get(vout) : null); return getWitnessUtxo() != null ? getWitnessUtxo() : (getNonWitnessUtxo() != null ? getNonWitnessUtxo().getOutputs().get(vout) : null);
} }
public void clearFinalised() { public void clearPrivateFields() {
partialSignatures.clear(); partialSignatures.clear();
sigHash = null; sigHash = null;
redeemScript = null; redeemScript = null;

View file

@ -713,6 +713,10 @@ public class Wallet {
TransactionInput txInput = psbt.getTransaction().getInputs().get(i); TransactionInput txInput = psbt.getTransaction().getInputs().get(i);
PSBTInput psbtInput = psbt.getPsbtInputs().get(i); PSBTInput psbtInput = psbt.getPsbtInputs().get(i);
if(psbtInput.isFinalized()) {
continue;
}
WalletNode signingNode = signingNodes.get(psbtInput); 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 //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.setFinalScriptSig(finalizedTxInput.getScriptSig());
psbtInput.setFinalScriptWitness(finalizedTxInput.getWitness()); psbtInput.setFinalScriptWitness(finalizedTxInput.getWitness());
psbtInput.clearFinalised(); psbtInput.clearPrivateFields();
} }
} }
} }