Skip to content

Commit

Permalink
chain: use nurkel instead of urkel.
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Feb 28, 2023
1 parent 6b47c3a commit 8c7dd0d
Show file tree
Hide file tree
Showing 19 changed files with 202 additions and 137 deletions.
13 changes: 7 additions & 6 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class Chain extends AsyncEmitter {
// tree interval. We might also need to recover from a
// failed compactTree() operation. Either way, there might have been
// new blocks added to the chain since then.
const currentRoot = this.db.treeRoot();
const currentRoot = await this.db.treeRoot();

// We store commit height for the tree in the tree state.
// commitHeight is the height of the block that committed tree root.
Expand Down Expand Up @@ -211,7 +211,8 @@ class Chain extends AsyncEmitter {
await this.db.saveNames(view, entry, false);
}

this.logger.info('Synchronized Tree Root: %x.', this.db.txn.rootHash());
this.logger.info('Synchronized Tree Root: %x.',
await this.db.txn.txRootHash());
}

/**
Expand Down Expand Up @@ -737,7 +738,7 @@ class Chain extends AsyncEmitter {
const view = new CoinView();
const height = prev.height + 1;

assert(block.treeRoot.equals(this.db.treeRoot()));
assert(block.treeRoot.equals(await this.db.treeRoot()));

for (let i = 0; i < block.txs.length; i++) {
const tx = block.txs[i];
Expand Down Expand Up @@ -786,7 +787,7 @@ class Chain extends AsyncEmitter {
let reward = 0;

// Check the name tree root.
if (!block.treeRoot.equals(this.db.treeRoot())) {
if (!block.treeRoot.equals(await this.db.treeRoot())) {
throw new VerifyError(block,
'invalid',
'bad-tree-root',
Expand Down Expand Up @@ -1815,7 +1816,7 @@ class Chain extends AsyncEmitter {
this.emit('reconnect', entry, block);

if ((entry.height % this.network.names.treeInterval) === 0)
this.emit('tree commit', this.db.tree.rootHash(), entry, block);
this.emit('tree commit', await this.db.tree.treeRootHash(), entry, block);

return this.emitAsync('connect', entry, block, view);
}
Expand Down Expand Up @@ -1914,7 +1915,7 @@ class Chain extends AsyncEmitter {
this.emit('block', block, entry);

if ((entry.height % this.network.names.treeInterval) === 0)
this.emit('tree commit', this.db.tree.rootHash(), entry, block);
this.emit('tree commit', await this.db.tree.treeRootHash(), entry, block);

return this.emitAsync('connect', entry, block, view);
}
Expand Down
76 changes: 43 additions & 33 deletions lib/blockchain/chaindb.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
const assert = require('bsert');
const bdb = require('bdb');
const bio = require('bufio');
const blake2b = require('bcrypto/lib/blake2b');
const LRU = require('blru');
const {Tree} = require('urkel');
const nurkel = require('nurkel');
const {Tree} = nurkel;
const {BufferMap, BufferSet} = require('buffer-map');
const ChainMigrator = require('./migrations');
const Amount = require('../ui/amount');
Expand Down Expand Up @@ -53,14 +53,11 @@ class ChainDB {
this.db = bdb.create(this.options);
this.name = 'chain';
this.version = 3;
this.tree = new Tree({
hash: blake2b,
bits: 256,
this.tree = nurkel.create({
prefix: this.options.treePrefix,
cacheOnly: true,
initCacheSize: -1
memory: this.options.memory || !this.options.treePrefix
});
this.txn = this.tree.txn();
this.txn = null;
this.treeState = new TreeState();
this.stateCache = new StateCache(this.network);
this.state = new ChainState();
Expand All @@ -84,6 +81,9 @@ class ChainDB {
await this.db.open();
await this.tree.open();

this.txn = this.tree.vtxn();
await this.txn.open();

const migrator = new ChainMigrator({
...this.options,
chainDB: this,
Expand Down Expand Up @@ -137,8 +137,6 @@ class ChainDB {
this.logger.info('ChainDB successfully loaded.');
}

this.txn = this.tree.txn();

this.logger.info(
'Chain State: hash=%x tx=%d coin=%d value=%s burned=%s.',
this.state.tip,
Expand All @@ -147,7 +145,7 @@ class ChainDB {
Amount.coin(this.state.value),
Amount.coin(this.state.burned));

this.logger.info('Tree Root: %x.', this.tree.rootHash());
this.logger.info('Tree Root: %x.', await this.tree.treeRootHash());
}

/**
Expand Down Expand Up @@ -224,8 +222,10 @@ class ChainDB {
*/

async close() {
await this.txn.close();
this.txn = null;

await this.tree.close();
this.txn = this.tree.txn();
return this.db.close();
}

Expand Down Expand Up @@ -630,8 +630,9 @@ class ChainDB {
if (this.options.spv)
throw new Error('Cannot lookup in SPV mode.');

const tree = this.tree.snapshot(root);
return tree.get(key);
const snap = this.tree.snapshot(root);
await snap.open();
return snap.get(key);
}

