Merge pull request #1439 from bitcoinjs/checkFinalizedSighash

Check signatures for finalized inputs too
This commit is contained in:
Jonathan Underwood 2019-07-23 17:52:41 +09:00 committed by GitHub
commit af8f41a1e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 4 deletions

View file

@ -626,8 +626,14 @@ function checkFees(psbt, cache, opts) {
function checkInputsForPartialSig(inputs, action) { function checkInputsForPartialSig(inputs, action) {
inputs.forEach(input => { inputs.forEach(input => {
let throws = false; let throws = false;
if ((input.partialSig || []).length === 0) return; let pSigs = [];
input.partialSig.forEach(pSig => { if ((input.partialSig || []).length === 0) {
if (!input.finalScriptSig && !input.finalScriptWitness) return;
pSigs = getPsigsFromInputFinalScripts(input);
} else {
pSigs = input.partialSig;
}
pSigs.forEach(pSig => {
const { hashType } = bscript.signature.decode(pSig.signature); const { hashType } = bscript.signature.decode(pSig.signature);
const whitelist = []; const whitelist = [];
const isAnyoneCanPay = const isAnyoneCanPay =
@ -899,6 +905,20 @@ function getPayment(script, scriptType, partialSig) {
} }
return payment; return payment;
} }
function getPsigsFromInputFinalScripts(input) {
const scriptItems = !input.finalScriptSig
? []
: bscript.decompile(input.finalScriptSig) || [];
const witnessItems = !input.finalScriptWitness
? []
: bscript.decompile(input.finalScriptWitness) || [];
return scriptItems
.concat(witnessItems)
.filter(item => {
return Buffer.isBuffer(item) && bscript.isCanonicalScriptSignature(item);
})
.map(sig => ({ signature: sig }));
}
function getScriptFromInput(inputIndex, input, cache) { function getScriptFromInput(inputIndex, input, cache) {
const unsignedTx = cache.__TX; const unsignedTx = cache.__TX;
const res = { const res = {

View file

@ -625,6 +625,9 @@ describe(`Psbt`, () => {
}, new RegExp('Can not modify transaction, signatures exist.')) }, new RegExp('Can not modify transaction, signatures exist.'))
psbt.validateSignaturesOfInput(0) psbt.validateSignaturesOfInput(0)
psbt.finalizeAllInputs() psbt.finalizeAllInputs()
assert.throws(() => {
psbt.setVersion(3)
}, new RegExp('Can not modify transaction, signatures exist.'))
assert.strictEqual( assert.strictEqual(
psbt.extractTransaction().toHex(), psbt.extractTransaction().toHex(),
'02000000013ebc8203037dda39d482bf41ff3be955996c50d9d4f7cfc3d2097a694a7' + '02000000013ebc8203037dda39d482bf41ff3be955996c50d9d4f7cfc3d2097a694a7' +

View file

@ -795,8 +795,14 @@ function checkFees(psbt: Psbt, cache: PsbtCache, opts: PsbtOpts): void {
function checkInputsForPartialSig(inputs: PsbtInput[], action: string): void { function checkInputsForPartialSig(inputs: PsbtInput[], action: string): void {
inputs.forEach(input => { inputs.forEach(input => {
let throws = false; let throws = false;
if ((input.partialSig || []).length === 0) return; let pSigs: PartialSig[] = [];
input.partialSig!.forEach(pSig => { if ((input.partialSig || []).length === 0) {
if (!input.finalScriptSig && !input.finalScriptWitness) return;
pSigs = getPsigsFromInputFinalScripts(input);
} else {
pSigs = input.partialSig!;
}
pSigs.forEach(pSig => {
const { hashType } = bscript.signature.decode(pSig.signature); const { hashType } = bscript.signature.decode(pSig.signature);
const whitelist: string[] = []; const whitelist: string[] = [];
const isAnyoneCanPay = hashType & Transaction.SIGHASH_ANYONECANPAY; const isAnyoneCanPay = hashType & Transaction.SIGHASH_ANYONECANPAY;
@ -1121,6 +1127,21 @@ function getPayment(
return payment!; return payment!;
} }
function getPsigsFromInputFinalScripts(input: PsbtInput): PartialSig[] {
const scriptItems = !input.finalScriptSig
? []
: bscript.decompile(input.finalScriptSig) || [];
const witnessItems = !input.finalScriptWitness
? []
: bscript.decompile(input.finalScriptWitness) || [];
return scriptItems
.concat(witnessItems)
.filter(item => {
return Buffer.isBuffer(item) && bscript.isCanonicalScriptSignature(item);
})
.map(sig => ({ signature: sig })) as PartialSig[];
}
interface GetScriptReturn { interface GetScriptReturn {
script: Buffer | null; script: Buffer | null;
isSegwit: boolean; isSegwit: boolean;