Skip to content

Commit

Permalink
feat: added headers first sync
Browse files Browse the repository at this point in the history
  • Loading branch information
masterchief164 committed Jun 23, 2023
1 parent b005869 commit a45770d
Show file tree
Hide file tree
Showing 5 changed files with 399 additions and 16 deletions.
4 changes: 2 additions & 2 deletions bin/bcoin
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ for arg in "$@"; do
--daemon)
daemon=1
;;
--spv)
cmd='spvnode'
--spv)
cmd='spvnode'
;;
esac
done
Expand Down
16 changes: 12 additions & 4 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -2006,16 +2006,18 @@ class Chain extends AsyncEmitter {
if (this.options.checkpoints) {
if (this.height < this.network.lastCheckpoint)
return;
}

if (this.tip.time < util.now() - this.network.block.maxTipAge)
} else if (!this.options.neutrino &&
this.tip.time < util.now() - this.network.block.maxTipAge)
return;

if (!this.hasChainwork())
return;

this.synced = true;
this.emit('full');
if (this.options.neutrino)
this.emit('headersFull');
else
this.emit('full');
}

/**
Expand Down Expand Up @@ -2616,6 +2618,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 +2665,11 @@ class ChainOptions {
this.spv = options.spv;
}

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

if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
Expand Down
14 changes: 13 additions & 1 deletion lib/net/peer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1449,12 +1449,18 @@ class Peer extends EventEmitter {
if (!(this.services & services.NETWORK))
throw new Error('Peer does not support network services.');

if (this.options.neutrino) {
if (!(this.services & services.NODE_COMPACT_FILTERS)) {
throw new Error('Peer does not support Compact Filters.');
}
}

if (this.options.headers) {
if (this.version < common.HEADERS_VERSION)
throw new Error('Peer does not support getheaders.');
}

if (this.options.spv) {
if (this.options.spv && !this.options.neutrino) {
if (!(this.services & services.BLOOM))
throw new Error('Peer does not support BIP37.');

Expand Down Expand Up @@ -2080,6 +2086,7 @@ class PeerOptions {
this.agent = common.USER_AGENT;
this.noRelay = false;
this.spv = false;
this.neutrino = false;
this.compact = false;
this.headers = false;
this.banScore = common.BAN_SCORE;
Expand Down Expand Up @@ -2143,6 +2150,11 @@ class PeerOptions {
this.spv = options.spv;
}

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

if (options.compact != null) {
assert(typeof options.compact === 'boolean');
this.compact = options.compact;
Expand Down
80 changes: 71 additions & 9 deletions lib/net/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class Pool extends EventEmitter {
this.pendingRefill = null;

this.checkpoints = false;
this.neutrino = false;
this.headerChain = new List();
this.headerNext = null;
this.headerTip = null;
Expand Down Expand Up @@ -204,7 +205,7 @@ class Pool extends EventEmitter {
*/

resetChain() {
if (!this.options.checkpoints)
if (!this.options.checkpoints && !this.options.neutrino)
return;

this.checkpoints = false;
Expand All @@ -213,7 +214,10 @@ class Pool extends EventEmitter {
this.headerNext = null;

const tip = this.chain.tip;

if (this.options.neutrino) {
this.headerChain.push(new HeaderEntry(tip.hash, tip.height));
return;
}
if (tip.height < this.network.lastCheckpoint) {
this.checkpoints = true;
this.headerTip = this.getNextTip(tip.height);
Expand Down Expand Up @@ -650,7 +654,10 @@ class Pool extends EventEmitter {
return;

this.syncing = true;
this.resync(false);
if (this.options.neutrino) {
this.startHeadersSync();
} else
this.resync(false);
}

/**
Expand Down Expand Up @@ -704,6 +711,32 @@ class Pool extends EventEmitter {
this.compactBlocks.clear();
}

/**
* Start the headers sync using getHeaders messages.
* @private
* @return {Promise}
*/

async startHeadersSync() {
if (!this.syncing)
return;
let locator;
try {
locator = await this.chain.getLocator();
} catch (e) {
this.emit('error', e);
return;
}

const peer = this.peers.load;
if (!peer) {
this.logger.info('No loader peer.');
return;
}
this.chain.synced = false;
peer.sendGetHeaders(locator);
}

/**
* Send a sync to each peer.
* @private
Expand Down Expand Up @@ -814,7 +847,10 @@ class Pool extends EventEmitter {

peer.syncing = true;
peer.blockTime = Date.now();

if (this.options.neutrino) {
peer.sendGetHeaders(locator);
return true;
}
if (this.checkpoints) {
peer.sendGetHeaders(locator, this.headerTip.hash);
return true;
Expand Down Expand Up @@ -2027,6 +2063,9 @@ class Pool extends EventEmitter {
if (this.options.selfish)
return;

if (this.options.neutrino)
return;

if (this.chain.options.spv)
return;

Expand Down Expand Up @@ -2139,7 +2178,8 @@ class Pool extends EventEmitter {
async _handleHeaders(peer, packet) {
const headers = packet.items;

if (!this.checkpoints)
if (!this.checkpoints && !this.options.neutrino)
// todo add support for checkpoints
return;

if (!this.syncing)
Expand Down Expand Up @@ -2185,7 +2225,8 @@ class Pool extends EventEmitter {

node = new HeaderEntry(hash, height);

if (node.height === this.headerTip.height) {
if (!this.options.neutrino && node.height === this.headerTip.height) {
// todo add support for checkpoints
if (!node.hash.equals(this.headerTip.hash)) {
this.logger.warning(
'Peer sent an invalid checkpoint (%s).',
Expand All @@ -2200,6 +2241,8 @@ class Pool extends EventEmitter {
this.headerNext = node;

this.headerChain.push(node);
if (this.options.neutrino)
await this._addBlock(peer, header, chainCommon.flags.VERIFY_POW);
}

this.logger.debug(
Expand All @@ -2219,7 +2262,12 @@ class Pool extends EventEmitter {
}

// Request more headers.
peer.sendGetHeaders([node.hash], this.headerTip.hash);
if (this.chain.synced)
return;
if (this.options.neutrino)
peer.sendGetHeaders([node.hash]);
else
peer.sendGetHeaders([node.hash], this.headerTip.hash);
}

/**
Expand Down Expand Up @@ -2293,7 +2341,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 Down Expand Up @@ -3690,6 +3738,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 +3821,19 @@ class PoolOptions {

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

if (options.neutrino != null) {
assert(typeof options.neutrino === 'boolean');
this.neutrino = options.neutrino;
assert(options.compact === false ||
options.compact === undefined, 'We cannot use compact blocks');
}

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

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

if (this.selfish) {
this.services &= ~common.services.NETWORK;
this.bip37 = false;
Expand Down
Loading

0 comments on commit a45770d

Please sign in to comment.