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) {
|
Chain.prototype._preload = function _preload(callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var url = 'https://headers.electrum.org/blockchain_headers';
|
var url = 'https://headers.electrum.org/blockchain_headers';
|
||||||
var chainHeight, buf, height, stream;
|
var buf, height, stream;
|
||||||
var request;
|
var request;
|
||||||
|
|
||||||
if (!this.options.preload)
|
if (!this.options.preload)
|
||||||
@ -289,114 +289,118 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
|
|
||||||
utils.debug('Loading %s', url);
|
utils.debug('Loading %s', url);
|
||||||
|
|
||||||
stream = request.get(url);
|
this.db.getChainHeight(function(err, chainHeight) {
|
||||||
chainHeight = this.db.getSize() - 1;
|
if (err)
|
||||||
height = 0;
|
return callback(err);
|
||||||
buf = {
|
|
||||||
data: [],
|
|
||||||
size: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
stream.on('response', function(res) {
|
stream = request.get(url);
|
||||||
if (res.statusCode >= 400) {
|
height = 0;
|
||||||
stream.destroy();
|
buf = {
|
||||||
return callback(new Error('Bad response code: ' + res.statusCode));
|
data: [],
|
||||||
}
|
size: 0
|
||||||
});
|
};
|
||||||
|
|
||||||
stream.on('error', function(err) {
|
stream.on('response', function(res) {
|
||||||
var start = Math.max(0, height - 2);
|
if (res.statusCode >= 400) {
|
||||||
self.reset(start, function(e) {
|
stream.destroy();
|
||||||
if (e)
|
return callback(new Error('Bad response code: ' + res.statusCode));
|
||||||
throw e;
|
}
|
||||||
return callback(err, start + 1);
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
stream.on('data', function(data) {
|
stream.on('error', function(err) {
|
||||||
var blocks = [];
|
var start = Math.max(0, height - 2);
|
||||||
var need = 80 - buf.size;
|
self.reset(start, function(e) {
|
||||||
var i, lastEntry;
|
if (e)
|
||||||
|
throw e;
|
||||||
while (data.length >= need) {
|
return callback(err, start + 1);
|
||||||
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() {
|
stream.on('data', function(data) {
|
||||||
return callback(null, height + 1);
|
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