chaindb: refactor.

This commit is contained in:
Christopher Jeffrey 2017-12-06 10:25:23 -08:00
parent cb978df380
commit bad028ab67
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
6 changed files with 53 additions and 82 deletions

View File

@ -31,19 +31,6 @@ const thresholdStates = common.thresholdStates;
* @property {ChainEntry?} tip
* @property {Number} height
* @property {DeploymentState} state
* @emits Chain#open
* @emits Chain#error
* @emits Chain#block
* @emits Chain#competitor
* @emits Chain#resolved
* @emits Chain#checkpoint
* @emits Chain#fork
* @emits Chain#reorganize
* @emits Chain#invalid
* @emits Chain#exists
* @emits Chain#connect
* @emits Chain#reconnect
* @emits Chain#disconnect
*/
class Chain extends AsyncEmitter {
@ -945,7 +932,7 @@ class Chain extends AsyncEmitter {
'Chain replay from height %d necessary.',
fork.height);
await this.emitAsync('reorganize', tip, competitor);
return this.emitAsync('reorganize', tip, competitor);
}
/**
@ -973,7 +960,7 @@ class Chain extends AsyncEmitter {
this.emit('tip', prev);
await this.emitAsync('disconnect', entry, block, view);
return this.emitAsync('disconnect', entry, block, view);
}
/**
@ -1023,7 +1010,7 @@ class Chain extends AsyncEmitter {
this.emit('tip', entry);
this.emit('reconnect', entry, block);
await this.emitAsync('connect', entry, block, view);
return this.emitAsync('connect', entry, block, view);
}
/**
@ -1047,10 +1034,8 @@ class Chain extends AsyncEmitter {
// In spv-mode, we reset the
// chain and redownload the blocks.
if (this.options.spv) {
await this.reorganizeSPV(entry);
return;
}
if (this.options.spv)
return this.reorganizeSPV(entry);
await this.reorganize(entry);
}
@ -1091,7 +1076,7 @@ class Chain extends AsyncEmitter {
this.emit('tip', entry);
this.emit('block', block, entry);
await this.emitAsync('connect', entry, block, view);
return this.emitAsync('connect', entry, block, view);
}
/**

View File

@ -514,7 +514,7 @@ class ChainDB {
this.logger.info('Writing genesis block to ChainDB.');
await this.save(entry, block, new CoinView());
return this.save(entry, block, new CoinView());
}
/**
@ -635,9 +635,9 @@ class ChainDB {
*/
saveDeployments() {
const batch = this.db.batch();
this.writeDeployments(batch);
return batch.write();
const b = this.db.batch();
this.writeDeployments(b);
return b.write();
}
/**
@ -645,7 +645,7 @@ class ChainDB {
* @returns {Promise}
*/
writeDeployments(batch) {
writeDeployments(b) {
const bw = bio.write(1 + 17 * this.network.deploys.length);
bw.writeU8(this.network.deploys.length);
@ -658,7 +658,7 @@ class ChainDB {
bw.writeI32(deployment.window);
}
batch.put(layout.D.build(), bw.render());
b.put(layout.D.build(), bw.render());
}
/**
@ -719,17 +719,17 @@ class ChainDB {
if (invalid.length === 0)
return true;
const batch = this.db.batch();
const b = this.db.batch();
for (const bit of invalid) {
this.logger.warning('Versionbit deployment params modified.');
this.logger.warning('Invalidating cache for bit %d.', bit);
await this.invalidateCache(bit, batch);
await this.invalidateCache(bit, b);
}
this.writeDeployments(batch);
this.writeDeployments(b);
await batch.write();
await b.write();
return false;
}
@ -740,14 +740,14 @@ class ChainDB {
* @returns {Promise}
*/
async invalidateCache(bit, batch) {
async invalidateCache(bit, b) {
const keys = await this.db.keys({
gte: layout.v.min(bit),
lte: layout.v.max(bit)
});
for (const key of keys)
batch.del(key);
b.del(key);
}
/**
@ -772,7 +772,7 @@ class ChainDB {
const start = pruneAfter + 1;
const end = height - keepBlocks;
const batch = this.db.batch();
const b = this.db.batch();
for (let i = start; i <= end; i++) {
const hash = await this.getHash(i);
@ -780,8 +780,8 @@ class ChainDB {
if (!hash)
throw new Error(`Cannot find hash for ${i}.`);
batch.del(layout.b.build(hash));
batch.del(layout.u.build(hash));
b.del(layout.b.build(hash));
b.del(layout.u.build(hash));
}
try {
@ -790,9 +790,9 @@ class ChainDB {
const flags = ChainFlags.fromOptions(options);
assert(flags.prune);
batch.put(layout.O.build(), flags.toRaw());
b.put(layout.O.build(), flags.toRaw());
await batch.write();
await b.write();
} catch (e) {
options.prune = false;
throw e;
@ -1309,6 +1309,7 @@ class ChainDB {
for (let i = 0; i < block.txs.length; i++) {
const tx = block.txs[i];
let found = false;
for (let j = 0; j < tx.outputs.length; j++) {
@ -1372,7 +1373,7 @@ class ChainDB {
}
/**
* Save an entry without a batch.
* Save an entry.
* @private
* @param {ChainEntry} entry
* @param {Block} block
@ -1438,7 +1439,7 @@ class ChainDB {
}
/**
* Reconnect block without a batch.
* Reconnect block.
* @private
* @param {ChainEntry} entry
* @param {Block} block
@ -1495,7 +1496,7 @@ class ChainDB {
}
/**
* Disconnect block without a batch.
* Disconnect block.
* @private
* @param {ChainEntry} entry
* @param {Block} block
@ -1756,7 +1757,7 @@ class ChainDB {
async connectBlock(entry, block, view) {
if (this.options.spv)
return;
return undefined;
const hash = block.hash();
@ -1764,7 +1765,7 @@ class ChainDB {
// Genesis block's coinbase is unspendable.
if (entry.isGenesis())
return;
return undefined;
// Update chain state value.
for (let i = 0; i < block.txs.length; i++) {
@ -1794,7 +1795,7 @@ class ChainDB {
this.put(layout.u.build(hash), view.undo.commit());
// Prune height-288 if pruning is enabled.
await this.pruneBlock(entry);
return this.pruneBlock(entry);
}
/**
@ -1891,9 +1892,9 @@ class ChainDB {
saveFlags() {
const flags = ChainFlags.fromOptions(this.options);
const batch = this.db.batch();
batch.put(layout.O.build(), flags.toRaw());
return batch.write();
const b = this.db.batch();
b.put(layout.O.build(), flags.toRaw());
return b.write();
}
/**
@ -1914,8 +1915,7 @@ class ChainDB {
this.put(layout.t.build(hash), meta.toRaw());
if (this.options.indexAddress) {
const hashes = tx.getHashes(view);
for (const addr of hashes)
for (const addr of tx.getHashes(view))
this.put(layout.T.build(addr, hash), null);
}
}
@ -1925,12 +1925,16 @@ class ChainDB {
if (!tx.isCoinbase()) {
for (const {prevout} of tx.inputs) {
const addr = view.getOutput(prevout).getHash();
const {hash, index} = prevout;
const coin = view.getOutput(prevout);
assert(coin);
const addr = coin.getHash();
if (!addr)
continue;
this.del(layout.C.build(addr, prevout.hash, prevout.index));
this.del(layout.C.build(addr, hash, index));
}
}
@ -1958,8 +1962,7 @@ class ChainDB {
if (this.options.indexTX) {
this.del(layout.t.build(hash));
if (this.options.indexAddress) {
const hashes = tx.getHashes(view);
for (const addr of hashes)
for (const addr of tx.getHashes(view))
this.del(layout.T.build(addr, hash));
}
}
@ -1969,12 +1972,16 @@ class ChainDB {
if (!tx.isCoinbase()) {
for (const {prevout} of tx.inputs) {
const addr = view.getOutput(prevout).getHash();
const {hash, index} = prevout;
const coin = view.getOutput(prevout);
assert(coin);
const addr = coin.getHash();
if (!addr)
continue;
this.put(layout.C.build(addr, prevout.hash, prevout.index), null);
this.put(layout.C.build(addr, hash, index), null);
}
}
@ -1990,13 +1997,6 @@ class ChainDB {
}
}
/**
* Database layout.
* @type {Object}
*/
ChainDB.layout = layout;
/**
* ChainFlags
*/

View File

@ -2048,13 +2048,6 @@ class TXDB {
}
}
/**
* Database layout.
* @type {Object}
*/
TXDB.layout = layout;
/**
* Balance
* @alias module:wallet.Balance

View File

@ -219,9 +219,8 @@ class WalletDB extends EventEmitter {
}
const magic = raw.readUInt32LE(0, true);
const network = Network.fromMagic(magic);
if (network !== this.network)
if (magic !== this.network.magic)
throw new Error('Network mismatch for WalletDB.');
return undefined;
@ -585,7 +584,7 @@ class WalletDB extends EventEmitter {
this.logger.warning('Wiped %d txdb records.', total);
await b.write();
return b.write();
}
/**
@ -2113,17 +2112,10 @@ class WalletDB extends EventEmitter {
if (entry.height > this.state.height)
throw new Error('WDB: Bad reset height.');
await this.rollback(entry.height);
return this.rollback(entry.height);
}
}
/**
* Database layout.
* @type {Object}
*/
WalletDB.layout = layout;
/**
* Wallet Options
* @alias module:wallet.WalletOptions

View File

@ -3,7 +3,6 @@
const assert = require('assert');
const bdb = require('bdb');
const layout = require('../lib/blockchain/layout');
const DUMMY = Buffer.alloc(1, 0x00);
// changes:
// db version record
@ -59,7 +58,7 @@ async function migrateKeys(id, from, to) {
let items = 0;
await iter.each(async (key) => {
batch.put(to.build(...from(key)), DUMMY);
batch.put(to.build(...from(key)), null);
batch.del(key);
total += (key.length + 80) * 2;

View File

@ -235,6 +235,8 @@ async function updateLookahead() {
await db.close();
}
updateLookahead;
async function unstate() {
await db.open();
batch = db.batch();