chaindb/pool: fixes. work.
This commit is contained in:
parent
9a575e9a26
commit
92619d408e
@ -99,7 +99,6 @@ Chain.msg = function msg(code) {
|
||||
|
||||
Chain.prototype._init = function _init() {
|
||||
var self = this;
|
||||
var s;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
@ -114,6 +113,7 @@ Chain.prototype._init = function _init() {
|
||||
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
|
||||
utils.debug('Chain successfully loaded.');
|
||||
});
|
||||
};
|
||||
@ -153,10 +153,10 @@ Chain.prototype._addIndex = function _addIndex(entry, save) {
|
||||
this.index.heights[entry.hash] = entry.height;
|
||||
this.index.count++;
|
||||
|
||||
if (!this.tip || entry.height > this.tip.height)
|
||||
if (!this.tip || entry.height > this.tip.height) {
|
||||
this.tip = entry;
|
||||
|
||||
this.emit('tip', this.tip);
|
||||
this.emit('tip', this.tip);
|
||||
}
|
||||
|
||||
return Chain.codes.okay;
|
||||
};
|
||||
@ -180,6 +180,7 @@ Chain.prototype.resetLastCheckpoint = function resetLastCheckpoint(height) {
|
||||
|
||||
Chain.prototype.resetHeight = function resetHeight(height) {
|
||||
var self = this;
|
||||
var i, existing;
|
||||
|
||||
assert(height < this.index.count);
|
||||
|
||||
@ -191,10 +192,11 @@ Chain.prototype.resetHeight = function resetHeight(height) {
|
||||
this.orphan.count = 0;
|
||||
this.orphan.size = 0;
|
||||
|
||||
for (var i = height + 1; height < this.index.count; i++) {
|
||||
var existing = this.db.get(i);
|
||||
this.db.del(i);
|
||||
for (i = height + 1; height < this.index.count; i++) {
|
||||
existing = this.db.get(i);
|
||||
assert(existing);
|
||||
delete this.index.heights[existing.hash];
|
||||
this.db.del(i);
|
||||
}
|
||||
|
||||
this.tip = this.db.get(height);
|
||||
@ -493,8 +495,7 @@ Chain.prototype.getTip = function getTip() {
|
||||
};
|
||||
|
||||
Chain.prototype.isFull = function isFull() {
|
||||
var last = this.tip.ts;
|
||||
var delta = utils.now() - last;
|
||||
var delta = utils.now() - this.tip.ts;
|
||||
return delta < 40 * 60;
|
||||
};
|
||||
|
||||
@ -702,46 +703,73 @@ Chain.prototype.fromJSON = function fromJSON(json) {
|
||||
|
||||
var BLOCK_SIZE = 112;
|
||||
|
||||
function ChainDB(chain) {
|
||||
var exists;
|
||||
function ChainDB(chain, options) {
|
||||
if (!(this instanceof ChainDB))
|
||||
return new ChainDB(chain);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
this.options = options;
|
||||
this.chain = chain;
|
||||
this.file = process.env.HOME + '/bcoin-' + network.type + '.blockchain';
|
||||
this.file = options.file;
|
||||
|
||||
if (!this.file)
|
||||
this.file = process.env.HOME + '/bcoin-' + network.type + '.blockchain';
|
||||
|
||||
this._queue = [];
|
||||
this._cache = {};
|
||||
this._bufferPool = {};
|
||||
this._nullBlock = new Buffer(BLOCK_SIZE);
|
||||
this._nullBlock.fill(0);
|
||||
this.tip = -1;
|
||||
this.size = 0;
|
||||
this.fd = null;
|
||||
|
||||
// Need to cache up to the retarget interval
|
||||
// if we're going to be checking the damn
|
||||
// target all the time.
|
||||
if (network.powAllowMinDifficultyBlocks)
|
||||
this._cacheWindow = network.powDiffInterval + 1;
|
||||
else
|
||||
this._cacheWindow = network.block.majorityWindow + 1;
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
ChainDB.prototype._init = function _init() {
|
||||
try {
|
||||
fs.unlinkSync(this.file);
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.accessSync(file);
|
||||
exists = true;
|
||||
} catch (e) {
|
||||
exists = false;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
if (!this.exists()) {
|
||||
fs.writeFileSync(this.file, new Buffer(0));
|
||||
fs.truncateSync(this.file, 0);
|
||||
}
|
||||
|
||||
this.size = this.getSize();
|
||||
this.fd = fs.openSync(this.file, 'r+');
|
||||
}
|
||||
};
|
||||
|
||||
ChainDB.prototype.getBuffer = function(size) {
|
||||
if (!this._bufferPool[size])
|
||||
this._bufferPool[size] = new Buffer(size);
|
||||
|
||||
return this._bufferPool[size];
|
||||
};
|
||||
|
||||
ChainDB.prototype.size = function size() {
|
||||
ChainDB.prototype.exists = function exists() {
|
||||
try {
|
||||
fs.statSync(file);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ChainDB.prototype.getSize = function getSize() {
|
||||
try {
|
||||
return fs.statSync(this.file).size;
|
||||
} catch (e) {
|
||||
@ -750,11 +778,20 @@ ChainDB.prototype.size = function size() {
|
||||
};
|
||||
|
||||
ChainDB.prototype.count = function count() {
|
||||
return this.size() / BLOCK_SIZE | 0;
|
||||
return this.size / BLOCK_SIZE | 0;
|
||||
};
|
||||
|
||||
ChainDB.prototype.cache = function cache(entry) {
|
||||
if (entry.height > this.tip) {
|
||||
this.tip = entry.height;
|
||||
delete this._cache[entry.height - this._cacheWindow];
|
||||
this._cache[entry.height] = entry;
|
||||
assert(Object.keys(this._cache).length <= this._cacheWindow);
|
||||
}
|
||||
};
|
||||
|
||||
ChainDB.prototype.get = function get(height) {
|
||||
var data;
|
||||
var data, entry;
|
||||
|
||||
if (this._cache[height])
|
||||
return this._cache[height];
|
||||
@ -762,25 +799,37 @@ ChainDB.prototype.get = function get(height) {
|
||||
if (this._queue[height])
|
||||
return this._queue[height];
|
||||
|
||||
if (height < 0 || height == null)
|
||||
return;
|
||||
|
||||
if ((height + 1) * BLOCK_SIZE > this.size)
|
||||
return;
|
||||
|
||||
data = this._read(BLOCK_SIZE, height * BLOCK_SIZE);
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Ignore if it is a null block.
|
||||
if (utils.read32(data, 0) === 0)
|
||||
return;
|
||||
|
||||
return ChainBlock.fromRaw(this.chain, height, data);
|
||||
entry = ChainBlock.fromRaw(this.chain, height, data);
|
||||
|
||||
// Cache the past 1001 blocks in memory
|
||||
// (necessary for isSuperMajority)
|
||||
this.cache(entry);
|
||||
|
||||
return entry;
|
||||
};
|
||||
|
||||
ChainDB.prototype.save = function save(entry, callback) {
|
||||
var self = this;
|
||||
var raw, offset;
|
||||
|
||||
// Cache the past 2016 blocks in memory
|
||||
this._cache[entry.height] = entry;
|
||||
delete this._cache[entry.height - network.powDiffInterval];
|
||||
assert(Object.keys(this._cache).length < network.powDiffInterval + 1);
|
||||
// Cache the past 1001 blocks in memory
|
||||
// (necessary for isSuperMajority)
|
||||
this.cache(entry);
|
||||
|
||||
// Something is already writing. Cancel it
|
||||
// and synchronously write the data after
|
||||
@ -834,10 +883,12 @@ ChainDB.prototype.del = function del(height) {
|
||||
// If we deleted several blocks at the end, go back
|
||||
// to the last non-null block and truncate the file
|
||||
// beyond that point.
|
||||
if ((height + 1) * BLOCK_SIZE === this.size()) {
|
||||
if ((height + 1) * BLOCK_SIZE === this.size) {
|
||||
while (this.isNull(height))
|
||||
height--;
|
||||
fs.ftruncateSync(this.fd, (height + 1) * BLOCK_SIZE);
|
||||
this.size = (height + 1) * BLOCK_SIZE;
|
||||
this.tip = height;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -888,8 +939,10 @@ ChainDB.prototype._write = function _write(data, offset, callback) {
|
||||
size -= bytes;
|
||||
offset += bytes;
|
||||
|
||||
if (index === data.length)
|
||||
if (index === data.length) {
|
||||
self.size += data.length;
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
callee();
|
||||
});
|
||||
@ -908,8 +961,10 @@ ChainDB.prototype._writeSync = function _writeSync(data, offset) {
|
||||
index += bytes;
|
||||
size -= bytes;
|
||||
offset += bytes;
|
||||
if (index === data.length)
|
||||
if (index === data.length) {
|
||||
self.size += data.length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1024,6 +1079,7 @@ ChainBlock.prototype.toRaw = function toRaw() {
|
||||
|
||||
ChainBlock.fromRaw = function fromRaw(chain, height, p) {
|
||||
return new ChainBlock(chain, {
|
||||
height: height,
|
||||
hash: utils.toHex(utils.dsha256(p.slice(0, 80))),
|
||||
version: utils.read32(p, 0),
|
||||
prevBlock: utils.toHex(p.slice(4, 36)),
|
||||
@ -1031,7 +1087,6 @@ ChainBlock.fromRaw = function fromRaw(chain, height, p) {
|
||||
ts: utils.readU32(p, 68),
|
||||
bits: utils.readU32(p, 72),
|
||||
nonce: utils.readU32(p, 76),
|
||||
height: height,
|
||||
chainwork: new bn(p.slice(80, 112), 'be')
|
||||
});
|
||||
};
|
||||
|
||||
@ -1577,6 +1577,7 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
||||
var i, addr;
|
||||
var original = this.originalSeeds;
|
||||
var seeds = this.seeds;
|
||||
var all = original.concat(seeds);
|
||||
var tries = this.peers.tries.regular;
|
||||
|
||||
if (priority)
|
||||
@ -1653,8 +1654,8 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
||||
// If we have no block peers, always return
|
||||
// an address.
|
||||
if (!priority) {
|
||||
if (this.peers.pending.length + this.peers.block.length === 0)
|
||||
return original[Math.random() * (original.length - 1) | 0];
|
||||
if (all.length === 1)
|
||||
return all[Math.random() * (all.length - 1) | 0];
|
||||
}
|
||||
|
||||
// This should never happen: priority sockets
|
||||
|
||||
Loading…
Reference in New Issue
Block a user