/**
Expand All @@ -645,17 +646,30 @@ class ChainDB {
if (this.options.spv)
throw new Error('Cannot prove in SPV mode.');

const tree = this.tree.snapshot(root);
return tree.prove(key);
const snap = this.tree.snapshot(root);
await snap.open();
return snap.prove(key);
}

/**
* Verify Proof
* @param {Proof}
* @param {Buffer} root
* @param {Buffer} key
* @returns {Promise<Array>}
*/

async verify(root, key, proof) {
return Tree.verify(root, key, proof);
}

/**
* Get the current name tree root.
* @returns {Hash}
* @returns {Promise<Hash>}
*/

treeRoot() {
return this.tree.rootHash();
return this.tree.treeRootHash();
}

/**
Expand Down Expand Up @@ -990,6 +1004,8 @@ class ChainDB {
*/

async compactTree(entry) {
assert(!this.options.memory && this.options.treePrefix,
'Can not compact in memory.');
// Before doing anything to the tree,
// save the target tree root hash to chain database.
// If the tree data gets out of sync or corrupted
Expand All @@ -1006,30 +1022,24 @@ class ChainDB {

const tmpDir = this.options.treePrefix + '~';

const tmpTree = new Tree({
hash: blake2b,
bits: 256,
prefix: tmpDir
});

// Make sure to remove the tmp directory first.
// There should not be directory, unless it was
// stopped in the middle of compaction.
// Otherwise compacted tree would add on top
// of the previsouly compacted db.
const tmpTree = nurkel.create({
prefix: tmpDir
});

await tmpTree.open();
const tmpStore = tmpTree.store;
await tmpTree.close();
await tmpStore.destroy();

// Rewind tree to historical commitment
await this.tree.inject(entry.treeRoot);
await Tree.destroy(tmpDir);

// Delete historical data
await this.tree.compact(tmpDir);
await this.tree.compact(tmpDir, entry.treeRoot);

// Reset in-memory tree delta
this.txn = this.tree.txn();
this.txn = this.tree.vtxn();
await this.txn.open();

// Mark tree compaction complete
this.start();
Expand Down Expand Up @@ -2081,7 +2091,7 @@ class ChainDB {
// Chain will need to recover current txn
// from treeState.commitHeight + 1 (including).
this.put(layout.s.encode(), this.pendingTreeState.commit(
this.tree.rootHash(),
await this.tree.treeRootHash(),
entry.height
));
}
Expand Down
2 changes: 1 addition & 1 deletion lib/mining/miner.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class Miner extends EventEmitter {

const state = await this.chain.getDeployments(time, tip);
const target = await this.chain.getTarget(time, tip);
const root = this.chain.db.treeRoot();
const root = await this.chain.db.treeRoot();

const attempt = new BlockTemplate({
prevBlock: tip.hash,
Expand Down
9 changes: 4 additions & 5 deletions lib/net/packets.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

const assert = require('bsert');
const bio = require('bufio');
const blake2b = require('bcrypto/lib/blake2b');
const UrkelProof = require('urkel').Proof;
const UrkelProof = require('nurkel').Proof;
const {BloomFilter} = require('bfilter');
const common = require('./common');
const util = require('../utils/util');
Expand Down Expand Up @@ -1669,7 +1668,7 @@ class ProofPacket extends Packet {

getSize() {
let size = 64;
size += this.proof.getSize(blake2b, 256);
size += this.proof.getSize();
return size;
}

Expand All @@ -1681,7 +1680,7 @@ class ProofPacket extends Packet {
write(bw) {
bw.writeHash(this.root);
bw.writeBytes(this.key);
this.proof.writeBW(bw, blake2b, 256);
this.proof.writeBW(bw);
return this;
}

Expand All @@ -1694,7 +1693,7 @@ class ProofPacket extends Packet {
read(br) {
this.root = br.readHash();
this.key = br.readBytes(32);
this.proof = UrkelProof.readBR(br, blake2b, 256);
this.proof = UrkelProof.readBR(br);
return this;
}
}
Expand Down
3 changes: 1 addition & 2 deletions lib/net/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const socks = require('bsocks');
const List = require('blst');
const base32 = require('bcrypto/lib/encoding/base32');
const {BufferMap, BufferSet} = require('buffer-map');
const blake2b = require('bcrypto/lib/blake2b');
const {BloomFilter, RollingFilter} = require('bfilter');
const rng = require('bcrypto/lib/random');
const secp256k1 = require('bcrypto/lib/secp256k1');
Expand Down Expand Up @@ -3284,7 +3283,7 @@ class Pool extends EventEmitter {
return;
}

const [code, data] = proof.verify(root, key, blake2b, 256);
const [code, data] = await this.chain.db.verify(root, key, proof);

if (code !== 0) {
this.logger.warning(
Expand Down
3 changes: 1 addition & 2 deletions lib/node/rpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2404,8 +2404,7 @@ class RPC extends RPCBase {

const iter = txn.iterator();

while (await iter.next()) {
const {key, value} = iter;
for await (const [key, value] of iter) {
const ns = NameState.decode(value);
ns.nameHash = key;

Expand Down
Loading

0 comments on commit 8c7dd0d

Please sign in to comment.