Merge pull request #1205 from maraoz/fix/block-parser

Fix block parsing
This commit is contained in:
Manuel Aráoz 2015-04-29 20:37:37 -03:00
commit a11b916be7
10 changed files with 59 additions and 26 deletions

View File

@ -68,8 +68,8 @@ Block._fromJSON = function _fromJSON(data) {
*/
Block._fromObject = function _fromObject(data) {
var transactions = [];
data.transactions.forEach(function(data) {
transactions.push(Transaction().fromJSON(data));
data.transactions.forEach(function(tx) {
transactions.push(Transaction().fromJSON(tx));
});
var info = {
header: BlockHeader.fromObject(data.header),
@ -118,6 +118,7 @@ Block._fromBufferReader = function _fromBufferReader(br) {
* @returns {Block} - An instance of block
*/
Block.fromBufferReader = function fromBufferReader(br) {
$.checkArgument(br, 'br is required');
var info = Block._fromBufferReader(br);
return new Block(info);
};
@ -127,7 +128,7 @@ Block.fromBufferReader = function fromBufferReader(br) {
* @returns {Block} - An instance of block
*/
Block.fromBuffer = function fromBuffer(buf) {
return Block.fromBufferReader(BufferReader(buf));
return Block.fromBufferReader(new BufferReader(buf));
};
/**

View File

@ -9,13 +9,22 @@ var BufferReader = function BufferReader(buf) {
if (!(this instanceof BufferReader)) {
return new BufferReader(buf);
}
if (_.isUndefined(buf)) {
return;
}
if (Buffer.isBuffer(buf)) {
this.set({
buf: buf
});
} else if (buf) {
} else if (_.isString(buf)) {
this.set({
buf: new Buffer(buf, 'hex'),
});
} else if (_.isObject(buf)) {
var obj = buf;
this.set(obj);
} else {
throw new TypeError('Unrecognized argument for BufferReader');
}
};

View File

@ -99,7 +99,7 @@ Script.fromBuffer = function(buffer) {
}
} catch (e) {
if (e instanceof RangeError) {
throw new errors.Script.InvalidBuffer(buffer);
throw new errors.Script.InvalidBuffer(buffer.toString('hex'));
}
throw e;
}
@ -778,13 +778,6 @@ Script.prototype.toAddress = function(network) {
return new Address(info);
};
/**
* @return {Script}
*/
Script.prototype.toScriptHashOut = function() {
return Script.buildScriptHashOut(this);
};
/**
* Analagous to bitcoind's FindAndDelete. Find and delete equivalent chunks,
* typically used with push data chunks. Note that this will find and delete

View File

@ -30,6 +30,9 @@ Object.defineProperty(Input.prototype, 'script', {
writeable: false,
enumerable: true,
get: function() {
if (this.isNull()) {
return null;
}
if (!this._script) {
this._script = new Script(this._scriptBuffer);
}
@ -59,8 +62,12 @@ Input.prototype.toObject = function toObject() {
prevTxId: this.prevTxId.toString('hex'),
outputIndex: this.outputIndex,
sequenceNumber: this.sequenceNumber,
script: this.script.toString(),
script: this._scriptBuffer.toString('hex'),
};
// add human readable form if input contains valid script
if (this.script) {
obj.scriptString = this.script.toString();
}
if (this.output) {
obj.output = this.output.toObject();
}
@ -88,6 +95,8 @@ Input.fromBufferReader = function(br) {
input.outputIndex = br.readUInt32LE();
input._scriptBuffer = br.readVarLengthBuffer();
input.sequenceNumber = br.readUInt32LE();
// TODO: return different classes according to which input it is
// e.g: CoinbaseInput, PublicKeyHashInput, MultiSigScriptHashInput, etc.
return input;
};
@ -105,14 +114,19 @@ Input.prototype.toBufferWriter = function(writer) {
};
Input.prototype.setScript = function(script) {
this._script = null;
if (script instanceof Script) {
this._script = script;
this._scriptBuffer = script.toBuffer();
} else if (JSUtil.isHexa(script)) {
// hex string script
this._scriptBuffer = new Buffer(script, 'hex');
} else if (_.isString(script)) {
// human readable string script
this._script = new Script(script);
this._scriptBuffer = this._script.toBuffer();
} else if (BufferUtil.isBuffer(script)) {
this._script = null;
// buffer script
this._scriptBuffer = new buffer.Buffer(script);
} else {
throw new TypeError('Invalid argument type: script');

View File

@ -1017,7 +1017,7 @@ Transaction.prototype.verify = function() {
var isCoinbase = this.isCoinbase();
if (isCoinbase) {
var buf = this.inputs[0]._script.toBuffer();
var buf = this.inputs[0]._scriptBuffer;
if (buf.length < 2 || buf.length > 100) {
return 'coinbase transaction script size invalid';
}

File diff suppressed because one or more lines are too long

View File

@ -21,6 +21,12 @@ describe('BufferReader', function() {
should.exist(br);
Buffer.isBuffer(br.buf).should.equal(true);
});
it('should fail for invalid object', function() {
var fail = function() {
return new BufferReader(5);
};
fail.should.throw('Unrecognized argument for BufferReader');
});
describe('#set', function() {

View File

@ -196,9 +196,6 @@ describe('Interpreter', function() {
var scriptPubkey = Script.fromBitcoindString(vector[1]);
var flags = getFlags(vector[2]);
//testToFromString(scriptSig);
//testToFromString(scriptPubkey);
var hashbuf = new Buffer(32);
hashbuf.fill(0);
var credtx = new Transaction();
@ -242,7 +239,8 @@ describe('Interpreter', function() {
var fullScriptString = vector[0] + ' ' + vector[1];
var comment = descstr ? (' (' + descstr + ')') : '';
it('should pass script_' + (expected ? '' : 'in') + 'valid ' +
'vector #' + c + ': ' + fullScriptString + comment, function() {
'vector #' + c + ': ' + fullScriptString + comment,
function() {
testFixture(vector, expected);
});
});
@ -279,12 +277,15 @@ describe('Interpreter', function() {
var tx = new Transaction(txhex);
var allInputsVerified = true;
tx.inputs.forEach(function(txin, j) {
if (txin.isNull()) {
return;
}
var scriptSig = txin.script;
var txidhex = txin.prevTxId.toString('hex');
var txoutnum = txin.outputIndex;
var scriptPubkey = map[txidhex + ':' + txoutnum];
should.exist(scriptPubkey);
should.exist(scriptSig);
(scriptSig !== undefined).should.equal(true);
var interp = new Interpreter();
var verified = interp.verify(scriptSig, scriptPubkey, tx, j, flags);
if (!verified) {

View File

@ -11,8 +11,6 @@ var Opcode = bitcore.Opcode;
var PublicKey = bitcore.PublicKey;
var Address = bitcore.Address;
var script_valid = require('../data/bitcoind/script_valid');
describe('Script', function() {
it('should make a new script', function() {
@ -328,11 +326,16 @@ describe('Script', function() {
describe('#isScripthashOut', function() {
it('should identify this known pubkeyhashout as pubkeyhashout', function() {
it('should identify this known p2shout as p2shout', function() {
Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(true);
});
it('should identify these known non-pubkeyhashout as not pubkeyhashout', function() {
it('should identify result of .isScriptHashOut() as p2sh', function() {
Script('OP_DUP OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG')
.toScriptHashOut().isScriptHashOut().should.equal(true);
});
it('should identify these known non-p2shout as not p2shout', function() {
Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL OP_EQUAL').isScriptHashOut().should.equal(false);
Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(false);
});
@ -755,4 +758,5 @@ describe('Script', function() {
});
});
});

View File

@ -73,7 +73,6 @@ describe('Transaction.Input', function() {
it('fromObject should work', function() {
var input = Input.fromJSON(coinbaseJSON);
var obj = input.toObject();
obj.script = new Buffer(obj.script, 'hex');
Input.fromObject(obj).should.deep.equal(input);
obj.script = 42;
Input.fromObject.bind(null, obj).should.throw('Invalid argument type: script');