Skip to content

Commit

Permalink
primitives: add serialized offset and only for block reader/writer
Browse files Browse the repository at this point in the history
  • Loading branch information
braydonf committed Apr 12, 2019
1 parent 70bec37 commit 10ef180
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/primitives/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ class Block extends AbstractBlock {
let witness = 0;

for (let i = 0; i < count; i++) {
const tx = TX.fromReader(br);
const tx = TX.fromReader(br, true);
witness += tx._witness;
this.txs.push(tx);
}
Expand Down Expand Up @@ -738,7 +738,7 @@ class Block extends AbstractBlock {
bw.writeVarint(this.txs.length);

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

return bw;
}
Expand Down
37 changes: 28 additions & 9 deletions lib/primitives/tx.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class TX {

this._raw = null;
this._offset = -1;
this._block = false;
this._size = -1;
this._witness = -1;
this._sigops = -1;
Expand Down Expand Up @@ -159,6 +160,7 @@ class TX {
this._raw = null;
this._size = -1;
this._offset = -1;
this._block = false;
this._witness = -1;
this._sigops = -1;

Expand Down Expand Up @@ -247,15 +249,21 @@ class TX {
/**
* Write the transaction to a buffer writer.
* @param {BufferWriter} bw
* @param {Boolean} block
*/

toWriter(bw) {
toWriter(bw, block) {
if (this.mutable) {
if (this.hasWitness())
return this.writeWitness(bw);
return this.writeNormal(bw);
}

if (block) {
this._offset = bw.offset;
this._block = true;
}

bw.writeBytes(this.toRaw());

return bw;
Expand Down Expand Up @@ -320,7 +328,7 @@ class TX {
*/

getPosition() {
assert(this._offset >= 0, 'Position not available.');
assert(this._block && this._offset > 80, 'Position not available.');

return {
offset: this._offset,
Expand Down Expand Up @@ -2243,11 +2251,12 @@ class TX {
/**
* Instantiate a transaction from a buffer reader.
* @param {BufferReader} br
* @param {Boolean} block
* @returns {TX}
*/

static fromReader(br) {
return new this().fromReader(br);
static fromReader(br, block) {
return new this().fromReader(br, block);
}

/**
Expand All @@ -2264,11 +2273,12 @@ class TX {
* Inject properties from buffer reader.
* @private
* @param {BufferReader} br
* @param {Boolean} block
*/

fromReader(br) {
fromReader(br, block) {
if (hasWitnessBytes(br))
return this.fromWitnessReader(br);
return this.fromWitnessReader(br, block);

const start = br.start();

Expand All @@ -2286,9 +2296,13 @@ class TX {

this.locktime = br.readU32();

if (block) {
this._offset = start;
this._block = true;
}

if (!this.mutable) {
this._raw = br.endData();
this._offset = start;
this._size = this._raw.length;
this._witness = 0;
} else {
Expand All @@ -2303,9 +2317,10 @@ class TX {
* buffer reader (witness serialization).
* @private
* @param {BufferReader} br
* @param {Boolean} block
*/

fromWitnessReader(br) {
fromWitnessReader(br, block) {
const start = br.start();

this.version = br.readU32();
Expand Down Expand Up @@ -2354,10 +2369,14 @@ class TX {

this.locktime = br.readU32();

if (block) {
this._offset = start;
this._block = true;
}

if (!this.mutable && hasWitness) {
this._raw = br.endData();
this._size = this._raw.length;
this._offset = start;
this._witness = witness;
} else {
br.end();
Expand Down
41 changes: 40 additions & 1 deletion test/block-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,46 @@ describe('Block', function() {
}
});

it('should deserialize with offset positions for txs (witness)', () => {
it('should serialize with offset positions for txs (witness)', () => {
const [block] = block482683.getBlock();

const expected = [
{offset: 81, size: 217},
{offset: 298, size: 815},
{offset: 1113, size: 192},
{offset: 1305, size: 259},
{offset: 1564, size: 223},
{offset: 1787, size: 1223},
{offset: 3010, size: 486},
{offset: 3496, size: 665},
{offset: 4161, size: 3176},
{offset: 7337, size: 225},
{offset: 7562, size: 1223},
{offset: 8785, size: 503}
];

assert.equal(expected.length, block.txs.length);
assert.equal(block.getSize(), expected.reduce((a, b) => a + b.size, 81));

// Reset the offset for all transactions, and clear
// any cached values for the block.
block.refresh(true);
for (let i = 0; i < block.txs.length; i++)
assert.equal(block.txs[i]._offset, -1);

// Serialize the block, as done before saving to disk.
const raw = block.toRaw();
assert(raw);

for (let i = 0; i < block.txs.length; i++) {
const {offset, size} = block.txs[i].getPosition();

assert.strictEqual(offset, expected[i].offset);
assert.strictEqual(size, expected[i].size);
}
});

it('should deserialize with offset positions for txs', () => {
const [block] = block300025.getBlock();

assert.equal(block.txs.length, 461);
Expand Down

0 comments on commit 10ef180

Please sign in to comment.