使用 bitcore-p2p 下载标题链
重要事项这只是一个示例代码,不要在生产中使用。
为了下载标题链,我们必须发送 getHeaders 消息 。
在这个例子中,我们将在第 40000 个之后需要尽可能多的头。对等体将响应批量的 2000 个头,因此,我们必须采用最后的头哈希才能够需要下一个 2000 头。
考虑到 bitcore-p2p 是一个基于事件的库的事实,最强大的选项可以是网络接口,以便使用 async / await 来下载头链。为简单起见,我们将使用生成器来面对网络的异步特性。
let Messages = require('bitcore-p2p').Messages;
let Pool = require('bitcore-p2p').Pool;
let NetworksData = require('bitcore-lib').Networks;
let network = 'livenet';
let headers = []; // do not do that in production!
let validHeaders = []; // do not do that in production!
let firsHeader = '000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f';
// Isatnciate and connect a node Pool
let pool = new Pool({network: NetworksData[network]});
pool.connect();
// we have to reverese the hash becaouse is in the format xxxx0000 instead of 0000xxxx or vice versa
function reverseHash(hash){
return hash.match(/.{1,2}/g).reverse().join('');
}
// check if the response is the one associate with the last request becaouse could be a response associate to an old request
function isValidResponse(firstHeaderRecived, headerHashRequested){
// the header hash of the block before the first block header that we get on the response
let headerHashBeforeFirstHeaderRecived = reverseHash(firstHeaderRecived.prevHash.toString('hex'));
if (headerHashBeforeFirstHeaderRecived === headerHashRequested){
return true;
}
else{
return false;
}
}
pool.on('peerheaders', function(peer, message) {
let lastHeaderHashRequested;
if (validHeaders[validHeaders.length -1]) {
lastHeaderHashRequested = validHeaders[validHeaders.length -1].hash;
}
else {
lastHeaderHashRequested = firsHeader;
}
if (isValidResponse(message.headers[0], lastHeaderHashRequested) && headers.length === 0) {
headers.push({
peer: peer,
message: message,
});
console.log('Recived from: ', peer.host, message.headers.length, 'headers');
console.log('The first block hash is', message.headers[0].hash);
console.log('The last block hash is', message.headers[message.headers.length - 1].hash);
syncronize.next();
//console.log(syncronize)
}
});
function* sync(lastHash) {
let startHash = new Buffer(lastHash, 'hex');
let message = new Messages({network: NetworksData[network]}).GetHeaders();
// require as much as possible headers after startHash
message.starts.push(startHash);
pool.sendMessage(message);
yield;
validHeaders.push(...headers[0].message.headers);
headers = [];
let lastDownloadedHeader = validHeaders[validHeaders.length - 1];
if (validHeaders.length % 2000 === 0) {
yield * sync(reverseHash(lastDownloadedHeader.hash));
}
}
syncronize = sync(reverseHash(firsHeader));
// Wait for pool to connect
setTimeout(function(){
console.log(pool);
syncronize.next();
}, 5000);