chaindb/pool: fixes. work.

This commit is contained in:
Christopher Jeffrey 2016-01-21 01:24:35 -08:00
parent 9a575e9a26
commit 92619d408e
2 changed files with 91 additions and 35 deletions

View File

@ -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')
});
};

View File

@ -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