Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added headers first sync #1156

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

masterchief164
Copy link
Collaborator

This PR adds support for headers first sync in neutrino mode.

@codecov
Copy link

codecov bot commented Jun 17, 2023

Codecov Report

Patch coverage: 81.06% and project coverage change: +0.25 🎉

Comparison is base (b005869) 69.55% compared to head (d213418) 69.81%.

❗ Current head d213418 differs from pull request most recent head 0d6615e. Consider uploading reports for the commit 0d6615e to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1156      +/-   ##
==========================================
+ Coverage   69.55%   69.81%   +0.25%     
==========================================
  Files         158      159       +1     
  Lines       26603    26725     +122     
==========================================
+ Hits        18505    18659     +154     
+ Misses       8098     8066      -32     
Impacted Files Coverage Δ
lib/net/pool.js 61.90% <79.59%> (+2.65%) ⬆️
lib/node/neutrino.js 80.88% <80.88%> (ø)
lib/net/peer.js 72.58% <85.71%> (+1.38%) ⬆️
lib/blockchain/chain.js 73.50% <87.50%> (+0.16%) ⬆️

... and 4 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@pinheadmz pinheadmz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left quite a few comments already but I wasn't sure if I was leading you astray or not, so I took a swing a branch myself: https://github.com/pinheadmz/bcoin/commits/neutrino-mz

Let's talk about it on the call this week

bin/bcoin Outdated Show resolved Hide resolved
lib/blockchain/chain.js Outdated Show resolved Hide resolved
return;

if (!this.hasChainwork())
return;

this.synced = true;
this.emit('full');
if (this.options.neutrino)
this.emit('headersFull');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we usually use spaces for event strings if its more than one word

Suggested change
this.emit('headersFull');
this.emit('headers full');

@@ -2616,6 +2618,7 @@ class ChainOptions {
this.compression = true;

this.spv = false;
this.neutrino = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think we can live without a neutrino mode in chain. It really is more of a pool option, and then in node/neutrino we can set pool.neutrino along with chain.spv and that should work

lib/net/pool.js Outdated
Comment on lines 217 to 220
if (this.options.neutrino) {
this.headerChain.push(new HeaderEntry(tip.hash, tip.height));
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to return early like this in neutrino mode? It doesn't finish resetting the headers chain

lib/net/pool.js Outdated
* @return {Promise}
*/

async startHeadersSync() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see if we can delete this function

lib/net/pool.js Outdated
return;
}

node = new HeaderEntry(hash, height);

if (node.height === this.headerTip.height) {
if (!this.options.neutrino && node.height === this.headerTip.height) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this necessary? It looks like the checkpoints-headers chain is getting mixed up with neutrino maybe we should chat about it on the weekly call. We might just be able to ignore the in memory headers chain in pool and just let it continue to do its thing with the one difference that we save the headers to disk throughout sync.

lib/net/pool.js Outdated
this.headerChain.shift();
this.resolveHeaders(peer);
return;
}

// Request more headers.
peer.sendGetHeaders([node.hash], this.headerTip.hash);
if (this.chain.synced)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any harm in just sending the request anyway even if we think we are synced?

lib/net/pool.js Outdated
@@ -2293,7 +2346,7 @@ class Pool extends EventEmitter {

const hash = block.hash();

if (!this.resolveBlock(peer, hash)) {
if (!this.options.neutrino && !this.resolveBlock(peer, hash)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we never add blocks to blockMap I wonder if it might be cleaner to just add if neutrino return at the top of resolveBlock()?

lib/net/pool.js Outdated
if (options.neutrino != null) {
assert(typeof options.neutrino === 'boolean');
this.neutrino = options.neutrino;
assert(options.compact === false ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this just assert !options.compactor am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants