Skip to content

Commit

Permalink
feat<node>: Added getblockpeer
Browse files Browse the repository at this point in the history
  • Loading branch information
manavdesai27 committed Jul 20, 2023
1 parent a4bf281 commit 9064032
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 8 deletions.
47 changes: 46 additions & 1 deletion 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 @@ -1368,7 +1370,17 @@ class Chain extends AsyncEmitter {
}

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

if (existingEntry && this.getPrunedMap.has(hash)) {
block = block.toBlock();
await this.db.updateNeutrinoSave();
await this.db.save(existingEntry, block, new CoinView());
await this.db.updateNeutrinoSave();
return existingEntry;

Check warning on line 1380 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1376-L1380

Added lines #L1376 - L1380 were not covered by tests
}

if (existingEntry) {
this.logger.debug('Already have block: %h.', block.hash());
throw new VerifyError(block, 'duplicate', 'duplicate', 0);
}
Expand Down Expand Up @@ -1925,6 +1937,33 @@ class Chain extends AsyncEmitter {
return this.db.getBlock(hash);
}

async getBlockPeer(hash) {
let block = await this.db.getBlock(hash);
if (block) {
const entry = await this.getEntry(hash);
assert(entry.hash.equals(hash));
return block;

Check warning on line 1945 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1941-L1945

Added lines #L1941 - L1945 were not covered by tests
} else {
this.logger.warning('Block not found, attempting to download');

Check warning on line 1947 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1947

Added line #L1947 was not covered by tests

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

Check warning on line 1950 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1950

Added line #L1950 was not covered by tests

const wait = new Promise((resolve, reject) => {
this.getPrunedMap.set(hash, resolve);

Check warning on line 1953 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1952-L1953

Added lines #L1952 - L1953 were not covered by tests
});

await this.emitAsync('getprunedblock', hash);
await wait;
block = await this.db.getBlock(hash);
const entry = await this.getEntry(hash);
assert(entry.hash.equals(hash));

Check warning on line 1960 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1956-L1960

Added lines #L1956 - L1960 were not covered by tests

this.emit('getblockpeer', entry, block);
return block;

Check warning on line 1963 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L1962-L1963

Added lines #L1962 - L1963 were not covered by tests
}
}

/**
* Retrieve a block from the database (not filled with coins).
* @param {Hash} block
Expand Down Expand Up @@ -2616,6 +2655,7 @@ class ChainOptions {
this.compression = true;

this.spv = false;
this.neutrino = false;
this.bip91 = false;
this.bip148 = false;
this.prune = false;
Expand Down Expand Up @@ -2662,6 +2702,11 @@ class ChainOptions {
this.spv = options.spv;
}

if (options.neutrino != null) {
assert(typeof options.neutrino === 'boolean');
this.neutrino = options.neutrino;

Check warning on line 2707 in lib/blockchain/chain.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chain.js#L2706-L2707

Added lines #L2706 - L2707 were not covered by tests
}

if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
Expand Down
12 changes: 10 additions & 2 deletions lib/blockchain/chaindb.js
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ class ChainDB {
*/

