使用 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);