Make errors clearer and increase coverage

This commit is contained in:
junderw 2019-06-17 13:34:20 +09:00
parent 071e201a75
commit 1b39d9caf4
No known key found for this signature in database
GPG key ID: B256185D3A971908
4 changed files with 256 additions and 15 deletions

View file

@ -734,13 +734,20 @@ function checkSignArgs(inputs, signParams) {
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
);
}
typeforce(
typeforce.tuple(
typeforce.Number,
typeforce.maybe(typeforce.Number),
types.Signer,
),
[signParams.vin, signParams.hashType, signParams.keyPair],
tfMessage(
typeforce.Number,
signParams.vin,
`sign must include vin parameter as Number (input index)`,
);
tfMessage(
types.Signer,
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 posType = signParams.prevOutScriptType;

View file

@ -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)",
"exception": "Transaction needs outputs",

View file

@ -104,7 +104,7 @@ function construct (f, dontSign, useOldSignArgs) {
// TODO: Remove loop in v6
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
let consoleWarn;
if (useOldSignArgs) {
@ -426,6 +426,49 @@ for (const useOldSignArgs of [ false, true ]) {
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 => {
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
const txb = construct(f, true)

View file

@ -958,13 +958,20 @@ function checkSignArgs(inputs: TxbInput[], signParams: TxbSignArg): void {
`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
);
}
typeforce(
typeforce.tuple(
typeforce.Number,
typeforce.maybe(typeforce.Number),
types.Signer,
),
[signParams.vin, signParams.hashType, signParams.keyPair],
tfMessage(
typeforce.Number,
signParams.vin,
`sign must include vin parameter as Number (input index)`,
);
tfMessage(
types.Signer,
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 posType = signParams.prevOutScriptType;