Merge pull request #1039 from bitcoinjs/maybedec

decompile should return Maybe chunks
This commit is contained in:
Daniel Cousens 2018-05-22 18:57:47 +10:00 committed by GitHub
commit 97252b2872
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 12 deletions

View file

@ -98,11 +98,11 @@ function decompile (buffer) {
var d = pushdata.decode(buffer, i) var d = pushdata.decode(buffer, i)
// did reading a pushDataInt fail? empty script // did reading a pushDataInt fail? empty script
if (d === null) return [] if (d === null) return null
i += d.size i += d.size
// attempt to read too much data? empty script // attempt to read too much data? empty script
if (i + d.number > buffer.length) return [] if (i + d.number > buffer.length) return null
var data = buffer.slice(i, i + d.number) var data = buffer.slice(i, i + d.number)
i += d.number i += d.number

View file

@ -28,6 +28,8 @@ function classifyOutput (script) {
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (multisig.output.check(chunks)) return types.MULTISIG if (multisig.output.check(chunks)) return types.MULTISIG
if (pubKey.output.check(chunks)) return types.P2PK if (pubKey.output.check(chunks)) return types.P2PK
if (witnessCommitment.output.check(chunks)) return types.WITNESS_COMMITMENT if (witnessCommitment.output.check(chunks)) return types.WITNESS_COMMITMENT
@ -39,6 +41,7 @@ function classifyOutput (script) {
function classifyInput (script, allowIncomplete) { function classifyInput (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (pubKeyHash.input.check(chunks)) return types.P2PKH if (pubKeyHash.input.check(chunks)) return types.P2PKH
if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH
@ -51,6 +54,7 @@ function classifyInput (script, allowIncomplete) {
function classifyWitness (script, allowIncomplete) { function classifyWitness (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use // XXX: optimization, below functions .decompile before use
var chunks = decompile(script) var chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH
if (witnessScriptHash.input.check(chunks, allowIncomplete)) return types.P2WSH if (witnessScriptHash.input.check(chunks, allowIncomplete)) return types.P2WSH

View file

@ -21,7 +21,7 @@ function check (script, allowIncomplete) {
var redeemScriptChunks = bscript.decompile(lastChunk) var redeemScriptChunks = bscript.decompile(lastChunk)
// is redeemScript a valid script? // is redeemScript a valid script?
if (redeemScriptChunks.length === 0) return false if (!redeemScriptChunks) return false
// is redeemScriptSig push only? // is redeemScriptSig push only?
if (!bscript.isPushOnly(scriptSigChunks)) return false if (!bscript.isPushOnly(scriptSigChunks)) return false

View file

@ -71,7 +71,7 @@ function expandInput (scriptSig, witnessStack) {
var witnessProgram var witnessProgram
var chunks var chunks
var scriptSigChunks = bscript.decompile(scriptSig) var scriptSigChunks = bscript.decompile(scriptSig) || []
var sigType = btemplates.classifyInput(scriptSigChunks, true) var sigType = btemplates.classifyInput(scriptSigChunks, true)
if (sigType === scriptTypes.P2SH) { if (sigType === scriptTypes.P2SH) {
p2sh = true p2sh = true
@ -209,7 +209,7 @@ function fixMultisigOrder (input, transaction, vin) {
function expandOutput (script, scriptType, ourPubKey) { function expandOutput (script, scriptType, ourPubKey) {
typeforce(types.Buffer, script) typeforce(types.Buffer, script)
var scriptChunks = bscript.decompile(script) var scriptChunks = bscript.decompile(script) || []
if (!scriptType) { if (!scriptType) {
scriptType = btemplates.classifyOutput(script) scriptType = btemplates.classifyOutput(script)
} }
@ -257,8 +257,9 @@ function checkP2SHInput (input, redeemScriptHash) {
if (input.prevOutType) { if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH') if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH')
var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1] var chunks = bscript.decompile(input.prevOutScript)
if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(redeemScript)') if (!chunks) throw new Error('Invalid prevOutScript')
if (!chunks[1].equals(redeemScriptHash)) throw new Error('Inconsistent hash160(redeemScript)')
} }
} }
@ -266,8 +267,9 @@ function checkP2WSHInput (input, witnessScriptHash) {
if (input.prevOutType) { if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2WSH) throw new Error('PrevOutScript must be P2WSH') if (input.prevOutType !== scriptTypes.P2WSH) throw new Error('PrevOutScript must be P2WSH')
var scriptHash = bscript.decompile(input.prevOutScript)[1] var chunks = bscript.decompile(input.prevOutScript)
if (!scriptHash.equals(witnessScriptHash)) throw new Error('Inconsistent sha256(witnessScript)') if (!chunks) throw new Error('Invalid witnessScript')
if (!chunks[1].equals(witnessScriptHash)) throw new Error('Inconsistent sha256(witnessScript)')
} }
} }

View file

@ -1917,10 +1917,16 @@
} }
] ]
}, },
{
"description": "Transaction w/ invalid scripts",
"exception": "Invalid script",
"incomplete": true,
"txHex": "010000000100000000171a0000e028f2000000000050178500000000000d0000000e000000000000002009f691b2263260e71f363d1db51ff3100d285956a40cc0e4f8c8c2c4a80559b1ffffffff0110270000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
},
{ {
"description": "Complete transaction w/ non-standard inputs", "description": "Complete transaction w/ non-standard inputs",
"exception": "nonstandard not supported", "exception": "nonstandard not supported",
"txHex": "010000000100000000171a0000e028f2000000000050178500000000000d0000000e000000000000002009f691b2263260e71f363d1db51ff3100d285956a40cc0e4f8c8c2c4a80559b1ffffffff0110270000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "010000000100000000171a0000e028f2000000000050178500000000000d0000000e00000000000000201ff691b2263260e71f363d1db51ff3100d285956a40cc0e4f8c8c2c4a80559b1ffffffff0110270000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
} }
], ],
"sign": [ "sign": [

View file

@ -124,10 +124,10 @@ describe('script', function () {
}) })
fixtures.invalid.decompile.forEach(function (f) { fixtures.invalid.decompile.forEach(function (f) {
it('decompiles ' + f.script + ' to [] because of "' + f.description + '"', function () { it('fails to decompile ' + f.script + ', because "' + f.description + '"', function () {
var chunks = bscript.decompile(Buffer.from(f.script, 'hex')) var chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
assert.strictEqual(chunks.length, 0) assert.strictEqual(chunks, null)
}) })
}) })
}) })