Make errors clearer and increase coverage
This commit is contained in:
parent
071e201a75
commit
1b39d9caf4
4 changed files with 256 additions and 15 deletions
|
@ -734,13 +734,20 @@ function checkSignArgs(inputs, signParams) {
|
||||||
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
|
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
typeforce(
|
tfMessage(
|
||||||
typeforce.tuple(
|
|
||||||
typeforce.Number,
|
typeforce.Number,
|
||||||
typeforce.maybe(typeforce.Number),
|
signParams.vin,
|
||||||
|
`sign must include vin parameter as Number (input index)`,
|
||||||
|
);
|
||||||
|
tfMessage(
|
||||||
types.Signer,
|
types.Signer,
|
||||||
),
|
signParams.keyPair,
|
||||||
[signParams.vin, signParams.hashType, signParams.keyPair],
|
`sign must include keyPair parameter as Signer interface`,
|
||||||
|
);
|
||||||
|
tfMessage(
|
||||||
|
typeforce.maybe(typeforce.Number),
|
||||||
|
signParams.hashType,
|
||||||
|
`sign hashType parameter must be a number`,
|
||||||
);
|
);
|
||||||
const prevOutType = (inputs[signParams.vin] || []).prevOutType;
|
const prevOutType = (inputs[signParams.vin] || []).prevOutType;
|
||||||
const posType = signParams.prevOutScriptType;
|
const posType = signParams.prevOutScriptType;
|
||||||
|
|
184
test/fixtures/transaction_builder.json
vendored
184
test/fixtures/transaction_builder.json
vendored
|
@ -2470,6 +2470,190 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2pk: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2pk",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2wpkh: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2wpkh",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2ms: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2ms",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2sh-p2wpkh: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2sh-p2wpkh",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2sh-p2pk: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2sh-p2pk",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2wsh-p2pk: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2wsh-p2pk",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "input #0 is not of type p2sh-p2wsh-p2pk: nulldata",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "p2sh-p2wsh-p2pk",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "Unknown prevOutScriptType \"notvalidtype\"",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"vout": 0,
|
||||||
|
"prevTxScript": "OP_RETURN deadbeef",
|
||||||
|
"signs": [
|
||||||
|
{
|
||||||
|
"prevOutScriptType": "notvalidtype",
|
||||||
|
"keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
|
||||||
|
"throws": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"script": "OP_RETURN deadbeef",
|
||||||
|
"value": 1000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Transaction w/ no outputs (but 1 SIGHASH_NONE)",
|
"description": "Transaction w/ no outputs (but 1 SIGHASH_NONE)",
|
||||||
"exception": "Transaction needs outputs",
|
"exception": "Transaction needs outputs",
|
||||||
|
|
|
@ -104,7 +104,7 @@ function construct (f, dontSign, useOldSignArgs) {
|
||||||
|
|
||||||
// TODO: Remove loop in v6
|
// TODO: Remove loop in v6
|
||||||
for (const useOldSignArgs of [ false, true ]) {
|
for (const useOldSignArgs of [ false, true ]) {
|
||||||
// Search for "// TODO: Remove me in v6"
|
// Search for "useOldSignArgs"
|
||||||
// to find the second part of this console.warn replace
|
// to find the second part of this console.warn replace
|
||||||
let consoleWarn;
|
let consoleWarn;
|
||||||
if (useOldSignArgs) {
|
if (useOldSignArgs) {
|
||||||
|
@ -426,6 +426,49 @@ for (const useOldSignArgs of [ false, true ]) {
|
||||||
assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a473044022012a601efa8756ebe83e9ac7a7db061c3147e3b49d8be67685799fe51a4c8c62f02204d568d301d5ce14af390d566d4fd50e7b8ee48e71ec67786c029e721194dae3601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
|
assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a473044022012a601efa8756ebe83e9ac7a7db061c3147e3b49d8be67685799fe51a4c8c62f02204d568d301d5ce14af390d566d4fd50e7b8ee48e71ec67786c029e721194dae3601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('fails when missing required arguments', () => {
|
||||||
|
let txb = new TransactionBuilder()
|
||||||
|
txb.setVersion(1)
|
||||||
|
txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
|
||||||
|
txb.addOutput('1111111111111111111114oLvT2', 100000)
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign()
|
||||||
|
}, /TransactionBuilder sign first arg must be TxbSignArg or number/)
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign({
|
||||||
|
prevOutScriptType: 'p2pkh',
|
||||||
|
vin: 1,
|
||||||
|
keyPair,
|
||||||
|
})
|
||||||
|
}, /No input at index: 1/)
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign({
|
||||||
|
prevOutScriptType: 'p2pkh',
|
||||||
|
keyPair,
|
||||||
|
})
|
||||||
|
}, /sign must include vin parameter as Number \(input index\)/)
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign({
|
||||||
|
prevOutScriptType: 'p2pkh',
|
||||||
|
vin: 0,
|
||||||
|
keyPair: {},
|
||||||
|
})
|
||||||
|
}, /sign must include keyPair parameter as Signer interface/)
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign({
|
||||||
|
prevOutScriptType: 'p2pkh',
|
||||||
|
vin: 0,
|
||||||
|
keyPair,
|
||||||
|
hashType: 'string',
|
||||||
|
})
|
||||||
|
}, /sign hashType parameter must be a number/)
|
||||||
|
if (useOldSignArgs) {
|
||||||
|
assert.throws(() => {
|
||||||
|
txb.sign(0)
|
||||||
|
}, /sign requires keypair/)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
fixtures.invalid.sign.forEach(f => {
|
fixtures.invalid.sign.forEach(f => {
|
||||||
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
|
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
|
||||||
const txb = construct(f, true)
|
const txb = construct(f, true)
|
||||||
|
|
|
@ -958,13 +958,20 @@ function checkSignArgs(inputs: TxbInput[], signParams: TxbSignArg): void {
|
||||||
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
|
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
typeforce(
|
tfMessage(
|
||||||
typeforce.tuple(
|
|
||||||
typeforce.Number,
|
typeforce.Number,
|
||||||
typeforce.maybe(typeforce.Number),
|
signParams.vin,
|
||||||
|
`sign must include vin parameter as Number (input index)`,
|
||||||
|
);
|
||||||
|
tfMessage(
|
||||||
types.Signer,
|
types.Signer,
|
||||||
),
|
signParams.keyPair,
|
||||||
[signParams.vin, signParams.hashType, signParams.keyPair],
|
`sign must include keyPair parameter as Signer interface`,
|
||||||
|
);
|
||||||
|
tfMessage(
|
||||||
|
typeforce.maybe(typeforce.Number),
|
||||||
|
signParams.hashType,
|
||||||
|
`sign hashType parameter must be a number`,
|
||||||
);
|
);
|
||||||
const prevOutType = (inputs[signParams.vin] || []).prevOutType;
|
const prevOutType = (inputs[signParams.vin] || []).prevOutType;
|
||||||
const posType = signParams.prevOutScriptType;
|
const posType = signParams.prevOutScriptType;
|
||||||
|
|
Loading…
Add table
Reference in a new issue