indexer: work with blockstore
This commit is contained in:
parent
51ac4a720b
commit
9f89c79bd7
@ -6,8 +6,12 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('bsert');
|
||||
const bdb = require('bdb');
|
||||
const bio = require('bufio');
|
||||
const layout = require('./layout');
|
||||
const consensus = require('../protocol/consensus');
|
||||
const TX = require('../primitives/tx');
|
||||
const TXMeta = require('../primitives/txmeta');
|
||||
const Indexer = require('./indexer');
|
||||
|
||||
@ -20,6 +24,83 @@ Object.assign(layout, {
|
||||
t: bdb.key('t', ['hash256'])
|
||||
});
|
||||
|
||||
/**
|
||||
* Transaction Record
|
||||
*/
|
||||
|
||||
class TxRecord {
|
||||
/**
|
||||
* Create a block record.
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
constructor(options = {}) {
|
||||
this.block = options.block || consensus.ZERO_HASH;
|
||||
this.height = options.height || 0;
|
||||
this.time = options.time || 0;
|
||||
this.index = options.index || 0;
|
||||
this.offset = options.offset || 0;
|
||||
this.length = options.length || 0;
|
||||
|
||||
assert((this.height >>> 0) === this.height);
|
||||
assert((this.time >>> 0) === this.time);
|
||||
assert((this.index >>> 0) === this.index);
|
||||
assert((this.offset >>> 0) === this.offset);
|
||||
assert((this.length >>> 0) === this.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from serialized data.
|
||||
* @private
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
fromRaw(data) {
|
||||
const br = bio.read(data);
|
||||
|
||||
this.block = br.readHash();
|
||||
this.height = br.readU32();
|
||||
this.time = br.readU32();
|
||||
this.index = br.readU32();
|
||||
if (this.index === 0x7fffffff)
|
||||
this.index = -1;
|
||||
|
||||
this.offset = br.readU32();
|
||||
this.length = br.readU32();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate block record from serialized data.
|
||||
* @param {Hash} hash
|
||||
* @param {Buffer} data
|
||||
* @returns {BlockRecord}
|
||||
*/
|
||||
|
||||
static fromRaw(data) {
|
||||
return new this().fromRaw(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the block record.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
toRaw() {
|
||||
const bw = bio.write(52);
|
||||
|
||||
bw.writeHash(this.block);
|
||||
bw.writeU32(this.height);
|
||||
bw.writeU32(this.time);
|
||||
bw.writeU32(this.index);
|
||||
bw.writeU32(this.offset);
|
||||
bw.writeU32(this.length);
|
||||
|
||||
return bw.render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TXIndexer
|
||||
* @alias module:indexer.TXIndexer
|
||||
@ -50,11 +131,27 @@ class TXIndexer extends Indexer {
|
||||
async indexBlock(entry, block, view) {
|
||||
const b = this.db.batch();
|
||||
|
||||
for (let i = 0; i < block.txs.length; i++) {
|
||||
const tx = block.txs[i];
|
||||
const data = block.toRaw();
|
||||
const br = bio.read(data);
|
||||
// ignore header
|
||||
br.readBytes(80);
|
||||
const count = br.readVarint();
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const offset = br.offset;
|
||||
const tx = TX.fromReader(br);
|
||||
const length = br.offset - offset;
|
||||
const hash = tx.hash();
|
||||
const meta = TXMeta.fromTX(tx, entry, i);
|
||||
b.put(layout.t.encode(hash), meta.toRaw());
|
||||
|
||||
const txrecord = new TxRecord({
|
||||
block: entry.hash,
|
||||
height: entry.height,
|
||||
time: entry.time,
|
||||
index: i,
|
||||
offset: offset,
|
||||
length: length
|
||||
});
|
||||
b.put(layout.t.encode(hash), txrecord.toRaw());
|
||||
}
|
||||
|
||||
return b.write();
|
||||
@ -87,12 +184,22 @@ class TXIndexer extends Indexer {
|
||||
*/
|
||||
|
||||
async getMeta(hash) {
|
||||
const data = await this.db.get(layout.t.encode(hash));
|
||||
|
||||
if (!data)
|
||||
const raw = await this.db.get(layout.t.encode(hash));
|
||||
if (!raw)
|
||||
return null;
|
||||
|
||||
return TXMeta.fromRaw(data);
|
||||
const record = TxRecord.fromRaw(raw);
|
||||
|
||||
const data = await this.read(record.block, record.offset, record.length);
|
||||
const tx = TX.fromRaw(data);
|
||||
|
||||
const meta = TXMeta.fromTX(tx);
|
||||
meta.height = record.height;
|
||||
meta.block = record.block;
|
||||
meta.time = record.time;
|
||||
meta.index = record.index;
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user