Skip to content

Commit 8e0bec0

Browse files
committed
feat<cli>: added filterheader
1 parent 62dfdbd commit 8e0bec0

File tree

7 files changed

+74
-40
lines changed

7 files changed

+74
-40
lines changed

bin/bcoin-cli

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,22 @@ class CLI {
129129
this.log(filter);
130130
}
131131

132+
async getFilterHeader() {
133+
let hash = this.config.str(0, '');
134+
135+
if (hash.length !== 64)
136+
hash = parseInt(hash, 10);
137+
138+
const filterHeader = await this.client.getFilterHeader(hash);
139+
140+
if (!filterHeader) {
141+
this.log('Filter header not found.');
142+
return;
143+
}
144+
145+
this.log(filterHeader);
146+
}
147+
132148
async estimateFee() {
133149
const blocks = this.config.uint(0, 1);
134150

@@ -246,6 +262,9 @@ class CLI {
246262
case 'filter':
247263
await this.getFilter();
248264
break;
265+
case 'filterheader':
266+
await this.getFilterHeader();
267+
break;
249268
case 'fee':
250269
await this.estimateFee();
251270
break;
@@ -263,6 +282,7 @@ class CLI {
263282
this.log(' $ coin [hash+index/address]: View coins.');
264283
this.log(' $ fee [target]: Estimate smart fee.');
265284
this.log(' $ filter [hash/height]: View filter.');
285+
this.log(' $ filterheader [hash/height]: View filter header.');
266286
this.log(' $ header [hash/height]: View block header.');
267287
this.log(' $ info: Get server info.');
268288
this.log(' $ mempool: Get mempool snapshot.');

bin/neutrino

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ console.log('Starting bcoin');
66
process.title = 'bcoin';
77
const Neutrino = require('../lib/node/neutrino');
88

9-
// Doubt in db
109
const node = new Neutrino({
1110
file: true,
1211
argv: true,
1312
env: true,
1413
logFile: true,
15-
logConsole: true,
16-
logLevel: 'debug',
14+
logConsole: true, // todo: remove
15+
logLevel: 'debug', // todo: remove
1716
db: 'leveldb',
1817
memory: false,
1918
workers: true,

lib/blockchain/chain.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,14 +2060,12 @@ class Chain extends AsyncEmitter {
20602060
if (this.synced)
20612061
return;
20622062

2063+
if (this.options.neutrino && this.getProgress() < 1)
2064+
return;
20632065
if (this.options.checkpoints) {
20642066
if (this.height < this.network.lastCheckpoint)
20652067
return;
2066-
}
2067-
if (this.options.neutrino && this.tip.time < 1686851917)
2068-
// TODO change this later
2069-
return;
2070-
else if (!this.options.neutrino &&
2068+
} else if (!this.options.neutrino &&
20712069
this.tip.time < util.now() - this.network.block.maxTipAge)
20722070
return;
20732071

@@ -2701,7 +2699,8 @@ class ChainOptions {
27012699

27022700
fromOptions(options) {
27032701
if (!options.spv) {
2704-
assert(options.blocks && typeof options.blocks === 'object');
2702+
assert(options.blocks && typeof options.blocks === 'object',
2703+
'Chain requires a blockstore.');
27052704
}
27062705

27072706
this.blocks = options.blocks;

lib/client/node.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,14 @@ class NodeClient extends Client {
164164
* @returns {Promise}
165165
*/
166166

167-
getFilter(filter) {
168-
assert(typeof filter === 'string' || typeof filter === 'number');
169-
return this.get(`/filter/${filter}`);
167+
getFilter(block) {
168+
assert(typeof block === 'string' || typeof block === 'number');
169+
return this.get(`/filter/${block}`);
170+
}
171+
172+
getFilterHeader(block) {
173+
assert(typeof block === 'string' || typeof block === 'number');
174+
return this.get(`/filterheader/${block}`);
170175
}
171176

172177
getBlockPeer(hash) {

lib/net/peer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1466,7 +1466,7 @@ class Peer extends EventEmitter {
14661466
throw new Error('Peer does not support getheaders.');
14671467
}
14681468

1469-
if (this.options.spv && !this.options.neutrino) {
1469+
if (this.options.spv) {
14701470
if (!(this.services & services.BLOOM))
14711471
throw new Error('Peer does not support BIP37.');
14721472

lib/net/pool.js

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ class Pool extends EventEmitter {
6969
this.connected = false;
7070
this.disconnecting = false;
7171
this.syncing = false;
72-
this.filterSyncing = false;
7372
this.discovering = false;
7473
this.spvFilter = null;
7574
this.txFilter = null;
@@ -81,7 +80,6 @@ class Pool extends EventEmitter {
8180
this.pendingRefill = null;
8281

8382
this.checkpoints = false;
84-
this.neutrino = false;
8583
this.headerChain = new List();
8684
this.headerNext = null;
8785
this.headerTip = null;
@@ -90,10 +88,9 @@ class Pool extends EventEmitter {
9088
this.hosts = new HostList(this.options);
9189
this.id = 0;
9290

93-
this.getcfheadersStopHash = null;
9491
this.requestedFilterType = null;
9592
this.getcfiltersStartHeight = null;
96-
this.getcfiltersStopHash = null;
93+
this.requestedStopHash = null;
9794

9895
if (this.options.spv) {
9996
this.spvFilter = BloomFilter.fromRate(
@@ -740,7 +737,6 @@ class Pool extends EventEmitter {
740737
if (!this.opened || !this.connected)
741738
return;
742739

743-
this.filterSyncing = true;
744740
const cFHeaderHeight = await this.chain.getCFHeaderHeight();
745741
const startHeight = cFHeaderHeight
746742
? cFHeaderHeight + 1 : 1;
@@ -749,7 +745,7 @@ class Pool extends EventEmitter {
749745
? 2000 : chainHeight;
750746
const stopHash = await this.chain.getHash(stopHeight);
751747
this.requestedFilterType = common.FILTERS.BASIC;
752-
this.getcfheadersStopHash = stopHash;
748+
this.requestedStopHash = stopHash;
753749
await this.peers.load.sendGetCFHeaders(
754750
common.FILTERS.BASIC,
755751
startHeight,
@@ -766,7 +762,6 @@ class Pool extends EventEmitter {
766762
if (!this.opened || !this.connected)
767763
return;
768764

769-
this.filterSyncing = true;
770765
const cFilterHeight = await this.chain.getCFilterHeight();
771766
const startHeight = cFilterHeight
772767
? cFilterHeight + 1 : 1;
@@ -776,7 +771,7 @@ class Pool extends EventEmitter {
776771
const stopHash = await this.chain.getHash(stopHeight);
777772
this.requestedFilterType = common.FILTERS.BASIC;
778773
this.getcfiltersStartHeight = startHeight;
779-
this.getcfiltersStopHash = stopHash;
774+
this.requestedStopHash = stopHash;
780775
await this.peers.load.sendGetCFilters(
781776
common.FILTERS.BASIC,
782777
startHeight,
@@ -899,17 +894,6 @@ class Pool extends EventEmitter {
899894
return this.sendLocator(locator, peer);
900895
}
901896

902-
// /**
903-
// * Sync the filter headers from peer.
904-
// * @method
905-
// * @param {Peer} peer
906-
// * @returns {void}
907-
// */
908-
//
909-
// syncCompactFiltersCheckPt(peer) {
910-
// peer.sendGetCFCheckpt(common.FILTERS.BASIC, this.chain.tip.hash);
911-
// }
912-
913897
/**
914898
* Send a chain locator and start syncing from peer.
915899
* @method
@@ -1762,7 +1746,9 @@ class Pool extends EventEmitter {
17621746
return;
17631747

17641748
if (this.options.neutrino) {
1765-
this.startSync();
1749+
const filterHeight = await this.chain.getCFilterHeight();
1750+
if (filterHeight === this.chain.height)
1751+
this.startSync();
17661752
return;
17671753
}
17681754

@@ -1830,6 +1816,8 @@ class Pool extends EventEmitter {
18301816
*/
18311817

18321818
async handleTXInv(peer, hashes) {
1819+
if (this.options.neutrino)
1820+
return;
18331821
assert(hashes.length > 0);
18341822

18351823
if (this.syncing && !this.chain.synced)
@@ -2178,13 +2166,15 @@ class Pool extends EventEmitter {
21782166
const filterType = packet.filterType;
21792167

21802168
if (filterType !== this.requestedFilterType) {
2169+
this.logger.warning('Received CFHeaders packet with wrong filterType');
21812170
peer.ban();
21822171
peer.destroy();
21832172
return;
21842173
}
21852174

21862175
const stopHash = packet.stopHash;
2187-
if (!stopHash.equals(this.getcfheadersStopHash)) {
2176+
if (!stopHash.equals(this.requestedStopHash)) {
2177+
this.logger.warning('Received CFHeaders packet with wrong stopHash');
21882178
peer.ban();
21892179
return;
21902180
}
@@ -2220,7 +2210,7 @@ class Pool extends EventEmitter {
22202210
const nextStopHeight = stopHeight + 2000 < this.chain.height
22212211
? stopHeight + 2000 : this.chain.height;
22222212
const nextStopHash = await this.chain.getHash(nextStopHeight);
2223-
this.getcfheadersStopHash = nextStopHash;
2213+
this.requestedStopHash = nextStopHash;
22242214
peer.sendGetCFHeaders(filterType, stopHeight + 1, nextStopHash);
22252215
}
22262216
}
@@ -2238,16 +2228,18 @@ class Pool extends EventEmitter {
22382228
const filter = packet.filterBytes;
22392229

22402230
if (filterType !== this.requestedFilterType) {
2231+
this.logger.warning('Received CFilter packet with wrong filterType');
22412232
peer.ban();
22422233
peer.destroy();
22432234
return;
22442235
}
22452236

22462237
const blockHeight = await this.chain.getHeight(blockHash);
2247-
const stopHeight = await this.chain.getHeight(this.getcfiltersStopHash);
2238+
const stopHeight = await this.chain.getHeight(this.requestedStopHash);
22482239

22492240
if (!(blockHeight >= this.getcfiltersStartHeight
22502241
&& blockHeight <= stopHeight)) {
2242+
this.logger.warning('Received CFilter packet with wrong blockHeight');
22512243
peer.ban();
22522244
return;
22532245
}
@@ -2271,7 +2263,7 @@ class Pool extends EventEmitter {
22712263
nextStopHeight = stopHeight + 1000;
22722264
const stopHash = await this.chain.getHash(nextStopHeight);
22732265
this.getcfiltersStartHeight = startHeight;
2274-
this.getcfiltersStopHash = stopHash;
2266+
this.requestedStopHash = stopHash;
22752267
this.peers.load.sendGetCFilters(
22762268
common.FILTERS.BASIC,
22772269
startHeight,
@@ -2281,7 +2273,7 @@ class Pool extends EventEmitter {
22812273
nextStopHeight = this.chain.height;
22822274
const stopHash = await this.chain.getHash(nextStopHeight);
22832275
this.getcfiltersStartHeight = startHeight;
2284-
this.getcfiltersStopHash = stopHash;
2276+
this.requestedStopHash = stopHash;
22852277
this.peers.load.sendGetCFilters(
22862278
common.FILTERS.BASIC,
22872279
startHeight,
@@ -2290,7 +2282,7 @@ class Pool extends EventEmitter {
22902282
return;
22912283
}
22922284
} else if (cFilterHeight === this.chain.height) {
2293-
this.logger.info('CFilters sync complete');
2285+
this.chain.emit('full');
22942286
}
22952287
}
22962288

lib/node/http.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ class HTTP extends Server {
291291

292292
enforce(hash != null, 'Hash or height required.');
293293

294-
const filter = await this.node.getBlockFilter(hash);
294+
const filterName = valid.str(1, 'BASIC').toUpperCase();
295+
const filter = await this.node.getBlockFilter(hash, filterName);
295296

296297
if (!filter) {
297298
res.json(404);
@@ -301,6 +302,24 @@ class HTTP extends Server {
301302
res.json(200, filter.toJSON());
302303
});
303304

305+
this.get('/filterheader/:block', async (req, res) => {
306+
const valid = Validator.fromRequest(req);
307+
const hash = valid.uintbrhash('block');
308+
309+
enforce(hash != null, 'Hash or height required.');
310+
311+
const filterName = valid.str(1, 'BASIC').toUpperCase();
312+
const filterHeader = await this.node.
313+
getBlockFilterHeader(hash, filterName);
314+
315+
if (!filterHeader) {
316+
res.json(404);
317+
return;
318+
}
319+
320+
res.json(200, filterHeader.toJSON());
321+
});
322+
304323
// Mempool snapshot
305324
this.get('/mempool', async (req, res) => {
306325
enforce(this.mempool, 'No mempool available.');

0 commit comments

Comments
 (0)