mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-25 07:27:18 +01:00
WalletService: adapt to segwit wallet
This commit is contained in:
parent
25515710ab
commit
d8b755794e
1 changed files with 33 additions and 12 deletions
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package bisq.core.btc.wallet;
|
package bisq.core.btc.wallet;
|
||||||
|
|
||||||
|
import bisq.core.btc.exceptions.SigningException;
|
||||||
import bisq.core.btc.exceptions.TransactionVerificationException;
|
import bisq.core.btc.exceptions.TransactionVerificationException;
|
||||||
import bisq.core.btc.exceptions.WalletException;
|
import bisq.core.btc.exceptions.WalletException;
|
||||||
import bisq.core.btc.listeners.AddressConfidenceListener;
|
import bisq.core.btc.listeners.AddressConfidenceListener;
|
||||||
|
@ -37,12 +38,14 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.core.Context;
|
import org.bitcoinj.core.Context;
|
||||||
import org.bitcoinj.core.ECKey;
|
import org.bitcoinj.core.ECKey;
|
||||||
import org.bitcoinj.core.InsufficientMoneyException;
|
import org.bitcoinj.core.InsufficientMoneyException;
|
||||||
|
import org.bitcoinj.core.LegacyAddress;
|
||||||
import org.bitcoinj.core.NetworkParameters;
|
import org.bitcoinj.core.NetworkParameters;
|
||||||
import org.bitcoinj.core.Sha256Hash;
|
import org.bitcoinj.core.Sha256Hash;
|
||||||
import org.bitcoinj.core.Transaction;
|
import org.bitcoinj.core.Transaction;
|
||||||
import org.bitcoinj.core.TransactionConfidence;
|
import org.bitcoinj.core.TransactionConfidence;
|
||||||
import org.bitcoinj.core.TransactionInput;
|
import org.bitcoinj.core.TransactionInput;
|
||||||
import org.bitcoinj.core.TransactionOutput;
|
import org.bitcoinj.core.TransactionOutput;
|
||||||
|
import org.bitcoinj.core.TransactionWitness;
|
||||||
import org.bitcoinj.core.VerificationException;
|
import org.bitcoinj.core.VerificationException;
|
||||||
import org.bitcoinj.core.listeners.NewBestBlockListener;
|
import org.bitcoinj.core.listeners.NewBestBlockListener;
|
||||||
import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
|
import org.bitcoinj.core.listeners.TransactionConfidenceEventListener;
|
||||||
|
@ -51,6 +54,7 @@ import org.bitcoinj.crypto.KeyCrypter;
|
||||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||||
import org.bitcoinj.crypto.TransactionSignature;
|
import org.bitcoinj.crypto.TransactionSignature;
|
||||||
import org.bitcoinj.script.Script;
|
import org.bitcoinj.script.Script;
|
||||||
|
import org.bitcoinj.script.ScriptBuilder;
|
||||||
import org.bitcoinj.script.ScriptChunk;
|
import org.bitcoinj.script.ScriptChunk;
|
||||||
import org.bitcoinj.script.ScriptException;
|
import org.bitcoinj.script.ScriptException;
|
||||||
import org.bitcoinj.script.ScriptPattern;
|
import org.bitcoinj.script.ScriptPattern;
|
||||||
|
@ -241,7 +245,7 @@ public abstract class WalletService {
|
||||||
int inputIndex) throws TransactionVerificationException {
|
int inputIndex) throws TransactionVerificationException {
|
||||||
try {
|
try {
|
||||||
checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null");
|
checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null");
|
||||||
input.getScriptSig().correctlySpends(transaction, inputIndex, input.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
input.getScriptSig().correctlySpends(transaction, inputIndex, input.getWitness(), input.getValue(), input.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
log.error(t.getMessage());
|
log.error(t.getMessage());
|
||||||
|
@ -265,7 +269,7 @@ public abstract class WalletService {
|
||||||
// We assume if it's already signed, it's hopefully got a SIGHASH type that will not invalidate when
|
// We assume if it's already signed, it's hopefully got a SIGHASH type that will not invalidate when
|
||||||
// we sign missing pieces (to check this would require either assuming any signatures are signing
|
// we sign missing pieces (to check this would require either assuming any signatures are signing
|
||||||
// standard output types or a way to get processed signatures out of script execution)
|
// standard output types or a way to get processed signatures out of script execution)
|
||||||
txIn.getScriptSig().correctlySpends(tx, index, txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
txIn.getScriptSig().correctlySpends(tx, index, txIn.getWitness(), txIn.getValue(), txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
||||||
log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
|
log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
|
||||||
return;
|
return;
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
|
@ -288,7 +292,7 @@ public abstract class WalletService {
|
||||||
// We assume if it's already signed, it's hopefully got a SIGHASH type that will not invalidate when
|
// We assume if it's already signed, it's hopefully got a SIGHASH type that will not invalidate when
|
||||||
// we sign missing pieces (to check this would require either assuming any signatures are signing
|
// we sign missing pieces (to check this would require either assuming any signatures are signing
|
||||||
// standard output types or a way to get processed signatures out of script execution)
|
// standard output types or a way to get processed signatures out of script execution)
|
||||||
txIn.getScriptSig().correctlySpends(tx, index, txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
txIn.getScriptSig().correctlySpends(tx, index, txIn.getWitness(), txIn.getValue(), txIn.getConnectedOutput().getScriptPubKey(), Script.ALL_VERIFY_FLAGS);
|
||||||
log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
|
log.warn("Input {} already correctly spends output, assuming SIGHASH type used will be safe and skipping signing.", index);
|
||||||
return;
|
return;
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
|
@ -312,14 +316,31 @@ public abstract class WalletService {
|
||||||
|
|
||||||
Script inputScript = txIn.getScriptSig();
|
Script inputScript = txIn.getScriptSig();
|
||||||
byte[] script = redeemData.redeemScript.getProgram();
|
byte[] script = redeemData.redeemScript.getProgram();
|
||||||
try {
|
|
||||||
TransactionSignature signature = partialTx.calculateSignature(index, key, script, Transaction.SigHash.ALL, false);
|
if (ScriptPattern.isP2PK(scriptPubKey) || ScriptPattern.isP2PKH(scriptPubKey)) {
|
||||||
inputScript = scriptPubKey.getScriptSigWithSignature(inputScript, signature.encodeToBitcoin(), 0);
|
try {
|
||||||
txIn.setScriptSig(inputScript);
|
TransactionSignature signature = partialTx.calculateSignature(index, key, script, Transaction.SigHash.ALL, false);
|
||||||
} catch (ECKey.KeyIsEncryptedException e1) {
|
inputScript = scriptPubKey.getScriptSigWithSignature(inputScript, signature.encodeToBitcoin(), 0);
|
||||||
throw e1;
|
txIn.setScriptSig(inputScript);
|
||||||
} catch (ECKey.MissingPrivateKeyException e1) {
|
} catch (ECKey.KeyIsEncryptedException e1) {
|
||||||
log.warn("No private key in keypair for input {}", index);
|
throw e1;
|
||||||
|
} catch (ECKey.MissingPrivateKeyException e1) {
|
||||||
|
log.warn("No private key in keypair for input {}", index);
|
||||||
|
}
|
||||||
|
} else if (ScriptPattern.isP2WPKH(scriptPubKey)) {
|
||||||
|
// TODO: Consider using this alternative way to build the scriptCode (taken from bitcoinj master)
|
||||||
|
// Script scriptCode = ScriptBuilder.createP2PKHOutputScript(key);
|
||||||
|
Script scriptCode = new ScriptBuilder().data(
|
||||||
|
ScriptBuilder.createOutputScript(LegacyAddress.fromKey(tx.getParams(), key)).getProgram())
|
||||||
|
.build();
|
||||||
|
Coin value = txIn.getValue();
|
||||||
|
TransactionSignature txSig = tx.calculateWitnessSignature(index, key, scriptCode, value,
|
||||||
|
Transaction.SigHash.ALL, false);
|
||||||
|
txIn.setScriptSig(ScriptBuilder.createEmpty());
|
||||||
|
txIn.setWitness(TransactionWitness.redeemP2WPKH(txSig, key));
|
||||||
|
} else {
|
||||||
|
// log.error("Unexpected script type.");
|
||||||
|
throw new RuntimeException("Unexpected script type.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("Missing connected output, assuming input {} is already signed.", index);
|
log.warn("Missing connected output, assuming input {} is already signed.", index);
|
||||||
|
@ -592,7 +613,7 @@ public abstract class WalletService {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public DeterministicKey findKeyFromPubKey(byte[] pubKey) {
|
public DeterministicKey findKeyFromPubKey(byte[] pubKey) {
|
||||||
return wallet.getActiveKeyChain().findKeyFromPubKey(pubKey);
|
return (DeterministicKey) wallet.findKeyFromPubKey(pubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEncrypted() {
|
public boolean isEncrypted() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue