Skip to content

Commit

Permalink
net/chain: fetch block from network if not found (for pruned nodes)
Browse files Browse the repository at this point in the history
FOR EDUCATIONAL PURPOSES ONLY. Do not merge.
  • Loading branch information
pinheadmz committed Jun 1, 2020
1 parent 6beb54d commit ec1f5c9
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
34 changes: 31 additions & 3 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ class Chain extends AsyncEmitter {

this.orphanMap = new BufferMap();
this.orphanPrev = new BufferMap();

this.getPrunedMap = new BufferMap();
}

/**
Expand Down Expand Up @@ -1371,7 +1373,16 @@ class Chain extends AsyncEmitter {
}

// Do we already have this block?
if (await this.hasEntry(hash)) {
const existingEntry = await this.getEntry(hash);

// FOR EDUCATIONAL PURPOSES ONLY: save block without checking anything
if (existingEntry && this.getPrunedMap.has(hash)) {
block = block.toBlock();
await this.db.save(existingEntry, block, new CoinView());
return existingEntry;
}

if (existingEntry) {
this.logger.debug('Already have block: %h.', block.hash());
throw new VerifyError(block, 'duplicate', 'duplicate', 0);
}
Expand Down Expand Up @@ -1924,8 +1935,25 @@ class Chain extends AsyncEmitter {
* @returns {Promise} - Returns {@link Block}.
*/

getBlock(hash) {
return this.db.getBlock(hash);
async getBlock(hash) {
const block = await this.db.getBlock(hash);
if (block) {
return block;
} else {
this.logger.warning('Block not found, attempting to download');

// Ensure hash not height
hash = await this.db.getHash(hash);

// FOR EDUCATIONAL PURPOSES ONLY: flag block for re-downloading
const wait = new Promise((resolve, reject) => {
this.getPrunedMap.set(hash, resolve);
});

await this.emitAsync('getprunedblock', hash);
await wait;
return this.db.getBlock(hash);
}
}

/**
Expand Down
18 changes: 18 additions & 0 deletions lib/net/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ class Pool extends EventEmitter {
this.handleBadOrphan('block', err, id);
});

this.chain.on('getprunedblock', async (hash) => {
// Find the first peer with a completed handshake
for (let peer = this.peers.head(); peer; peer = peer.next) {
if (!peer.handshake)
continue;

await this.getBlock(peer, [hash]);
}
});

if (this.mempool) {
this.mempool.on('tx', (tx) => {
this.emit('tx', tx);
Expand Down Expand Up @@ -2184,6 +2194,14 @@ class Pool extends EventEmitter {
throw err;
}

// Someone was waiting for a pruned block to download
const resolve = this.chain.getPrunedMap.get(hash);
if (resolve) {
this.logger.warning('Received pruned block by special request');
this.chain.getPrunedMap.delete(hash);
resolve();
}

// Block was orphaned.
if (!entry) {
if (this.checkpoints) {
Expand Down

0 comments on commit ec1f5c9

Please sign in to comment.