cleanup chain db. fixes.
This commit is contained in:
parent
f6a35d0810
commit
43a365962b
@ -45,40 +45,22 @@ function Chain(options) {
|
||||
|
||||
this.index = {
|
||||
heights: {},
|
||||
count: this.db.count(),
|
||||
count: 0,
|
||||
lastTs: 0
|
||||
};
|
||||
|
||||
this.request = new utils.RequestCache();
|
||||
|
||||
this.fromJSON({
|
||||
v: 2,
|
||||
type: 'chain',
|
||||
network: network.type,
|
||||
entries: [
|
||||
{
|
||||
hash: network.genesis.hash,
|
||||
version: network.genesis.version,
|
||||
prevBlock: network.genesis.prevBlock,
|
||||
merkleRoot: network.genesis.merkleRoot,
|
||||
ts: network.genesis.ts,
|
||||
bits: network.genesis.bits,
|
||||
nonce: network.genesis.nonce,
|
||||
height: 0
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
if (process.env.BCOIN_START_HEIGHT) {
|
||||
this.storage = null;
|
||||
if (network.type === 'main')
|
||||
this.fromJSON(require('./protocol/preload-full'));
|
||||
else if (network.type === 'testnet')
|
||||
this.fromJSON(require('./protocol/preload-test-full'));
|
||||
this.resetHeight(+process.env.BCOIN_START_HEIGHT);
|
||||
}
|
||||
|
||||
this.tip = this.db.get(this.index.count - 1);
|
||||
this._addIndex(ChainBlock.fromJSON(this, {
|
||||
hash: network.genesis.hash,
|
||||
version: network.genesis.version,
|
||||
prevBlock: network.genesis.prevBlock,
|
||||
merkleRoot: network.genesis.merkleRoot,
|
||||
ts: network.genesis.ts,
|
||||
bits: network.genesis.bits,
|
||||
nonce: network.genesis.nonce,
|
||||
height: 0
|
||||
}), true);
|
||||
|
||||
// Last TS after preload, needed for fill percent
|
||||
this.index.lastTs = this.tip.ts;
|
||||
@ -121,44 +103,24 @@ Chain.prototype._init = function _init() {
|
||||
|
||||
this.loading = true;
|
||||
|
||||
if (!this.storage) {
|
||||
utils.nextTick(function() {
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
});
|
||||
return;
|
||||
}
|
||||
utils.debug('Chain is loading.');
|
||||
|
||||
utils.nextTick(function() {
|
||||
utils.debug('Chain is loading.');
|
||||
});
|
||||
var count = self.db.count();
|
||||
var i, entry;
|
||||
|
||||
s = this.storage.createReadStream({
|
||||
start: this.prefix,
|
||||
end: this.prefix + 'z'
|
||||
});
|
||||
for (i = 1; i < self.index.count; i++)
|
||||
self._addIndex(self.db.get(i));
|
||||
|
||||
s.on('data', function(data) {
|
||||
data.value.hash = data.key.slice(self.prefix.length);
|
||||
self._addIndex(ChainBlock.fromJSON(self, data.value));
|
||||
});
|
||||
|
||||
s.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
s.on('end', function() {
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
utils.debug('Chain successfully loaded.');
|
||||
});
|
||||
};
|
||||
|
||||
Chain.prototype.getEntry = function getEntry(height) {
|
||||
};
|
||||
|
||||
Chain.prototype._addIndex = function _addIndex(entry, save) {
|
||||
var self = this;
|
||||
var existing;
|
||||
|
||||
// Already added
|
||||
if (this.index.heights[entry.hash] != null) {
|
||||
@ -167,7 +129,7 @@ Chain.prototype._addIndex = function _addIndex(entry, save) {
|
||||
}
|
||||
|
||||
// Duplicate height
|
||||
var existing = this.db.get(entry.height);
|
||||
existing = this.db.get(entry.height);
|
||||
if (existing && existing.hash === entry.hash)
|
||||
return Chain.codes.unchanged;
|
||||
|
||||
@ -185,7 +147,9 @@ Chain.prototype._addIndex = function _addIndex(entry, save) {
|
||||
}
|
||||
}
|
||||
|
||||
this.db.save(entry);
|
||||
if (save)
|
||||
this.db.save(entry);
|
||||
|
||||
this.index.heights[entry.hash] = entry.height;
|
||||
this.index.count++;
|
||||
|
||||
@ -257,7 +221,7 @@ Chain.prototype.resetTime = function resetTime(ts) {
|
||||
Chain.prototype.add = function add(block, peer) {
|
||||
var initial = block;
|
||||
var code = Chain.codes.unchanged;
|
||||
var hash, prevHash, prevHeight, entry, tip;
|
||||
var hash, prevHash, prevHeight, entry, tip, existing;
|
||||
var total = 0;
|
||||
|
||||
for (;;) {
|
||||
@ -329,7 +293,7 @@ Chain.prototype.add = function add(block, peer) {
|
||||
|
||||
// Add entry if we do not have it (or if
|
||||
// there is another entry at its height)
|
||||
var existing = this.db.get(entry.height);
|
||||
existing = this.db.get(entry.height);
|
||||
if (!existing || existing.hash !== hash) {
|
||||
assert(this.index.heights[entry.hash] == null);
|
||||
|
||||
@ -342,7 +306,6 @@ Chain.prototype.add = function add(block, peer) {
|
||||
// The tip has more chainwork, it is a
|
||||
// higher height than the entry. This is
|
||||
// not an alternate tip. Ignore it.
|
||||
if (0)
|
||||
if (this.tip.chainwork.cmp(entry.chainwork) > 0) {
|
||||
code = Chain.codes.unchanged;
|
||||
break;
|
||||
@ -474,12 +437,25 @@ Chain.prototype.byHash = function byHash(hash) {
|
||||
};
|
||||
|
||||
Chain.prototype.byTime = function byTime(ts) {
|
||||
for (var i = this.index.count - 1; i >= 0; i--) {
|
||||
var existing = this.db.get(i);
|
||||
var i, delta, existing;
|
||||
var step = 1;
|
||||
|
||||
if (ts >= this.tip.ts)
|
||||
return this.tip;
|
||||
|
||||
for (i = this.index.count - 1; i >= 0; i -= step) {
|
||||
existing = this.db.get(i);
|
||||
|
||||
if (ts >= existing.ts)
|
||||
return existing;
|
||||
|
||||
delta = existing.ts - ts;
|
||||
// If they're more than 1000 blocks apart
|
||||
if (delta > 1000 * 60 * 10)
|
||||
step *= 2;
|
||||
}
|
||||
return null;
|
||||
|
||||
return this.db.get(0);
|
||||
};
|
||||
|
||||
Chain.prototype.hasBlock = function hasBlock(hash) {
|
||||
@ -540,7 +516,7 @@ Chain.prototype.locatorHashes = function locatorHashes(start) {
|
||||
var hashes = [];
|
||||
var top = this.height();
|
||||
var step = 1;
|
||||
var i;
|
||||
var i, existing;
|
||||
|
||||
if (start) {
|
||||
if (utils.isBuffer(start))
|
||||
@ -564,11 +540,11 @@ Chain.prototype.locatorHashes = function locatorHashes(start) {
|
||||
top = start;
|
||||
}
|
||||
|
||||
// assert(chain[top]);
|
||||
assert(this.db.get(top));
|
||||
|
||||
i = top;
|
||||
for (;;) {
|
||||
var existing = this.db.get(i);
|
||||
existing = this.db.get(i);
|
||||
if (existing)
|
||||
hashes.push(existing.hash);
|
||||
i = i - step;
|
||||
@ -709,7 +685,7 @@ Chain.prototype.fromJSON = function fromJSON(json) {
|
||||
assert.equal(json.network, network.type);
|
||||
|
||||
json.entries.forEach(function(entry) {
|
||||
this._addIndex(ChainBlock.fromJSON(this, entry), true);
|
||||
this._addIndex(ChainBlock.fromJSON(this, entry));
|
||||
}, this);
|
||||
};
|
||||
|
||||
@ -717,8 +693,8 @@ Chain.prototype.fromJSON = function fromJSON(json) {
|
||||
* ChainDB
|
||||
*/
|
||||
|
||||
var BLOCK_SIZE = 80;
|
||||
// var BLOCK_SIZE = 144;
|
||||
// var BLOCK_SIZE = 80;
|
||||
var BLOCK_SIZE = 112;
|
||||
|
||||
function ChainDB(chain) {
|
||||
var exists;
|
||||
@ -952,8 +928,8 @@ function ChainBlock(chain, data) {
|
||||
this.bits = data.bits;
|
||||
this.nonce = data.nonce;
|
||||
this.height = data.height;
|
||||
this.chainwork = data.chainwork || new bn(0);
|
||||
// this.chainwork = data.chainwork || this.getChainwork();
|
||||
// this.chainwork = data.chainwork || new bn(0);
|
||||
this.chainwork = data.chainwork || this.getChainwork();
|
||||
}
|
||||
|
||||
ChainBlock.prototype.__defineGetter__('prev', function() {
|
||||
@ -1041,8 +1017,7 @@ ChainBlock.prototype.toRaw = function toRaw() {
|
||||
utils.writeU32(res, this.ts, 68);
|
||||
utils.writeU32(res, this.bits, 72);
|
||||
utils.writeU32(res, this.nonce, 76);
|
||||
// utils.copy(utils.toArray(this.hash, 'hex'), res, 80);
|
||||
// utils.copy(this.chainwork.toArray('be', 32), res, 112);
|
||||
utils.copy(this.chainwork.toArray('be', 32), res, 80);
|
||||
|
||||
return res;
|
||||
};
|
||||
@ -1057,8 +1032,7 @@ ChainBlock.fromRaw = function fromRaw(chain, height, p) {
|
||||
bits: utils.readU32(p, 72),
|
||||
nonce: utils.readU32(p, 76),
|
||||
height: height,
|
||||
// hash: utils.toHex(utils.toArray(p.slice(80, 112))),
|
||||
// chainwork: new bn(p.slice(112, 144))
|
||||
chainwork: new bn(p.slice(80, 112))
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user