Skip to content

Commit

Permalink
Merge pull request #881 from braydonf/merkle-serialize
Browse files Browse the repository at this point in the history
Add option to serialize merkle block with transactions
  • Loading branch information
braydonf committed Oct 17, 2019
2 parents e678642 + 3b24b16 commit 41af3d2
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
97 changes: 96 additions & 1 deletion lib/primitives/merkleblock.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const util = require('../utils/util');
const hash256 = require('bcrypto/lib/hash256');
const consensus = require('../protocol/consensus');
const AbstractBlock = require('./abstractblock');
const TX = require('./tx');
const Headers = require('./headers');
const DUMMY = Buffer.from([0]);
const {encoding} = bio;
Expand Down Expand Up @@ -316,7 +317,9 @@ class MerkleBlock extends AbstractBlock {
}),
flags: this.flags,
map: this.getTree().map,
txs: this.txs.length
txs: this.txs.map((tx, i) => {
return tx.format(view, null, i);
})
};
}

Expand All @@ -336,6 +339,22 @@ class MerkleBlock extends AbstractBlock {
return size;
}

/**
* Get merkleblock size with transactions.
* @returns {Number} Size.
*/

getExtendedSize() {
let size = this.getSize();

size += encoding.sizeVarint(this.txs.length);

for (const tx of this.txs)
size += tx.getSize();

return size;
}

/**
* Write the merkleblock to a buffer writer.
* @param {BufferWriter} bw
Expand All @@ -356,6 +375,22 @@ class MerkleBlock extends AbstractBlock {
return bw;
}

/**
* Write the merkleblock to a buffer writer with transactions.
* @param {BufferWriter} bw
*/

toExtendedWriter(bw) {
this.toWriter(bw);

bw.writeVarint(this.txs.length);

for (const tx of this.txs)
tx.toWriter(bw);

return bw;
}

/**
* Serialize the merkleblock.
* @param {String?} enc - Encoding, can be `'hex'` or null.
Expand All @@ -367,6 +402,16 @@ class MerkleBlock extends AbstractBlock {
return this.toWriter(bio.write(size)).render();
}

/**
* Serialize the merkleblock with transactions.
* @returns {Buffer}
*/

toExtendedRaw() {
const size = this.getExtendedSize();
return this.toExtendedWriter(bio.write(size)).render();
}

/**
* Inject properties from buffer reader.
* @private
Expand All @@ -388,6 +433,23 @@ class MerkleBlock extends AbstractBlock {
return this;
}

/**
* Inject properties with transactions from buffer reader.
* @private
* @param {BufferReader} br
*/

fromExtendedReader(br) {
this.fromReader(br);

const count = br.readVarint();

for (let i = 0; i < count; i++)
this.txs.push(TX.fromReader(br));

return this;
}

/**
* Inject properties from serialized data.
* @private
Expand All @@ -398,6 +460,16 @@ class MerkleBlock extends AbstractBlock {
return this.fromReader(bio.read(data));
}

/**
* Inject properties with transactions from serialized data.
* @private
* @param {Buffer} data
*/

fromExtendedRaw(data) {
return this.fromExtendedReader(bio.read(data));
}

/**
* Instantiate a merkleblock from a buffer reader.
* @param {BufferReader} br
Expand All @@ -408,6 +480,16 @@ class MerkleBlock extends AbstractBlock {
return new this().fromReader(br);
}

/**
* Instantiate a merkleblock with transactions from a buffer reader.
* @param {BufferReader} br
* @returns {MerkleBlock}
*/

static fromExtendedReader(br) {
return new this().fromExtendedReader(br);
}

/**
* Instantiate a merkleblock from a serialized data.
* @param {Buffer} data
Expand All @@ -421,6 +503,19 @@ class MerkleBlock extends AbstractBlock {
return new this().fromRaw(data);
}

/**
* Instantiate a merkleblock with transactions from a serialized data.
* @param {Buffer} data
* @param {String?} enc - Encoding, can be `'hex'` or null.
* @returns {MerkleBlock}
*/

static fromExtendedRaw(data, enc) {
if (typeof data === 'string')
data = Buffer.from(data, enc);
return new this().fromExtendedRaw(data);
}

/**
* Convert the block to an object suitable
* for JSON serialization.
Expand Down
16 changes: 16 additions & 0 deletions test/block-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const assert = require('bsert');
const common = require('./util/common');
const {BloomFilter} = require('bfilter');
const {BufferMap} = require('buffer-map');
const TX = require('../lib/primitives/tx');
const Block = require('../lib/primitives/block');
const MerkleBlock = require('../lib/primitives/merkleblock');
const consensus = require('../lib/protocol/consensus');
Expand Down Expand Up @@ -101,6 +102,21 @@ describe('Block', function() {
assert(block2.verify());
});

it('should serialize merkle block with transactions', () => {
const [full] = block300025.getBlock();
const [block] = merkle300025.getBlock();

const tree = block.getTree();

for (const tx of full.txs) {
if (tree.map.has(tx.hash()))
block.txs.push(TX.fromRaw(tx.toRaw()));
}

const block2 = MerkleBlock.fromExtendedRaw(block.toExtendedRaw());
assert.deepEqual(block.txs, block2.txs);
});

it('should parse JSON', () => {
const [block1] = block300025.getBlock();
const block2 = Block.fromJSON(block1.toJSON());
Expand Down
Binary file added test/data/merkle300025-extended.raw
Binary file not shown.

0 comments on commit 41af3d2

Please sign in to comment.