fix chain preload.
This commit is contained in:
parent
df97d0ce11
commit
509ef15094
@ -269,7 +269,7 @@ Chain.prototype._ensureGenesis = function _ensureGenesis(callback) {
|
||||
Chain.prototype._preload = function _preload(callback) {
|
||||
var self = this;
|
||||
var url = 'https://headers.electrum.org/blockchain_headers';
|
||||
var chainHeight, buf, height, stream;
|
||||
var buf, height, stream;
|
||||
var request;
|
||||
|
||||
if (!this.options.preload)
|
||||
@ -289,114 +289,118 @@ Chain.prototype._preload = function _preload(callback) {
|
||||
|
||||
utils.debug('Loading %s', url);
|
||||
|
||||
stream = request.get(url);
|
||||
chainHeight = this.db.getSize() - 1;
|
||||
height = 0;
|
||||
buf = {
|
||||
data: [],
|
||||
size: 0
|
||||
};
|
||||
this.db.getChainHeight(function(err, chainHeight) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
stream.on('response', function(res) {
|
||||
if (res.statusCode >= 400) {
|
||||
stream.destroy();
|
||||
return callback(new Error('Bad response code: ' + res.statusCode));
|
||||
}
|
||||
});
|
||||
stream = request.get(url);
|
||||
height = 0;
|
||||
buf = {
|
||||
data: [],
|
||||
size: 0
|
||||
};
|
||||
|
||||
stream.on('error', function(err) {
|
||||
var start = Math.max(0, height - 2);
|
||||
self.reset(start, function(e) {
|
||||
if (e)
|
||||
throw e;
|
||||
return callback(err, start + 1);
|
||||
stream.on('response', function(res) {
|
||||
if (res.statusCode >= 400) {
|
||||
stream.destroy();
|
||||
return callback(new Error('Bad response code: ' + res.statusCode));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
stream.on('data', function(data) {
|
||||
var blocks = [];
|
||||
var need = 80 - buf.size;
|
||||
var i, lastEntry;
|
||||
|
||||
while (data.length >= need) {
|
||||
buf.data.push(data.slice(0, need));
|
||||
blocks.push(Buffer.concat(buf.data));
|
||||
buf.data.length = 0;
|
||||
buf.size = 0;
|
||||
data = data.slice(need);
|
||||
need = 80 - buf.size;
|
||||
}
|
||||
|
||||
if (data.length > 0) {
|
||||
assert(data.length < 80);
|
||||
buf.data.push(data);
|
||||
buf.size += data.length;
|
||||
}
|
||||
|
||||
if (blocks.length === 0)
|
||||
return;
|
||||
|
||||
blocks.forEach(function(data) {
|
||||
var entry = bcoin.chainblock.fromRaw(self, data);
|
||||
var block, start;
|
||||
|
||||
entry.height = height;
|
||||
|
||||
block = bcoin.headers(entry);
|
||||
|
||||
// Do some paranoid checks.
|
||||
if (lastEntry && entry.prevBlock !== lastEntry.hash) {
|
||||
start = Math.max(0, height - 2);
|
||||
stream.destroy();
|
||||
return self.reset(start, function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
return callback(new Error('Corrupt headers.'), start + 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Verify the block headers. We don't want to
|
||||
// trust an external centralized source completely.
|
||||
if (!block.verifyHeaders()) {
|
||||
start = Math.max(0, height - 2);
|
||||
stream.destroy();
|
||||
return self.reset(start, function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
return callback(new Error('Bad headers.'), start + 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate chainwork.
|
||||
delete entry.chainwork;
|
||||
entry.chainwork = entry.getChainwork(lastEntry);
|
||||
|
||||
lastEntry = entry;
|
||||
|
||||
// Make sure the genesis block is correct.
|
||||
if (height === 0 && entry.hash !== network.genesis.hash) {
|
||||
stream.destroy();
|
||||
return callback(new Error('Bad genesis block.'), 0);
|
||||
}
|
||||
|
||||
// Filthy hack to avoid writing
|
||||
// redundant blocks to disk!
|
||||
if (height <= chainHeight) {
|
||||
self.db.addCache(entry);
|
||||
self.db.bloom(entry.hash, 'hex');
|
||||
} else {
|
||||
self.db.save(entry);
|
||||
}
|
||||
|
||||
height++;
|
||||
|
||||
if ((height + 1) % 50000 === 0)
|
||||
utils.debug('Received %d headers from electrum.org.', height + 1);
|
||||
stream.on('error', function(err) {
|
||||
var start = Math.max(0, height - 2);
|
||||
self.reset(start, function(e) {
|
||||
if (e)
|
||||
throw e;
|
||||
return callback(err, start + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
return callback(null, height + 1);
|
||||
stream.on('data', function(data) {
|
||||
var blocks = [];
|
||||
var need = 80 - buf.size;
|
||||
var i, lastEntry;
|
||||
|
||||
while (data.length >= need) {
|
||||
buf.data.push(data.slice(0, need));
|
||||
blocks.push(Buffer.concat(buf.data));
|
||||
buf.data.length = 0;
|
||||
buf.size = 0;
|
||||
data = data.slice(need);
|
||||
need = 80 - buf.size;
|
||||
}
|
||||
|
||||
if (data.length > 0) {
|
||||
assert(data.length < 80);
|
||||
buf.data.push(data);
|
||||
buf.size += data.length;
|
||||
}
|
||||
|
||||
if (blocks.length === 0)
|
||||
return;
|
||||
|
||||
blocks.forEach(function(data) {
|
||||
var entry = bcoin.chainblock.fromRaw(self, data);
|
||||
var block, start;
|
||||
|
||||
entry.height = height;
|
||||
|
||||
block = bcoin.headers(entry);
|
||||
|
||||
// Do some paranoid checks.
|
||||
if (lastEntry && entry.prevBlock !== lastEntry.hash) {
|
||||
start = Math.max(0, height - 2);
|
||||
stream.destroy();
|
||||
return self.reset(start, function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
return callback(new Error('Corrupt headers.'), start + 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Verify the block headers. We don't want to
|
||||
// trust an external centralized source completely.
|
||||
if (!block.verifyHeaders()) {
|
||||
start = Math.max(0, height - 2);
|
||||
stream.destroy();
|
||||
return self.reset(start, function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
return callback(new Error('Bad headers.'), start + 1);
|
||||
});
|
||||
}
|
||||
|
||||
// Calculate chainwork.
|
||||
delete entry.chainwork;
|
||||
entry.chainwork = entry.getChainwork(lastEntry);
|
||||
|
||||
lastEntry = entry;
|
||||
|
||||
// Make sure the genesis block is correct.
|
||||
if (height === 0 && entry.hash !== network.genesis.hash) {
|
||||
stream.destroy();
|
||||
return callback(new Error('Bad genesis block.'), 0);
|
||||
}
|
||||
|
||||
// Filthy hack to avoid writing
|
||||
// redundant blocks to disk!
|
||||
if (height <= chainHeight) {
|
||||
self.db.addCache(entry);
|
||||
self.db.bloom(entry.hash, 'hex');
|
||||
} else {
|
||||
self.db.save(entry);
|
||||
}
|
||||
|
||||
height++;
|
||||
|
||||
if ((height + 1) % 50000 === 0)
|
||||
utils.debug('Received %d headers from electrum.org.', height + 1);
|
||||
});
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
return callback(null, height + 1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user