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 17, 2023
1 parent b005869 commit 94d5a97
Show file tree
Hide file tree
Showing 9 changed files with 458 additions and 16 deletions.
7 changes: 5 additions & 2 deletions bin/bcoin
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ for arg in "$@"; do
--daemon)
daemon=1
;;
--spv)
cmd='spvnode'
--neutrino)
cmd='neutrino'
;;
--spv)
cmd='spvnode'
;;
esac
done
Expand Down
45 changes: 45 additions & 0 deletions bin/neutrino
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env node

'use strict';

console.log('Starting bcoin');
process.title = 'bcoin';
const Neutrino = require('../lib/node/neutrino');
const Outpoint = require('../lib/primitives/outpoint');
const assert = require('assert');

// Doubt in db
const node = new Neutrino({
file: true,
argv: true,
env: true,
logFile: true,
logConsole: true,
logLevel: 'debug',
db: 'leveldb',
memory: false,
workers: true,
loader: require
});

(async () => {
await node.ensure();
await node.open();
await node.connect();
node.startSync();

node.on("full", () => {
console.log("Full node");
});
})().catch((err) => {
console.error(err.stack);
process.exit(1);
});

process.on('unhandledRejection', (err, promise) => {
throw err;
});

process.on('SIGINT', async () => {
await node.close();
});
1 change: 1 addition & 0 deletions lib/bcoin-browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ bcoin.node = require('./node');
bcoin.Node = require('./node/node');
bcoin.FullNode = require('./node/fullnode');
bcoin.SPVNode = require('./node/spvnode');
bcoin.Neutrino = require('./node/neutrino');

// Primitives
bcoin.primitives = require('./primitives');
Expand Down
1 change: 1 addition & 0 deletions lib/bcoin.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ bcoin.define('node', './node');
bcoin.define('Node', './node/node');
bcoin.define('FullNode', './node/fullnode');
bcoin.define('SPVNode', './node/spvnode');
bcoin.define('Neutrino', './node/neutrino');

// Primitives
bcoin.define('primitives', './primitives');
Expand Down
18 changes: 15 additions & 3 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -2007,15 +2007,21 @@ class Chain extends AsyncEmitter {
if (this.height < this.network.lastCheckpoint)
return;
}

if (this.tip.time < util.now() - this.network.block.maxTipAge)
if (this.options.neutrino && this.tip.time < 1686851917)
// TODO change this later
return;
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 +2622,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 +2669,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
82 changes: 73 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,34 @@ class Pool extends EventEmitter {
this.compactBlocks.clear();
}

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

async startHeadersSync() {
if (!this.syncing)
return;
console.log('startHeadersSync');
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);
// this.emit('headersFull');
}

/**
* Send a sync to each peer.
* @private
Expand Down Expand Up @@ -814,7 +849,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 +2065,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 +2180,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 +2227,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 +2243,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 +2264,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 +2343,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 +3740,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 +3823,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 +4011,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 94d5a97

Please sign in to comment.