Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for scripts.witness*.input and fixes #911

Merged
merged 2 commits into from
Sep 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 59 additions & 5 deletions src/templates/witnessscripthash/input.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,63 @@
// {signature} {pubKey}
// <scriptSig> {serialized scriptPubKey script}

var p2sh = require('../scripthash/input')
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')

var p2ms = require('../multisig/')
var p2pk = require('../pubkey/')
var p2pkh = require('../pubkeyhash/')

function check (chunks, allowIncomplete) {
typeforce(types.Array, chunks)
if (chunks.length < 1) return false

var witnessScript = chunks[chunks.length - 1]
if (!Buffer.isBuffer(witnessScript)) return false

var witnessScriptChunks = bscript.decompile(witnessScript)

// is witnessScript a valid script?
if (witnessScriptChunks.length === 0) return false

var witnessRawScriptSig = bscript.compile(chunks.slice(0, -1))

// match types
if (p2pkh.input.check(witnessRawScriptSig) &&
p2pkh.output.check(witnessScriptChunks)) return true

if (p2ms.input.check(witnessRawScriptSig, allowIncomplete) &&
p2ms.output.check(witnessScriptChunks)) return true

if (p2pk.input.check(witnessRawScriptSig) &&
p2pk.output.check(witnessScriptChunks)) return true

return false
}
check.toJSON = function () { return 'witnessScriptHash input' }

function encodeStack (witnessData, witnessScript) {
typeforce({
witnessData: [types.Buffer],
witnessScript: types.Buffer
}, {
witnessData: witnessData,
witnessScript: witnessScript
})

return [].concat(witnessData, witnessScript)
}

function decodeStack (chunks) {
typeforce(check, chunks)
return {
witnessData: chunks.slice(0, -1),
witnessScript: chunks[chunks.length - 1]
}
}

module.exports = {
check: p2sh.check,
decodeStack: p2sh.decodeStack,
encodeStack: p2sh.encodeStack
check: check,
decodeStack: decodeStack,
encodeStack: encodeStack
}
22 changes: 18 additions & 4 deletions test/fixtures/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,30 @@
{
"type": "witnesspubkeyhash",
"pubKey": "02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1",
"signature": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
"output": "OP_0 aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5",
"outputHex": "0014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5"
"outputHex": "0014aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5",
"inputStack": [
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
"02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1"
]
},
{
"type": "witnessscripthash",
"witnessScriptPubKey": "OP_2 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a OP_2 OP_CHECKMULTISIG",
"witnessScriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501",
"witnessScript": "OP_2 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 0395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a OP_2 OP_CHECKMULTISIG",
"witnessData": [
"",
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
],
"output": "OP_0 32447752937d355ca2defddcd1f6b4fc53d182f8901cebbcff42f5e381bf0b80",
"outputHex": "002032447752937d355ca2defddcd1f6b4fc53d182f8901cebbcff42f5e381bf0b80",
"witness": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae"
"inputStack": [
"",
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501",
"522102359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1210395a9d84d47d524548f79f435758c01faec5da2b7e551d3b8c995b7e06326ae4a52ae"
]
},
{
"type": "nulldata",
Expand Down
55 changes: 53 additions & 2 deletions test/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ var ops = require('bitcoin-ops')

var fixtures = require('./fixtures/templates.json')

function fromHex (x) { return Buffer.from(x, 'hex') }
function toHex (x) { return x.toString('hex') }

describe('script-templates', function () {
describe('classifyInput', function () {
fixtures.valid.forEach(function (f) {
Expand Down Expand Up @@ -296,8 +299,8 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'scripthash') return

var redeemScript = bscript.fromASM(f.redeemScript)
var redeemScriptSig = bscript.fromASM(f.redeemScriptSig)
var redeemScript = bscript.fromASM(f.redeemScript)
var input = btemplates.scriptHash.input.encode(redeemScriptSig, redeemScript)

it('encodes to ' + f.output, function () {
Expand Down Expand Up @@ -347,6 +350,31 @@ describe('script-templates', function () {
})
})

describe('witnessPubKeyHash.input', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'pubkeyhash' && f.type !== 'witnesspubkeyhash') return
if (!f.inputStack) return

var pubKey = Buffer.from(f.pubKey, 'hex')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use fromHex here?

Copy link
Contributor Author

@dcousens dcousens Sep 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@junderw I was only using fromHex in the .map(function (x) { return Buffer.from(x, 'hex') }) case, if we had ES6 lambdas, I wouldn't have bothered.

var signature = Buffer.from(f.signature, 'hex')

it('encodes to ' + f.input, function () {
var inputStack = btemplates.witnessPubKeyHash.input.encodeStack(signature, pubKey)

assert.deepEqual(inputStack.map(toHex), f.inputStack)
})

it('decodes to original arguments', function () {
var fInputStack = f.inputStack.map(fromHex)

assert.deepEqual(btemplates.witnessPubKeyHash.input.decodeStack(fInputStack), {
signature: signature,
pubKey: pubKey
})
})
})
})

describe('witnessPubKeyHash.output', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'witnesspubkeyhash') return
Expand Down Expand Up @@ -377,12 +405,35 @@ describe('script-templates', function () {
})
})

describe('witnessScriptHash.input', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'witnessscripthash') return
if (!f.inputStack || !f.witnessData) return

var witnessData = f.witnessData.map(fromHex)
var witnessScript = bscript.fromASM(f.witnessScript || f.redeemScript)

it('encodes to ' + f.input, function () {
var inputStack = btemplates.witnessScriptHash.input.encodeStack(witnessData, witnessScript)

assert.deepEqual(inputStack.map(toHex), f.inputStack)
})

it('decodes to original arguments', function () {
var result = btemplates.witnessScriptHash.input.decodeStack(f.inputStack.map(fromHex))

assert.deepEqual(result.witnessData.map(toHex), f.witnessData)
assert.strictEqual(bscript.toASM(result.witnessScript), f.witnessScript)
})
})
})

describe('witnessScriptHash.output', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'witnessscripthash') return
if (!f.output) return

var witnessScriptPubKey = bscript.fromASM(f.witnessScriptPubKey)
var witnessScriptPubKey = bscript.fromASM(f.witnessScript)
var scriptHash = bcrypto.hash256(witnessScriptPubKey)
var output = btemplates.witnessScriptHash.output.encode(scriptHash)

Expand Down