Browse Source

fix block parsing problem

patch-2
Manuel Araoz 10 years ago
parent
commit
dfc075e5d1
  1. 1
      lib/block/block.js
  2. 6
      lib/script/script.js
  3. 21
      lib/transaction/input/input.js
  4. 2
      test/block.js
  5. 18
      test/script/script.js

1
lib/block/block.js

@ -69,7 +69,6 @@ Block._fromJSON = function _fromJSON(data) {
Block._fromObject = function _fromObject(data) { Block._fromObject = function _fromObject(data) {
var transactions = []; var transactions = [];
data.transactions.forEach(function(tx) { data.transactions.forEach(function(tx) {
console.log(tx.id);
transactions.push(Transaction().fromJSON(tx)); transactions.push(Transaction().fromJSON(tx));
}); });
var info = { var info = {

6
lib/script/script.js

@ -93,13 +93,17 @@ Script.fromBuffer = function(buffer) {
opcodenum: opcodenum opcodenum: opcodenum
}); });
} else { } else {
var op = Opcode.reverseMap[opcodenum];
if (!op) {
throw new errors.Script.InvalidBuffer(buffer.toString('hex'));
}
script.chunks.push({ script.chunks.push({
opcodenum: opcodenum opcodenum: opcodenum
}); });
} }
} catch (e) { } catch (e) {
if (e instanceof RangeError) { if (e instanceof RangeError) {
throw new errors.Script.InvalidBuffer(buffer); throw new errors.Script.InvalidBuffer(buffer.toString('hex'));
} }
throw e; throw e;
} }

21
lib/transaction/input/input.js

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

2
test/block.js

@ -188,7 +188,7 @@ describe('Block', function() {
prevTxId: '0000000000000000000000000000000000000000000000000000000000000000', prevTxId: '0000000000000000000000000000000000000000000000000000000000000000',
outputIndex: 4294967295, outputIndex: 4294967295,
sequenceNumber: 4294967295, sequenceNumber: 4294967295,
script: '4 0xffff001d 1 0x04' script: '04ffff001d0104'
}], }],
outputs: [{ outputs: [{
satoshis: 5000000000, satoshis: 5000000000,

18
test/script/script.js

@ -754,13 +754,17 @@ describe('Script', function() {
Script().add(new Buffer('a')).equals(Script().add(new Buffer('b'))).should.equal(false); Script().add(new Buffer('a')).equals(Script().add(new Buffer('b'))).should.equal(false);
}); });
}); });
describe.only('coinbase transaction input script', function() { describe('coinbase transaction input script for tx ', function() {
it('works for bug found in bitcore-node', function() { it('fails for that specific malformed script', function() {
var hex = '03984b05e4b883e5bda9e7a59ee4bb99e9b1bcfabe6d6d5cb348c1c7d580627835202f5ad93c2f3db10bb850a1a513979f8328d9f35aff1000000000000000006189dd01cf00004d696e6564206279207975313333353131373131'; var hex = '03984b05' + // push 0x03 bytes with block height
var s = new Script(hex); 'e4' + // attempt to push 0xe4 bytes, but should use OP_PUSHDATA 0xe4
var s2 = new Script(s.toString()); 'b883e5bda9e7a59ee4bb99e9b1bcfabe6d6d5cb348c1c7d58062783520' +
console.log(s2.toString()); '2f5ad93c2f3db10bb850a1a513979f8328d9f35aff1000000000000000' +
s2.toString().should.equal(s.toString()); '006189dd01cf00004d696e6564206279207975313333353131373131';
var fails = function() {
return new Script(hex);
};
fails.should.throw('Invalid script buffer: can\'t parse valid script from given buffer');
}); });
}); });

Loading…
Cancel
Save