diff --git a/bin/bcoin b/bin/bcoin index 56842efa5..990d72f19 100755 --- a/bin/bcoin +++ b/bin/bcoin @@ -47,7 +47,7 @@ for arg in "$@"; do cmd='neutrino' ;; --spv) - cmd='spvnode' + cmd='spvnode' ;; esac done diff --git a/bin/neutrino b/bin/neutrino index d42ec71c0..7e0155348 100755 --- a/bin/neutrino +++ b/bin/neutrino @@ -30,10 +30,6 @@ if (!node.config.bool('no-wallet') && !node.has('walletdb')) { await node.open(); await node.connect(); node.startSync(); - - node.on("full", () => { - console.log("Full node"); - }); })().catch((err) => { console.error(err.stack); process.exit(1); diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 7a621183a..0a3f13339 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -585,7 +585,7 @@ class Chain extends AsyncEmitter { // UASF is now enforced (bip148) (mainnet-only). if (this.options.bip148 && this.network === Network.main) { if (witness !== thresholdStates.LOCKED_IN - && witness !== thresholdStates.ACTIVE) { + && witness !== thresholdStates.ACTIVE) { // The BIP148 MTP check is nonsensical in // that it includes the _current_ entry's // timestamp. This requires some hackery, @@ -1955,7 +1955,7 @@ class Chain extends AsyncEmitter { return this.db.getBlock(hash); } - async getBlockPeer(hash, filter) { + async getBlockPeer(hash) { let block = await this.db.getBlock(hash); if (block) { const entry = await this.getEntry(hash); @@ -2283,7 +2283,6 @@ class Chain extends AsyncEmitter { return pow.bits; while (prev.height !== 0 - && prev.height % pow.retargetInterval !== 0 && prev.bits === pow.bits) { const cache = this.getPrevCache(prev); @@ -2517,7 +2516,7 @@ class Chain extends AsyncEmitter { const state = await this.getState(prev, deployment); if (state === thresholdStates.LOCKED_IN - || state === thresholdStates.STARTED) { + || state === thresholdStates.STARTED) { version |= 1 << deployment.bit; } } @@ -2701,8 +2700,7 @@ class ChainOptions { fromOptions(options) { if (!options.spv) { - assert(options.blocks && typeof options.blocks === 'object', - 'Chain requires a blockstore.'); + assert(options.blocks && typeof options.blocks === 'object'); } this.blocks = options.blocks; diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index 78e2324ff..07f510096 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -670,10 +670,10 @@ class ChainDB { const deployment = this.network.byBit(bit); if (deployment - && start === deployment.startTime - && timeout === deployment.timeout - && threshold === deployment.threshold - && window === deployment.window) { + && start === deployment.startTime + && timeout === deployment.timeout + && threshold === deployment.threshold + && window === deployment.window) { continue; } diff --git a/lib/client/node.js b/lib/client/node.js index 96b5ac81f..5133abd0f 100644 --- a/lib/client/node.js +++ b/lib/client/node.js @@ -169,8 +169,8 @@ class NodeClient extends Client { return this.get(`/filter/${filter}`); } - getBlockPeer(hash, filter) { - return this.call('get block peer', hash, filter); + getBlockPeer(hash) { + return this.call('get block peer', hash); } /** diff --git a/lib/net/pool.js b/lib/net/pool.js index a400c8933..dbbb2518c 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -81,7 +81,7 @@ class Pool extends EventEmitter { this.pendingRefill = null; this.checkpoints = false; - this.neutrino = this.options.neutrino; + this.neutrino = false; this.headerChain = new List(); this.headerNext = null; this.headerTip = null; @@ -90,9 +90,8 @@ class Pool extends EventEmitter { this.hosts = new HostList(this.options); this.id = 0; - this.getcfheadersFilterType = null; this.getcfheadersStopHash = null; - this.getcfiltersFilterType = null; + this.requestedFilterType = null; this.getcfiltersStartHeight = null; this.getcfiltersStopHash = null; @@ -749,7 +748,7 @@ class Pool extends EventEmitter { const stopHeight = chainHeight - startHeight + 1 > 2000 ? 2000 : chainHeight; const stopHash = await this.chain.getHash(stopHeight); - this.getcfheadersFilterType = common.FILTERS.BASIC; + this.requestedFilterType = common.FILTERS.BASIC; this.getcfheadersStopHash = stopHash; await this.peers.load.sendGetCFHeaders( common.FILTERS.BASIC, @@ -775,7 +774,7 @@ class Pool extends EventEmitter { const stopHeight = chainHeight - startHeight + 1 > 1000 ? 1000 : chainHeight; const stopHash = await this.chain.getHash(stopHeight); - this.getcfiltersFilterType = common.FILTERS.BASIC; + this.requestedFilterType = common.FILTERS.BASIC; this.getcfiltersStartHeight = startHeight; this.getcfiltersStopHash = stopHash; await this.peers.load.sendGetCFilters( @@ -1419,7 +1418,7 @@ class Pool extends EventEmitter { } // We want compact blocks! - if (this.options.compact && !this.options.neutrino) + if (this.options.compact) peer.sendCompact(this.options.blockMode); // Find some more peers. @@ -1762,7 +1761,7 @@ class Pool extends EventEmitter { if (this.options.hasWitness() && !peer.hasWitness()) return; - if (this.neutrino) { + if (this.options.neutrino) { this.startSync(); return; } @@ -2178,21 +2177,27 @@ class Pool extends EventEmitter { const filterType = packet.filterType; - if (filterType !== this.getcfheadersFilterType) { + if (filterType !== this.requestedFilterType) { peer.ban(); peer.destroy(); return; } const stopHash = packet.stopHash; - assert(stopHash.equals(this.getcfheadersStopHash)); + if (!stopHash.equals(this.getcfheadersStopHash)) { + peer.ban(); + return; + } let previousFilterHeader = packet.previousFilterHeader; const filterHashes = packet.filterHashes; let blockHeight = await this.chain.getHeight(stopHash) - filterHashes.length + 1; const stopHeight = await this.chain.getHeight(stopHash); for (const filterHash of filterHashes) { - assert(blockHeight <= stopHeight); + if (blockHeight > stopHeight) { + peer.ban(); + return; + } const basicFilter = new BasicFilter(); basicFilter._hash = filterHash; const filterHeader = basicFilter.header(previousFilterHeader); @@ -2232,7 +2237,7 @@ class Pool extends EventEmitter { const filterType = packet.filterType; const filter = packet.filterBytes; - if (filterType !== this.getcfheadersFilterType) { + if (filterType !== this.requestedFilterType) { peer.ban(); peer.destroy(); return; @@ -2241,8 +2246,11 @@ class Pool extends EventEmitter { const blockHeight = await this.chain.getHeight(blockHash); const stopHeight = await this.chain.getHeight(this.getcfiltersStopHash); - assert(blockHeight >= this.getcfiltersStartHeight - && blockHeight <= stopHeight); + if (!(blockHeight >= this.getcfiltersStartHeight + && blockHeight <= stopHeight)) { + peer.ban(); + return; + } const basicFilter = new BasicFilter(); const gcsFilter = basicFilter.fromNBytes(filter); @@ -2543,11 +2551,6 @@ class Pool extends EventEmitter { await this.addBlock(peer, packet.block, flags); } - async handleFilter(peer, packet) { - const flags = chainCommon.flags.DEFAULT_FLAGS; - await this.addFilter(peer, packet.filter, flags); - } - /** * Attempt to add block to chain. * @method @@ -2652,20 +2655,6 @@ class Pool extends EventEmitter { await this.resolveChain(peer, hash); } - async addFilter(peer, filter, flags) { - const hash = filter.hash(); - const unlock = await this.locker.lock(hash); - try { - return await this._addFilter(peer, filter, flags); - } finally { - unlock(); - } - } - - async _addFilter(peer, filter, flags) { - - } - /** * Resolve header chain. * @method @@ -4086,13 +4075,13 @@ 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; } diff --git a/lib/node/fullnode.js b/lib/node/fullnode.js index 035d62dea..928a3756d 100644 --- a/lib/node/fullnode.js +++ b/lib/node/fullnode.js @@ -645,50 +645,6 @@ class FullNode extends Node { return false; } - - /** - * Retrieve compact filter by hash/height. - * @param {Hash | Number} hash - * @param {Number} type - * @returns {Promise} - Returns {@link Buffer}. - */ - - async getBlockFilter(hash, filterType) { - const Indexer = this.filterIndexers.get(filterType); - - if (!Indexer) - return null; - - if (typeof hash === 'number') - hash = await this.chain.getHash(hash); - - if (!hash) - return null; - - return Indexer.getFilter(hash); - } - - /** - * Retrieve compact filter by hash/height. - * @param {Hash | Number} hash - * @param {Number} type - * @returns {Promise} - Returns {@link Buffer}. - */ - - async getBlockFilterHeader(hash, filterType) { - const Indexer = this.filterIndexers.get(filterType); - - if (!Indexer) - return null; - - if (typeof hash === 'number') - hash = await this.chain.getHash(hash); - - if (!hash) - return null; - - return Indexer.getFilterHeader(hash); - } } /* diff --git a/lib/node/http.js b/lib/node/http.js index bed31bf20..c8e8316fb 100644 --- a/lib/node/http.js +++ b/lib/node/http.js @@ -501,8 +501,7 @@ class HTTP extends Server { socket.hook('get block peer', (...args) => { const valid = new Validator(args); const hash = valid.hash(0); - const filter = valid.buf(1); - return this.pool.getBlockPeer(hash, filter); + return this.chain.getBlockPeer(hash); }); socket.hook('estimate fee', (...args) => { diff --git a/lib/node/neutrino.js b/lib/node/neutrino.js index b3570f69f..8077943f2 100644 --- a/lib/node/neutrino.js +++ b/lib/node/neutrino.js @@ -1,7 +1,7 @@ /*! * neutrino.js - spv node for bcoin - * Copyright (c) 2014-2015, Fedor Indutny (MIT License) - * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License). + * Copyright (c) 2023, Manav Desai (MIT License) + * Copyright (c) 2023, Shaswat Gupta (MIT License). * https://github.com/bcoin-org/bcoin */ @@ -134,7 +134,6 @@ class Neutrino extends Node { */ init() { - console.log('Initializing Neutrino Node.'); // Bind to errors this.chain.on('error', err => this.error(err)); this.pool.on('error', err => this.error(err)); @@ -142,10 +141,6 @@ class Neutrino extends Node { if (this.http) this.http.on('error', err => this.error(err)); - this.pool.on('tx', (tx) => { - this.emit('tx', tx); - }); - this.chain.on('block', (block) => { this.emit('block', block); }); diff --git a/lib/node/node.js b/lib/node/node.js index 6ef9803fe..e2e20f453 100644 --- a/lib/node/node.js +++ b/lib/node/node.js @@ -413,6 +413,50 @@ class Node extends EventEmitter { await plugin.close(); } } + + /** + * Retrieve compact filter by hash/height. + * @param {Hash | Number} hash + * @param {Number} type + * @returns {Promise} - Returns {@link Buffer}. + */ + + async getBlockFilter(hash, filterType) { + const Indexer = this.filterIndexers.get(filterType); + + if (!Indexer) + return null; + + if (typeof hash === 'number') + hash = await this.chain.getHash(hash); + + if (!hash) + return null; + + return Indexer.getFilter(hash); + } + + /** + * Retrieve compact filter header by hash/height. + * @param {Hash | Number} hash + * @param {Number} type + * @returns {Promise} - Returns {@link Buffer}. + */ + + async getBlockFilterHeader(hash, filterType) { + const Indexer = this.filterIndexers.get(filterType); + + if (!Indexer) + return null; + + if (typeof hash === 'number') + hash = await this.chain.getHash(hash); + + if (!hash) + return null; + + return Indexer.getFilterHeader(hash); + } } /* diff --git a/lib/wallet/client.js b/lib/wallet/client.js index 6a9a12a77..b39d5bc33 100644 --- a/lib/wallet/client.js +++ b/lib/wallet/client.js @@ -78,8 +78,8 @@ class WalletClient extends NodeClient { * @returns {Promise} */ - async getBlockFromNode(hash, filter) { - return super.getBlockPeer(hash, filter); + async getBlockFromNode(hash) { + return super.getBlockPeer(hash); } async rescan(start) { diff --git a/lib/wallet/nodeclient.js b/lib/wallet/nodeclient.js index 64079d1f7..f33d7ba7d 100644 --- a/lib/wallet/nodeclient.js +++ b/lib/wallet/nodeclient.js @@ -148,8 +148,8 @@ class NodeClient extends AsyncEmitter { return entry; } - async getBlockFromNode(hash, filter) { - await this.node.chain.getBlockPeer(hash, filter); + async getBlockFromNode(hash) { + await this.node.chain.getBlockPeer(hash); } /** diff --git a/lib/wallet/nullclient.js b/lib/wallet/nullclient.js index a6387fc30..f08ca5d6d 100644 --- a/lib/wallet/nullclient.js +++ b/lib/wallet/nullclient.js @@ -137,7 +137,7 @@ class NullClient extends EventEmitter { * @returns {Promise} */ - async getBlockFromNode(hash, filter) { + async getBlockFromNode(hash) { ; } diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 32bdb4b38..3703deaf9 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -59,8 +59,6 @@ class Wallet extends EventEmitter { this.writeLock = new Lock(); this.fundLock = new Lock(); - this.neutrino = false; - this.wid = 0; this.id = null; this.watchOnly = false; diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index b1b2c7c84..31ef5e04c 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -606,7 +606,7 @@ class WalletDB extends EventEmitter { const script = Script.fromAddress(address); const match = filter.match(gcsKey, script.toRaw()); if (match) { - await this.client.getBlockFromNode(blockHash, filter); + await this.client.getBlockFromNode(blockHash); return; } }); diff --git a/test/neutrino-test.js b/test/neutrino-test.js index 842fe2782..2a0562a69 100644 --- a/test/neutrino-test.js +++ b/test/neutrino-test.js @@ -13,6 +13,8 @@ describe('neutrino', function () { port: 10000, httpPort: 20000, neutrino: true, + logConsole: true, + logLevel: 'debug', only: '127.0.0.1' }); diff --git a/test/wallet-neutrino-test.js b/test/wallet-neutrino-test.js index 2ab783c62..bbbe38ff8 100644 --- a/test/wallet-neutrino-test.js +++ b/test/wallet-neutrino-test.js @@ -54,7 +54,6 @@ function parseAddress(raw, network) { describe('wallet-neutrino', function() { it('should open chain and miner', async () => { - miner.mempool = null; await node1.open(); await node2.open(); });