fuzz: update fuzzer to use bitcoinconsensus.

This commit is contained in:
Christopher Jeffrey 2017-08-24 22:23:53 -07:00
parent af132c8818
commit f1ac30a6c1
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -1,5 +1,6 @@
'use strict';
const assert = require('assert');
const util = require('../lib/utils/util');
const Script = require('../lib/script/script');
const Stack = require('../lib/script/stack');
@ -11,9 +12,62 @@ const TX = require('../lib/primitives/tx');
const random = require('../lib/crypto/random');
const flags = Script.flags;
let consensus = null;
try {
consensus = require('nodeconsensus');
} catch (e) {
;
}
if (consensus)
util.log('Running against bitcoinconsensus...');
const MANDATORY = flags.MANDATORY_VERIFY_FLAGS | flags.VERIFY_WITNESS;
const STANDARD = flags.STANDARD_VERIFY_FLAGS;
function verifyConsensus(tx, index, output, value, flags) {
if (!consensus)
return 'OK';
return consensus.verify(tx.toRaw(), index, output.toRaw(), value, flags);
}
function assertConsensus(tx, output, flags, code) {
if (!consensus)
return code;
const err = verifyConsensus(tx, 0, output, 0, flags);
if (err !== code) {
util.log('bitcoinconsensus mismatch!');
util.log(`${err} (bitcoin core) !== ${code} (bcoin)`);
util.log(tx);
util.log(output);
util.log(flags);
util.log('TX: %s', tx.toRaw().toString('hex'));
util.log('Output Script: %s', output.toRaw().toString('hex'));
}
}
function randomSignature() {
const r = secp256k1.generatePrivateKey();
const s = secp256k1.generatePrivateKey();
return secp256k1.toDER(Buffer.concat([r, s]));
}
function randomKey() {
const x = secp256k1.generatePrivateKey();
const y = secp256k1.generatePrivateKey();
if (util.random(0, 2) === 0) {
const p = Buffer.from([2 | (y[y.length - 1] & 1)]);
return Buffer.concat([p, x]);
}
const p = Buffer.from([4]);
return Buffer.concat([p, x, y]);
}
function randomOutpoint() {
const hash = random.randomBytes(32).toString('hex');
return new Outpoint(hash, util.random(0, 0xffffffff));
@ -43,7 +97,7 @@ function randomTX() {
tx.inputs.push(randomInput());
for (let i = 0; i < outputs; i++)
tx.inputs.push(randomOutput());
tx.outputs.push(randomOutput());
if (util.random(0, 5) === 0)
tx.locktime = util.random(0, 0xffffffff);
@ -333,6 +387,11 @@ function fuzzVerify(flags) {
const witness = randomWitness();
const output = randomOutputScript();
tx.inputs[0].script = input;
tx.inputs[0].witness = witness;
tx.refresh();
try {
Script.verify(
input,
@ -344,11 +403,15 @@ function fuzzVerify(flags) {
flags
);
} catch (e) {
if (e.type === 'ScriptError')
if (e.type === 'ScriptError') {
assertConsensus(tx, output, flags, e.code);
continue;
}
throw e;
}
assertConsensus(tx, output, flags, 'OK');
if (isPushOnly(output))
continue;
@ -379,6 +442,12 @@ function fuzzLess(flags) {
tx = randomTX();
const ctx = randomContext();
const input = tx.inputs[0];
input.script = ctx.input;
input.witness = ctx.witness;
tx.refresh();
try {
Script.verify(
@ -391,11 +460,15 @@ function fuzzLess(flags) {
flags
);
} catch (e) {
if (e.type === 'ScriptError')
if (e.type === 'ScriptError') {
assertConsensus(tx, ctx.output, flags, e.code);
continue;
}
throw e;
}
assertConsensus(tx, ctx.output, flags, 'OK');
util.log('Produced valid scripts:');
util.log('Input:');
@ -439,4 +512,7 @@ function main() {
}
}
randomKey;
randomSignature;
main();