switch to fullchain for both spv and fullnode.

This commit is contained in:
Christopher Jeffrey 2016-01-04 20:13:06 -08:00
parent 582a21fd5a
commit 019ecf4f2a
6 changed files with 29235 additions and 16276 deletions

View File

@ -49,7 +49,7 @@ function Chain(options) {
this.request = new utils.RequestCache();
this.fromJSON({
v: 1,
v: 2,
type: 'chain',
network: network.type,
entries: [
@ -64,6 +64,9 @@ function Chain(options) {
]
});
if (!this.options.fullNode)
this.fromJSON(network.preload);
this.tip = this.index.entries[this.index.entries.length - 1];
// Last TS after preload, needed for fill percent
@ -183,13 +186,20 @@ Chain.prototype.resetHeight = function resetHeight(height) {
var self = this;
var ahead = this.index.entries.slice(height + 1);
assert(height < this.index.entries - 1);
assert(height <= this.index.entries.length - 1);
if (height === this.index.entries.length - 1)
return;
this.orphan.map = {};
this.orphan.bmap = {};
this.orphan.count = 0;
this.index.entries.length = height + 1;
this.index.heights = this.index.entries.reduce(function(out, entry) {
if (!self.options.fullNode) {
if (!entry)
return out;
}
out[entry.hash] = entry.height;
return out;
}, {});
@ -204,6 +214,10 @@ Chain.prototype.resetHeight = function resetHeight(height) {
);
ahead.forEach(function(entry) {
if (!self.options.fullNode) {
if (!entry)
return;
}
self._delete(entry.hash);
});
};
@ -225,7 +239,6 @@ Chain.prototype.add = function add(block, peer) {
var initial = block;
var code = Chain.codes.unchanged;
var length = this.index.entries.length;
var hash, prev, prevProbe, range, i, entry;
for (;;) {
@ -306,6 +319,12 @@ Chain.prototype.add = function add(block, peer) {
this.orphan.count = 0;
}
// No need to have a huge chain
// if (!this.options.fullNode) {
// if (this.size() > 100000)
// this.compact();
// }
return code;
};
@ -342,6 +361,10 @@ Chain.prototype.byHash = function byHash(hash) {
Chain.prototype.byTime = function byTime(ts) {
for (var i = this.index.entries.length - 1; i >= 0; i--) {
if (!this.options.fullNode) {
if (!this.index.entries[i])
continue;
}
if (ts >= this.index.entries[i].ts)
return this.index.entries[i];
}
@ -356,10 +379,6 @@ Chain.prototype.hasOrphan = function hasOrphan(hash) {
return !!this.getOrphan(hash);
};
Chain.prototype.hasCache = function hasCache(hash) {
assert(false);
};
Chain.prototype.getBlock = function getBlock(hash) {
if (typeof hash === 'number')
return this.byHeight(hash);
@ -375,10 +394,6 @@ Chain.prototype.getOrphan = function getOrphan(hash) {
return this.orphan.bmap[hash] || null;
};
Chain.prototype.getCache = function getCache(hash) {
assert(false);
};
Chain.prototype.getTip = function getTip() {
return this.index.entries[this.index.entries.length - 1];
};
@ -406,11 +421,10 @@ Chain.prototype.hashRange = function hashRange(start, end) {
hashes = this.index.hashes.slice(start.height, end.height + 1);
return hashes;
};
if (!this.options.fullNode)
hashes = hashes.filter(Boolean);
Chain.prototype.hashesInRange = function hashesInRange(start, end, cb) {
assert(false);
return hashes;
};
Chain.prototype.getStartHeight = function getStartHeight() {
@ -450,7 +464,8 @@ Chain.prototype.locatorHashes = function locatorHashes(start) {
hashes.push(chain[i]);
i = i - step;
if (i <= 0) {
hashes.push(chain[0]);
if (i + step !== 0)
hashes.push(chain[0]);
break;
}
if (hashes.length >= 10)
@ -565,8 +580,57 @@ Chain.prototype.retarget = function retarget(last, firstTs) {
return utils.toCompact(target);
};
Chain.prototype.compact = function compact() {
assert(false);
Chain.prototype.compact = function compact(keep) {
var entries = this._compact(keep);
this.index.entries = {};
this.index.hashes = [];
this.index.heights = {};
json.entries.forEach(function(entry) {
this._addIndex(ChainBlock.fromJSON(this, entry));
}, this);
};
Chain.prototype._compact = function _compact(keep) {
var entries = this.index.entries.filter(Boolean);
if (!keep)
keep = 1000;
// Keep only last 1000 consequent blocks, dilate others at:
// 7 day range for blocks before 2013
// 12 hour for blocks before 2014
// 6 hour for blocks in 2014 and after it
// (or at maximum 250 block range)
var last = entries.slice(-keep);
var first = [];
var delta1 = 7 * 24 * 3600;
var delta2 = 12 * 3600;
var delta3 = 6 * 3600;
var lastTs = 0;
var lastHeight = -1000;
var i, ts, delta, hdelta;
for (i = 0; i < entries.length - keep; i++) {
ts = entries[i].ts;
delta = ts < 1356984000
? delta1
: ts < 1388520000 ? delta2 : delta3;
hdelta = entries[i].height - lastHeight;
if (ts - lastTs < delta && hdelta < 250)
continue;
lastTs = ts;
lastHeight = entries[i].height;
first.push(this.index.entries[i]);
}
return first.concat(last);
};
Chain.prototype._save = function(hash, obj) {
@ -595,8 +659,12 @@ Chain.prototype._delete = function(hash) {
Chain.prototype.toJSON = function toJSON() {
var entries = this.index.entries;
if (!this.options.fullNode)
entries = this._compact();
return {
v: 1,
v: 2,
type: 'chain',
network: network.type,
entries: entries.map(function(entry) {
@ -606,7 +674,7 @@ Chain.prototype.toJSON = function toJSON() {
};
Chain.prototype.fromJSON = function fromJSON(json) {
assert.equal(json.v, 1);
assert.equal(json.v, 2);
assert.equal(json.type, 'chain');
assert.equal(json.network, network.type);

View File

@ -47,11 +47,11 @@ function Peer(pool, createSocket, options) {
if (this.options.backoff) {
setTimeout(function() {
self.socket = createSocket(self);
self.socket = createSocket(self, pool);
self.emit('socket');
}, this.options.backoff);
} else {
this.socket = createSocket(this);
this.socket = createSocket(this, pool);
}
this._broadcast = {

View File

@ -46,7 +46,7 @@ function Pool(options) {
if (!this.options.fullNode) {
if (this.options.headers == null)
this.options.headers = false;
this.options.headers = true;
if (this.options.multiplePeers == null)
this.options.multiplePeers = true;
} else {
@ -56,6 +56,9 @@ function Pool(options) {
this.options.multiplePeers = false;
}
if (!this.options.headers)
this.options.multiplePeers = false;
this.backoff = {
delta: options.backoffDelta || 500,
max: options.backoffMax || 5000
@ -76,12 +79,11 @@ function Pool(options) {
this.maxRetries = options.maxRetries || 42;
this.requestTimeout = options.requestTimeout || 10000;
Chain = this.options.fullNode
? bcoin.fullChain
: bcoin.spvChain;
Chain = bcoin.fullChain;
this.chain = new Chain({
storage: this.storage
storage: this.storage,
fullNode: this.options.fullNode
});
this.watchMap = {};
@ -322,14 +324,14 @@ Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) {
assert(this.options.headers);
if (headers.length === 0)
return;
this.emit('debug',
'Recieved %s headers from %s',
headers.length,
peer.address);
if (headers.length === 0)
return;
if (headers.length > 2000) {
peer.destroy();
return;
@ -383,14 +385,14 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) {
assert(!this.options.headers);
if (hashes.length === 0)
return;
this.emit('debug',
'Recieved %s block hashes from %s',
hashes.length,
peer.address);
if (hashes.length === 0)
return;
if (hashes.length > 500) {
peer.destroy();
return;

View File

@ -106,7 +106,30 @@ main.genesis = {
main.magic = 0xd9b4bef9;
main.preload = require('./preload');
main.preload = {
v: 2,
type: 'chain',
network: main.type,
entries: [
{
hash: utils.toHex(main.genesis._hash),
version: main.genesis.version,
// prevBlock: utils.toHex(main.genesis.prevBlock),
ts: main.genesis.ts,
bits: main.genesis.bits,
height: 0
}
]
};
try {
main._preload = require('./preload');
utils.assert(main._preload.entries[0]);
main.preload = main._preload;
delete main._preload;
} catch (e) {
delete main._preload;
}
main.powLimit = new bn(
'00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
@ -191,11 +214,19 @@ testnet.genesis = {
testnet.magic = 0x0709110b;
testnet.preload = {
'v': 1,
'type': 'chain',
'hashes': [utils.toHex(testnet.genesis._hash)],
'ts': [testnet.genesis.ts],
'heights': [0]
v: 2,
type: 'chain',
network: testnet.type,
entries: [
{
hash: utils.toHex(testnet.genesis._hash),
version: testnet.genesis.version,
// prevBlock: utils.toHex(testnet.genesis.prevBlock),
ts: testnet.genesis.ts,
bits: testnet.genesis.bits,
height: 0
}
]
};
testnet.powLimit = new bn(

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ var bcoin = require('../');
var addrs = bcoin.protocol.network.seeds.slice();
var pool = bcoin.pool({
size: 32,
size: 6,
redundancy: 1,
parallel: 4000,
loadWindow: 750,