node: add blockstore to full node

This commit is contained in:
Braydon Fuller 2019-03-07 11:02:22 -08:00
parent 11af5456ce
commit 0b0dd58a91
No known key found for this signature in database
GPG Key ID: F24F232D108B3AD4
6 changed files with 56 additions and 16 deletions

View File

@ -49,6 +49,7 @@ class Chain extends AsyncEmitter {
this.network = this.options.network;
this.logger = this.options.logger.context('chain');
this.blocks = this.options.blocks;
this.workers = this.options.workers;
this.db = new ChainDB(this.options);
@ -2662,6 +2663,7 @@ class ChainOptions {
constructor(options) {
this.network = Network.primary;
this.logger = Logger.global;
this.blocks = null;
this.workers = null;
this.prefix = null;
@ -2695,6 +2697,11 @@ class ChainOptions {
*/
fromOptions(options) {
assert(options.blocks && typeof options.blocks === 'object',
'Chain requires a blockstore.');
this.blocks = options.blocks;
if (options.network != null)
this.network = Network.get(options.network);

View File

@ -11,7 +11,6 @@ const assert = require('bsert');
const bdb = require('bdb');
const bio = require('bufio');
const LRU = require('blru');
const {resolve} = require('path');
const {BufferMap, BufferSet} = require('buffer-map');
const Amount = require('../btc/amount');
const Network = require('../protocol/network');
@ -25,7 +24,6 @@ const Address = require('../primitives/address');
const ChainEntry = require('./chainentry');
const TXMeta = require('../primitives/txmeta');
const CoinEntry = require('../coins/coinentry');
const FileBlockStore = require('../blockstore/file');
/**
* ChainDB
@ -42,15 +40,14 @@ class ChainDB {
this.options = options;
this.network = this.options.network;
this.logger = this.options.logger.context('chaindb');
this.blocks = this.options.blocks;
this.db = bdb.create(this.options);
this.stateCache = new StateCache(this.network);
this.state = new ChainState();
this.pending = null;
this.current = null;
this.blockStore = new FileBlockStore({
location: resolve(options.location, '../blocks')
});
this.cacheHash = new LRU(this.options.entryCache, null, BufferMap);
this.cacheHeight = new LRU(this.options.entryCache);
@ -66,7 +63,6 @@ class ChainDB {
await this.db.open();
await this.db.verify(layout.V.encode(), 'chain', 5);
await this.blockStore.open();
const state = await this.getState();
@ -108,7 +104,6 @@ class ChainDB {
*/
async close() {
await this.blockStore.close();
return this.db.close();
}
@ -776,7 +771,7 @@ class ChainDB {
throw new Error(`Cannot find hash for ${i}.`);
b.del(layout.u.encode(hash));
await this.blockStore.prune(hash);
await this.blocks.prune(hash);
}
try {
@ -1059,7 +1054,7 @@ class ChainDB {
if (!hash)
return null;
return this.blockStore.read(hash);
return this.blocks.read(hash);
}
/**
@ -1646,7 +1641,7 @@ class ChainDB {
this.del(layout.p.encode(tip.hash));
this.del(layout.h.encode(tip.hash));
this.del(layout.e.encode(tip.hash));
await this.blockStore.prune(tip.hash);
await this.blocks.prune(tip.hash);
// Queue up hash to be removed
// on successful write.
@ -1674,7 +1669,7 @@ class ChainDB {
// Write actual block data (this may be
// better suited to flat files in the future).
await this.blockStore.write(hash, block.toRaw());
await this.blocks.write(hash, block.toRaw());
if (!view)
return;
@ -1698,7 +1693,7 @@ class ChainDB {
if (!block)
throw new Error('Block not found.');
await this.blockStore.prune(block.hash());
await this.blocks.prune(block.hash());
return this.disconnectBlock(entry, block);
}
@ -1859,7 +1854,7 @@ class ChainDB {
return;
this.del(layout.u.encode(hash));
await this.blockStore.prune(hash);
await this.blocks.prune(hash);
}
/**

View File

@ -16,6 +16,7 @@ const Miner = require('../mining/miner');
const Node = require('./node');
const HTTP = require('./http');
const RPC = require('./rpc');
const blockstore = require('../blockstore');
/**
* Full Node
@ -40,10 +41,20 @@ class FullNode extends Node {
// SPV flag.
this.spv = false;
// Instantiate blockchain.
// Instantiate block storage.
this.blocks = blockstore.create({
network: this.network,
logger: this.logger,
prefix: this.config.prefix,
cacheSize: this.config.mb('block-cache-size'),
memory: this.config.bool('memory')
});
// Chain needs access to blocks.
this.chain = new Chain({
network: this.network,
logger: this.logger,
blocks: this.blocks,
workers: this.workers,
memory: this.config.bool('memory'),
prefix: this.config.prefix,
@ -218,6 +229,7 @@ class FullNode extends Node {
this.opened = true;
await this.handlePreopen();
await this.blocks.open();
await this.chain.open();
await this.mempool.open();
await this.miner.open();
@ -250,6 +262,7 @@ class FullNode extends Node {
await this.miner.close();
await this.mempool.close();
await this.chain.close();
await this.blocks.close();
await this.handleClose();
}

View File

@ -17,6 +17,7 @@ const Output = require('../lib/primitives/output');
const common = require('../lib/blockchain/common');
const nodejsUtil = require('util');
const Opcode = require('../lib/script/opcode');
const BlockStore = require('../lib/blockstore/level');
const opcodes = Script.opcodes;
const ZERO_KEY = Buffer.alloc(33, 0x00);
@ -30,8 +31,14 @@ const workers = new WorkerPool({
enabled: true
});
const blocks = new BlockStore({
memory: true,
network
});
const chain = new Chain({
memory: true,
blocks,
network,
workers
});
@ -115,6 +122,7 @@ describe('Chain', function() {
this.timeout(process.browser ? 1200000 : 60000);
it('should open chain and miner', async () => {
await blocks.open();
await chain.open();
await miner.open();
});
@ -895,5 +903,6 @@ describe('Chain', function() {
it('should cleanup', async () => {
await miner.close();
await chain.close();
await blocks.close();
});
});

View File

@ -18,6 +18,7 @@ const Script = require('../lib/script/script');
const opcodes = Script.opcodes;
const Witness = require('../lib/script/witness');
const MemWallet = require('./util/memwallet');
const BlockStore = require('../lib/blockstore/level');
const ALL = Script.hashType.ALL;
const ONE_HASH = Buffer.alloc(32, 0x00);
@ -27,9 +28,14 @@ const workers = new WorkerPool({
enabled: true
});
const blocks = new BlockStore({
memory: true
});
const chain = new Chain({
memory: true,
workers
workers,
blocks
});
const mempool = new Mempool({
@ -68,6 +74,7 @@ describe('Mempool', function() {
it('should open mempool', async () => {
await workers.open();
await blocks.open();
await chain.open();
await mempool.open();
chain.state.flags |= Script.flags.VERIFY_WITNESS;
@ -453,6 +460,7 @@ describe('Mempool', function() {
it('should destroy mempool', async () => {
await mempool.close();
await chain.close();
await blocks.close();
await workers.close();
});
});

View File

@ -7,6 +7,7 @@ const assert = require('./util/assert');
const Chain = require('../lib/blockchain/chain');
const ChainEntry = require('../lib/blockchain/chainentry');
const Network = require('../lib/protocol/network');
const BlockStore = require('../lib/blockstore/level');
const network = Network.get('main');
@ -14,13 +15,20 @@ function random(max) {
return Math.floor(Math.random() * max);
}
const chain = new Chain({
const blocks = new BlockStore({
memory: true,
network
});
const chain = new Chain({
memory: true,
network,
blocks
});
describe('Difficulty', function() {
it('should open chain', async () => {
await blocks.open();
await chain.open();
});