diff --git a/lib/indexer/indexer.js b/lib/indexer/indexer.js index d16f8dc9..5a6b51f4 100644 --- a/lib/indexer/indexer.js +++ b/lib/indexer/indexer.js @@ -15,6 +15,8 @@ const Logger = require('blgr'); const Network = require('../protocol/network'); const util = require('../utils/util'); const layout = require('./layout'); +const CoinView = require('../coins/coinview'); +const Block = require('../primitives/block'); const {ZERO_HASH} = require('../protocol/consensus'); /** @@ -111,6 +113,8 @@ class Indexer extends EventEmitter { const data = await this.db.get(layout.R.encode()); if (data) this.height = bio.readU32(data, 0); + else + await this.saveGenesis(); // Bind to chain events. this.bind(); @@ -160,6 +164,27 @@ class Indexer extends EventEmitter { throw new Error('Indexer: Network mismatch.'); } + /** + * A special case for indexing the genesis block. The genesis + * block coins are not spendable, however indexers can still index + * the block for historical and informational purposes. + * @private + * @returns {Promise} + */ + + async saveGenesis() { + this.start(); + + const block = Block.fromRaw(Buffer.from(this.network.genesisBlock, 'hex')); + const meta = new BlockMeta(block.hash(), 0); + + await this.indexBlock(meta, block, new CoinView()); + await this._setTip(meta); + await this.commit(); + + this.height = 0; + } + /** * Bind to chain events. * @private diff --git a/test/indexer-test.js b/test/indexer-test.js index 021f8100..699c4813 100644 --- a/test/indexer-test.js +++ b/test/indexer-test.js @@ -8,6 +8,7 @@ const reorg = require('./util/reorg'); const Script = require('../lib/script/script'); const Opcode = require('../lib/script/opcode'); const Address = require('../lib/primitives/address'); +const Block = require('../lib/primitives/block'); const Chain = require('../lib/blockchain/chain'); const WorkerPool = require('../lib/workers/workerpool'); const Miner = require('../lib/mining/miner'); @@ -306,6 +307,21 @@ describe('Indexer', function() { assert.strictEqual(tx, null); assert.strictEqual(meta, null); }); + + it('should get unspendable genesis tx', async () => { + const block = Block.fromRaw(Buffer.from(network.genesisBlock, 'hex')); + const hash = block.txs[0].hash(); + + const tx = await txindexer.getTX(hash); + const meta = await txindexer.getMeta(hash); + + assert(meta); + assert.equal(meta.height, 0); + assert(meta.block); + assert(meta.time); + + assert.deepEqual(meta.tx, tx); + }); }); describe('Reorg and rescan', function() {