async getRawBlock(block) {
if (this.options.spv)
if (this.options.spv && !this.options.neutrino)
return null;

const hash = await this.getHash(block);
Expand Down Expand Up @@ -1150,6 +1150,14 @@ class ChainDB {
* @returns {Promise}
*/

async updateNeutrinoSave () {
if (this.neutrinoSave) {
this.neutrinoSave = false;

Check warning on line 1155 in lib/blockchain/chaindb.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chaindb.js#L1154-L1155

Added lines #L1154 - L1155 were not covered by tests
} else {
this.neutrinoSave = true;

Check warning on line 1157 in lib/blockchain/chaindb.js

View check run for this annotation

Codecov / codecov/patch

lib/blockchain/chaindb.js#L1157

Added line #L1157 was not covered by tests
}
}

async save(entry, block, view) {
this.start();
try {
Expand Down Expand Up @@ -1478,7 +1486,7 @@ class ChainDB {
async saveBlock(entry, block, view) {
const hash = block.hash();

if (this.options.spv)
if (this.options.spv && !this.neutrinoSave)
return;

// Write actual block data.
Expand Down
5 changes: 2 additions & 3 deletions lib/client/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,8 @@ class NodeClient extends Client {
* @returns {Promise}
*/

getFilter(filter) {
assert(typeof filter === 'string' || typeof filter === 'number');
return this.get(`/filter/${filter}`);
getBlockPeer(hash) {
return this.call('get block peer', hash);

Check warning on line 168 in lib/client/node.js

View check run for this annotation

Codecov / codecov/patch

lib/client/node.js#L168

Added line #L168 was not covered by tests
}

/**
Expand Down
34 changes: 32 additions & 2 deletions lib/net/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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;

Check warning on line 148 in lib/net/pool.js

View check run for this annotation

Codecov / codecov/patch

lib/net/pool.js#L146-L148

Added lines #L146 - L148 were not covered by tests

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

Check warning on line 150 in lib/net/pool.js

View check run for this annotation

Codecov / codecov/patch

lib/net/pool.js#L150

Added line #L150 was not covered by tests
}
});

if (this.mempool) {
this.mempool.on('tx', (tx) => {
this.emit('tx', tx);
Expand Down Expand Up @@ -2293,7 +2303,7 @@ class Pool extends EventEmitter {

const hash = block.hash();

if (!this.resolveBlock(peer, hash)) {
if (!this.options.neutrino && !this.resolveBlock(peer, hash)) {
this.logger.warning(
'Received unrequested block: %h (%s).',
block.hash(), peer.hostname());
Expand All @@ -2316,6 +2326,14 @@ class Pool extends EventEmitter {
}

// Block was orphaned.

const resolve = this.chain.getPrunedMap.get(hash);
if (resolve) {
this.logger.warning('Received pruned block by special request');
this.chain.getPrunedMap.delete(hash);
resolve();

Check warning on line 2334 in lib/net/pool.js

View check run for this annotation

Codecov / codecov/patch

lib/net/pool.js#L2332-L2334

Added lines #L2332 - L2334 were not covered by tests
}

if (!entry) {
if (this.checkpoints) {
this.logger.warning(
Expand Down Expand Up @@ -3690,6 +3708,7 @@ class PoolOptions {
this.prefix = null;
this.checkpoints = true;
this.spv = false;
this.neutrino = false;
this.bip37 = false;
this.bip157 = false;
this.listen = false;
Expand Down Expand Up @@ -3772,12 +3791,17 @@ class PoolOptions {

if (options.spv != null) {
assert(typeof options.spv === 'boolean');
assert(options.spv === this.chain.options.spv);
this.spv = options.spv;
} else {
this.spv = this.chain.options.spv;
}

if (options.neutrino != null) {
assert(options.compact !== true);
assert(typeof options.neutrino === 'boolean');
this.neutrino = options.neutrino;

Check warning on line 3802 in lib/net/pool.js

View check run for this annotation

Codecov / codecov/patch

lib/net/pool.js#L3800-L3802

Added lines #L3800 - L3802 were not covered by tests
}

if (options.bip37 != null) {
assert(typeof options.bip37 === 'boolean');
this.bip37 = options.bip37;
Expand Down Expand Up @@ -3953,6 +3977,12 @@ class PoolOptions {
this.listen = false;
}

if (this.neutrino) {
this.requiredServices |= common.services.NODE_COMPACT_FILTERS;
this.checkpoints = true;
this.compact = false;

Check warning on line 3983 in lib/net/pool.js

View check run for this annotation

Codecov / codecov/patch

lib/net/pool.js#L3981-L3983

Added lines #L3981 - L3983 were not covered by tests
}

if (this.selfish) {
this.services &= ~common.services.NETWORK;
this.bip37 = false;
Expand Down
6 changes: 6 additions & 0 deletions lib/node/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ class HTTP extends Server {
return null;
});

socket.hook('get block peer', (...args) => {
const valid = new Validator(args);
const hash = valid.hash(0);
return this.chain.getBlockPeer(hash);

Check warning on line 504 in lib/node/http.js

View check run for this annotation

Codecov / codecov/patch

lib/node/http.js#L502-L504

Added lines #L502 - L504 were not covered by tests
});

socket.hook('estimate fee', (...args) => {
const valid = new Validator(args);
const blocks = valid.u32(0);
Expand Down
11 changes: 11 additions & 0 deletions lib/wallet/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ class WalletClient extends NodeClient {
return super.setFilter(filter.toRaw());
}

/**
* Check filter against wallet key ring
* @param {WalletKey} ring
* @param {Filter} filter
* @returns {Promise}
*/

async getBlockFromNode(hash) {
return super.getBlockPeer(hash);

Check warning on line 82 in lib/wallet/client.js

View check run for this annotation

Codecov / codecov/patch

lib/wallet/client.js#L82

Added line #L82 was not covered by tests
}

async rescan(start) {
if (Buffer.isBuffer(start))
start = util.revHex(start);
Expand Down
11 changes: 11 additions & 0 deletions lib/wallet/nodeclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ class NodeClient extends AsyncEmitter {

init() {
this.node.chain.on('connect', async (entry, block) => {
if (!this.opened || this.node.neutrino)
return;

Check warning on line 41 in lib/wallet/nodeclient.js

View check run for this annotation

Codecov / codecov/patch

lib/wallet/nodeclient.js#L41

Added line #L41 was not covered by tests

await this.emitAsync('block connect', entry, block.txs);
});

this.node.chain.on('getblockpeer', async (entry, block) => {
if (!this.opened)
return;

Expand Down Expand Up @@ -134,6 +141,10 @@ class NodeClient extends AsyncEmitter {
return entry;
}

async getBlockFromNode(hash) {
await this.node.chain.getBlockPeer(hash);

Check warning on line 145 in lib/wallet/nodeclient.js

View check run for this annotation

Codecov / codecov/patch

lib/wallet/nodeclient.js#L145

Added line #L145 was not covered by tests
}

/**
* Send a transaction. Do not wait for promise.
* @param {TX} tx
Expand Down
11 changes: 11 additions & 0 deletions lib/wallet/nullclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ class NullClient extends EventEmitter {
this.wdb.emit('reset filter');
}

/**
* Check filter against wallet key ring
* @param {WalletKey} ring
* @param {Filter} filter
* @returns {Promise}
*/

async getBlockFromNode(hash) {
;
}

/**
* Esimate smart fee.
* @param {Number?} blocks
Expand Down

0 comments on commit 9064032

Please sign in to comment.