Add tests for bip69 from bitcoinjs

This commit is contained in:
Esteban Ordano 2015-09-30 10:07:02 -07:00
parent fb65145ba7
commit 026f878e51
5 changed files with 318 additions and 19 deletions

View File

@ -912,28 +912,19 @@ Transaction.prototype.removeOutput = function(index) {
* @return {Transaction} this
*/
Transaction.prototype.sort = function() {
this.sortOutputs(function(outputs) {
var copy = Array.prototype.concat.apply([], outputs);
copy.sort(function compare(first, second) {
if (first.satoshis < second.satoshis) {
return -1;
} else if (first.satoshis === second.satoshis) {
return Buffer.compare(first.script.toBuffer(), second.script.toBuffer());
} else {
return 1;
}
});
return copy;
});
this.sortInputs(function(inputs) {
var copy = Array.prototype.concat.apply([], inputs);
copy.sort(function compare(first, second) {
var compareTx = Buffer.compare(first.script.toBuffer(), second.script.toBuffer());
if (compareTx === 0) {
return first.outputIndex < second.outputIndex ? -1 : 1;
} else {
return compareTx;
}
return BufferUtil.compare(first.prevTxId, second.prevTxId)
|| first.outputIndex - second.outputIndex;
});
return copy;
});
this.sortOutputs(function(outputs) {
var copy = Array.prototype.concat.apply([], outputs);
copy.sort(function compare(first, second) {
return first.satoshis - second.satoshis
|| BufferUtil.compare(first.script.toBuffer(), second.script.toBuffer());
});
return copy;
});

View File

@ -170,6 +170,49 @@ module.exports = {
hexToBuffer: function hexToBuffer(string) {
assert(js.isHexa(string));
return new buffer.Buffer(string, 'hex');
},
/**
* Browser shim for buffer compare
*
* MIT. Copyright by Feross Aboukhadijeh, and other contributors.
* Originally forked from an MIT-licensed module by Romain Beauxis.
* @see {https://github.com/feross/buffer/blob/bc33ea4618e6846148e35aee78dfc28d999bdd1c/index.js#L264}
*/
compare: function(a, b) {
if (Buffer.compare) {
return Buffer.compare(a, b);
} else {
if (a === b) {
return 0;
}
var x = a.length;
var y = b.length;
var i = 0;
var len = Math.min(x, y);
while (i < len) {
if (a[i] !== b[i]) {
break;
}
++i;
}
if (i !== len) {
x = a[i];
y = b[i];
}
if (x < y) {
return -1;
}
if (y < x) {
return 1;
}
return 0;
}
}
};

View File

@ -68,6 +68,7 @@
"bip21",
"bip32",
"bip37",
"bip39",
"bip70",
"multisig"
],

215
test/data/bip69.json Normal file
View File

@ -0,0 +1,215 @@
{
"inputs": [
{
"description": "Ordered by txId, descending (reverse-byte-order ascending)",
"inputs": [
{
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 0
},
{
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"vout": 0
},
{
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"vout": 0
},
{
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbff",
"vout": 0
},
{
"txId": "ffbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"vout": 0
}
],
"expected": [0, 2, 3, 1, 4]
},
{
"description": "Ordered by vout, ascending",
"inputs": [
{
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 1
},
{
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 2
},
{
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 0
}
],
"expected": [2, 0, 1]
},
{
"description": "Ordered by txId, then vout",
"inputs": [
{
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 99
},
{
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"vout": 99
},
{
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"vout": 0
},
{
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"vout": 0
}
],
"expected": [0, 3, 1, 2]
},
{
"description": "BIP69 test vector 1",
"inputs": [
{ "txId": "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57", "vout": 0 },
{ "txId": "26aa6e6d8b9e49bb0630aac301db6757c02e3619feb4ee0eea81eb1672947024", "vout": 1 },
{ "txId": "28e0fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2", "vout": 0 },
{ "txId": "381de9b9ae1a94d9c17f6a08ef9d341a5ce29e2e60c36a52d333ff6203e58d5d", "vout": 1 },
{ "txId": "3b8b2f8efceb60ba78ca8bba206a137f14cb5ea4035e761ee204302d46b98de2", "vout": 0 },
{ "txId": "402b2c02411720bf409eff60d05adad684f135838962823f3614cc657dd7bc0a", "vout": 1 },
{ "txId": "54ffff182965ed0957dba1239c27164ace5a73c9b62a660c74b7b7f15ff61e7a", "vout": 1 },
{ "txId": "643e5f4e66373a57251fb173151e838ccd27d279aca882997e005016bb53d5aa", "vout": 0 },
{ "txId": "6c1d56f31b2de4bfc6aaea28396b333102b1f600da9c6d6149e96ca43f1102b1", "vout": 1 },
{ "txId": "7a1de137cbafb5c70405455c49c5104ca3057a1f1243e6563bb9245c9c88c191", "vout": 0 },
{ "txId": "7d037ceb2ee0dc03e82f17be7935d238b35d1deabf953a892a4507bfbeeb3ba4", "vout": 1 },
{ "txId": "a5e899dddb28776ea9ddac0a502316d53a4a3fca607c72f66c470e0412e34086", "vout": 0 },
{ "txId": "b4112b8f900a7ca0c8b0e7c4dfad35c6be5f6be46b3458974988e1cdb2fa61b8", "vout": 0 },
{ "txId": "bafd65e3c7f3f9fdfdc1ddb026131b278c3be1af90a4a6ffa78c4658f9ec0c85", "vout": 0 },
{ "txId": "de0411a1e97484a2804ff1dbde260ac19de841bebad1880c782941aca883b4e9", "vout": 1 },
{ "txId": "f0a130a84912d03c1d284974f563c5949ac13f8342b8112edff52971599e6a45", "vout": 0 },
{ "txId": "f320832a9d2e2452af63154bc687493484a0e7745ebd3aaf9ca19eb80834ad60", "vout": 0 }
],
"expected": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
},
{
"description": "BIP69 test vector 2",
"inputs": [
{ "txId": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", "vout": 0 },
{ "txId": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", "vout": 1 }
],
"expected": [0, 1]
}
],
"outputs": [
{
"description": "Ordered by Amount, ascending",
"outputs": [
{
"script": "00000000",
"value": 3000
},
{
"script": "00000000",
"value": 2000
},
{
"script": "00000000",
"value": 1000
}
],
"expected": [2, 1, 0]
},
{
"description": "Ordered by Script, ascending",
"outputs": [
{
"script": "00000000",
"value": 1000
},
{
"script": "22222222",
"value": 1000
},
{
"script": "11111111",
"value": 1000
}
],
"expected": [0, 2, 1]
},
{
"description": "Ordered by Amount, then Script",
"outputs": [
{
"script": "11111111",
"value": 1000
},
{
"script": "11111111",
"value": 2000
},
{
"script": "00000000",
"value": 3000
},
{
"script": "00000000",
"value": 2000
}
],
"expected": [0, 3, 1, 2]
},
{
"description": "Sorting is irrelevant for equivalent outputs",
"outputs": [
{
"script": "00000000",
"value": 2000
},
{
"script": "11111111",
"value": 2000
},
{
"script": "00000000",
"value": 2000
},
{
"script": "11111111",
"value": 3000
},
{
"script": "22222222",
"value": 3000
}
],
"expected": [0, 2, 1, 3, 4]
},
{
"description": "BIP69 test vector 1",
"outputs": [
{
"script": "76a9144a5fba237213a062f6f57978f796390bdcf8d01588ac",
"value": 400057456
},
{
"script": "76a9145be32612930b8323add2212a4ec03c1562084f8488ac",
"value": 40000000000
}
],
"expected": [0, 1]
},
{
"description": "BIP69 test vector 2",
"outputs": [
{
"script": "41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac",
"value": 100000000
},
{
"script": "41044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac",
"value": 2400000000
}
],
"expected": [0, 1]
}
]
}

View File

@ -10,6 +10,8 @@ var sinon = require('sinon');
var bitcore = require('../..');
var BN = bitcore.crypto.BN;
var Transaction = bitcore.Transaction;
var Input = bitcore.Transaction.Input;
var Output = bitcore.Transaction.Output;
var PrivateKey = bitcore.PrivateKey;
var Script = bitcore.Script;
var Address = bitcore.Address;
@ -977,9 +979,56 @@ describe('Transaction', function() {
tx.outputs[1].script.toString().should.equal('OP_0');
tx.outputs[2].script.toString().should.equal('0x01');
});
describe('bitcoinjs fixtures', function() {
var fixture = require('../data/bip69.json');
// returns index-based order of sorted against original
var getIndexOrder = function(original, sorted) {
return sorted.map(function (value) {
return original.indexOf(value);
});
};
fixture.inputs.forEach(function(inputSet) {
it(inputSet.description, function() {
var tx = new Transaction();
inputSet.inputs = inputSet.inputs.map(function(input) {
var input = new Input({
prevTxId: input.txId,
outputIndex: input.vout,
script: new Script(),
output: new Output({ script: new Script(), satoshis: 0 })
});
input.clearSignatures = function () {};
return input;
});
tx.inputs = inputSet.inputs;
tx.sort();
getIndexOrder(inputSet.inputs, tx.inputs).should.deep.equal(inputSet.expected);
});
});
fixture.outputs.forEach(function(outputSet) {
it(outputSet.description, function() {
var tx = new Transaction();
outputSet.outputs = outputSet.outputs.map(function(output) {
return new Output({
script: new Script(output.script),
satoshis: output.value
});
});
tx.outputs = outputSet.outputs;
tx.sort();
getIndexOrder(outputSet.outputs, tx.outputs).should.deep.equal(outputSet.expected);
});
});
});
});
});
var tx_empty_hex = '01000000000000000000';
/* jshint maxlen: 1000 */