more node improvements.
This commit is contained in:
parent
00b8f8950b
commit
45292df44d
@ -22,11 +22,6 @@ function BlockDB(node, options) {
|
||||
if (!(this instanceof BlockDB))
|
||||
return new BlockDB(node, options);
|
||||
|
||||
if (!(node instanceof bcoin.node)) {
|
||||
options = node;
|
||||
node = null;
|
||||
}
|
||||
|
||||
// Some lazy loading
|
||||
levelup = require('levelup');
|
||||
|
||||
@ -45,7 +40,7 @@ function BlockDB(node, options) {
|
||||
this.options = options;
|
||||
|
||||
this.node = node;
|
||||
this.data = new BlockData(options);
|
||||
this.data = new BlockData(node, this, options);
|
||||
|
||||
this.cache = {
|
||||
unspent: new bcoin.lru(32 * 1024 * 1024),
|
||||
@ -1039,13 +1034,15 @@ BlockDB.prototype._getEntry = function _getEntry(height, callback) {
|
||||
* BlockData
|
||||
*/
|
||||
|
||||
function BlockData(options) {
|
||||
function BlockData(node, blockdb, options) {
|
||||
if (!(this instanceof BlockData))
|
||||
return new BlockData(options);
|
||||
return new BlockData(node, blockdb, options);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
this.node = node;
|
||||
this.blockdb = blockdb;
|
||||
this.options = options;
|
||||
this.file = options.blockFile;
|
||||
|
||||
|
||||
@ -32,12 +32,12 @@ function Chain(node, options) {
|
||||
if (this.options.debug)
|
||||
bcoin.debug = this.options.debug;
|
||||
|
||||
this.db = new bcoin.chaindb(this);
|
||||
this.node = node;
|
||||
this.request = new utils.RequestCache();
|
||||
this.loading = false;
|
||||
this.node = node;
|
||||
this.mempool = node.mempool;
|
||||
this.blockdb = node.blockdb;
|
||||
this.db = new bcoin.chaindb(node, this);
|
||||
this.busy = false;
|
||||
this.jobs = [];
|
||||
this.pending = [];
|
||||
@ -132,17 +132,6 @@ Chain.prototype._init = function _init() {
|
||||
utils.debug('Warning: %d (%dmb) orphans cleared!', count, utils.mb(size));
|
||||
});
|
||||
|
||||
// Update the mempool.
|
||||
this.on('add block', function(block) {
|
||||
if (self.mempool)
|
||||
self.mempool.addBlock(block);
|
||||
});
|
||||
|
||||
this.on('remove block', function(block) {
|
||||
if (self.mempool)
|
||||
self.mempool.removeBlock(block);
|
||||
});
|
||||
|
||||
this.loading = true;
|
||||
|
||||
utils.debug('Chain is loading.');
|
||||
|
||||
@ -20,9 +20,9 @@ var BLOCK_SIZE = bcoin.chainblock.BLOCK_SIZE;
|
||||
* ChainDB
|
||||
*/
|
||||
|
||||
function ChainDB(chain, options) {
|
||||
function ChainDB(node, chain, options) {
|
||||
if (!(this instanceof ChainDB))
|
||||
return new ChainDB(chain, options);
|
||||
return new ChainDB(node, chain, options);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
@ -30,6 +30,8 @@ function ChainDB(chain, options) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.options = options;
|
||||
this.node = node;
|
||||
this.network = node.network;
|
||||
this.chain = chain;
|
||||
this.file = options.file;
|
||||
|
||||
|
||||
@ -60,7 +60,10 @@ HTTPServer.prototype._init = function _init() {
|
||||
});
|
||||
|
||||
this.get('/', function(req, res, next, send) {
|
||||
send(200, { version: require('../../package.json').version });
|
||||
send(200, {
|
||||
version: require('../../package.json').version,
|
||||
network: self.node.network.type
|
||||
});
|
||||
});
|
||||
|
||||
// UTXO by address
|
||||
|
||||
@ -28,17 +28,6 @@ function Fullnode(options) {
|
||||
|
||||
bcoin.node.call(this, options);
|
||||
|
||||
this.options.http = {};
|
||||
|
||||
if (!this.options.wallet)
|
||||
this.options.wallet = {};
|
||||
|
||||
if (!this.options.wallet.id)
|
||||
this.options.wallet.id = 'primary';
|
||||
|
||||
if (!this.options.wallet.passphrase)
|
||||
this.options.wallet.passphrase = 'node';
|
||||
|
||||
this.loading = false;
|
||||
|
||||
Fullnode.global = this;
|
||||
@ -50,35 +39,52 @@ utils.inherits(Fullnode, bcoin.node);
|
||||
|
||||
Fullnode.prototype._init = function _init() {
|
||||
var self = this;
|
||||
var pending = 3;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
// BlockDB and Mempool need to be instantiated
|
||||
// first because the chain needs access to them.
|
||||
// BlockDB technically needs access to the
|
||||
// chain, but that's only once it's being
|
||||
// used for tx retrieval.
|
||||
this.blockdb = new bcoin.blockdb(this, {
|
||||
cache: false
|
||||
});
|
||||
|
||||
this.mempool = new bcoin.mempool(this);
|
||||
// Mempool needs access to blockdb.
|
||||
this.mempool = new bcoin.mempool(this, {
|
||||
rbf: false
|
||||
});
|
||||
|
||||
// Chain is instantiated next. The pool needs it.
|
||||
// Chain needs access to blockdb.
|
||||
this.chain = new bcoin.chain(this, {
|
||||
preload: false
|
||||
});
|
||||
|
||||
// Pool needs access to the chain.
|
||||
this.pool = new bcoin.pool(this, {
|
||||
witness: this.network.type === 'segnet',
|
||||
spv: false
|
||||
});
|
||||
|
||||
this.miner = new bcoin.miner(this, this.options.miner);
|
||||
this.walletdb = new bcoin.walletdb(this, this.options.walletdb);
|
||||
// Miner needs access to the mempool.
|
||||
this.miner = new bcoin.miner(this, {
|
||||
address: this.options.payoutAddress,
|
||||
coinbaseFlags: this.options.coinbaseFlags
|
||||
});
|
||||
|
||||
if (this.options.http && bcoin.http) {
|
||||
this.http = new bcoin.http(this, this.options.http);
|
||||
this.http.listen(this.options.http.port || 8080);
|
||||
}
|
||||
// WalletDB needs access to the network type.
|
||||
this.walletdb = new bcoin.walletdb(this, {
|
||||
type: this.options.walletdb
|
||||
});
|
||||
|
||||
// HTTP needs access to the mempool
|
||||
// and blockdb.
|
||||
this.http = new bcoin.http(this, {
|
||||
key: this.options.httpKey,
|
||||
cert: this.options.httpCert
|
||||
});
|
||||
|
||||
// Bind to errors
|
||||
this.mempool.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
@ -87,15 +93,23 @@ Fullnode.prototype._init = function _init() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.chain.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
// Emit events for any TX we see that's
|
||||
// is relevant to one of our wallets.
|
||||
this.on('tx', function(tx) {
|
||||
self.walletdb.ownTX(tx, function(err, input, output) {
|
||||
if (err)
|
||||
return self.emit('error', err);
|
||||
|
||||
self.emit('own tx', tx, input, output);
|
||||
if (input || output)
|
||||
self.emit('wallet tx', tx, input || [], output || []);
|
||||
});
|
||||
});
|
||||
|
||||
// Emit events for valid blocks and TXs.
|
||||
this.chain.on('block', function(block) {
|
||||
self.emit('block', block);
|
||||
block.txs.forEach(function(tx) {
|
||||
@ -107,7 +121,17 @@ Fullnode.prototype._init = function _init() {
|
||||
self.emit('tx', tx);
|
||||
});
|
||||
|
||||
// Handle forks
|
||||
// Update the mempool.
|
||||
this.chain.on('add block', function(block) {
|
||||
self.mempool.addBlock(block);
|
||||
});
|
||||
|
||||
this.chain.on('remove block', function(block) {
|
||||
self.mempool.removeBlock(block);
|
||||
});
|
||||
|
||||
// Handle forks by unconfirming txs
|
||||
// in our wallets' tx pools.
|
||||
this.chain.on('remove entry', function(entry) {
|
||||
self.wallets.forEach(function(wallet) {
|
||||
wallet.tx.getAll().forEach(function(tx) {
|
||||
@ -117,16 +141,39 @@ Fullnode.prototype._init = function _init() {
|
||||
});
|
||||
});
|
||||
|
||||
this.createWallet(this.options.wallet, function(err, wallet) {
|
||||
function load() {
|
||||
if (!--pending) {
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
self.pool.startSync();
|
||||
utils.debug('Node is loaded and syncing.');
|
||||
}
|
||||
}
|
||||
|
||||
// Create or load the primary wallet.
|
||||
this.createWallet({ id: 'primary', passphrase: 'node' }, function(err, wallet) {
|
||||
if (err)
|
||||
throw err;
|
||||
|
||||
self.miner.address = wallet.getAddress();
|
||||
// Set the miner payout address if the
|
||||
// programmer didn't pass one in.
|
||||
if (!self.miner.address)
|
||||
self.miner.address = wallet.getAddress();
|
||||
|
||||
self.pool.startSync();
|
||||
wallet.on('load', function() {
|
||||
load();
|
||||
});
|
||||
});
|
||||
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
this.chain.once('load', function() {
|
||||
load();
|
||||
});
|
||||
|
||||
this.http.listen(this.options.httpPort || 8080, '0.0.0.0', function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
|
||||
load();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -28,9 +28,12 @@ function Node(options) {
|
||||
|
||||
this.options = options;
|
||||
|
||||
if (this.options.debug)
|
||||
if (this.options.debug != null)
|
||||
bcoin.debug = this.options.debug;
|
||||
|
||||
if (this.options.debugFile != null)
|
||||
bcoin.debugFile = this.options.debugFile;
|
||||
|
||||
if (this.options.network)
|
||||
network.set(this.options.network);
|
||||
|
||||
@ -40,6 +43,7 @@ function Node(options) {
|
||||
this.pool = null;
|
||||
this.chain = null;
|
||||
this.miner = null;
|
||||
this.profiler = null;
|
||||
this.wallets = [];
|
||||
|
||||
Node.global = this;
|
||||
|
||||
@ -30,12 +30,6 @@ function Pool(node, options) {
|
||||
|
||||
this.options = options;
|
||||
|
||||
if (options.debug)
|
||||
bcoin.debug = this.options.debug;
|
||||
|
||||
if (options.network)
|
||||
network.set(options.network);
|
||||
|
||||
options.spv = options.spv !== false;
|
||||
|
||||
if (options.type === 'spv')
|
||||
@ -48,6 +42,7 @@ function Pool(node, options) {
|
||||
? (!options.spv ? true : false)
|
||||
: options.relay;
|
||||
|
||||
this.network = node.network;
|
||||
this.originalSeeds = (options.seeds || network.seeds).map(utils.parseHost);
|
||||
this.setSeeds([]);
|
||||
|
||||
@ -152,6 +147,13 @@ function Pool(node, options) {
|
||||
|
||||
this.loading = true;
|
||||
|
||||
if (!this.chain.loading) {
|
||||
this.loading = false;
|
||||
this.emit('load');
|
||||
this._init();
|
||||
return;
|
||||
}
|
||||
|
||||
this.chain.once('load', function() {
|
||||
self.loading = false;
|
||||
self.emit('load');
|
||||
@ -1222,6 +1224,13 @@ Pool.prototype.addWallet = function addWallet(wallet, callback) {
|
||||
if (this.loading)
|
||||
return this.once('load', this.addWallet.bind(this, wallet, callback));
|
||||
|
||||
if (!this.options.spv) {
|
||||
wallet.getPending().forEach(function(tx) {
|
||||
self.sendTX(tx);
|
||||
});
|
||||
return utils.nextTick(callback);
|
||||
}
|
||||
|
||||
if (this.wallets.indexOf(wallet) !== -1)
|
||||
return false;
|
||||
|
||||
@ -1238,9 +1247,6 @@ Pool.prototype.addWallet = function addWallet(wallet, callback) {
|
||||
self.sendTX(tx);
|
||||
});
|
||||
|
||||
if (!self.options.spv)
|
||||
return callback();
|
||||
|
||||
if (self._pendingSearch)
|
||||
return callback();
|
||||
|
||||
@ -1259,82 +1265,42 @@ Pool.prototype.addWallet = function addWallet(wallet, callback) {
|
||||
};
|
||||
|
||||
Pool.prototype.removeWallet = function removeWallet(wallet) {
|
||||
var i = this.wallets.indexOf(wallet);
|
||||
var i;
|
||||
|
||||
if (!this.options.spv)
|
||||
return;
|
||||
|
||||
i = this.wallets.indexOf(wallet);
|
||||
|
||||
assert(!this.loading);
|
||||
|
||||
if (i == -1)
|
||||
return;
|
||||
|
||||
this.wallets.splice(i, 1);
|
||||
this.unwatchWallet(wallet);
|
||||
};
|
||||
|
||||
Pool.prototype.watchAddress = function watchAddress(address) {
|
||||
if (address.script) {
|
||||
// For the redeem script hash in outputs:
|
||||
this.watch(address.getScriptHash160());
|
||||
// For the redeem script in inputs:
|
||||
this.watch(address.getScript());
|
||||
}
|
||||
|
||||
if (address.program) {
|
||||
// For programs inside P2SH
|
||||
this.watch(address.getProgramHash());
|
||||
// For witness scripthash
|
||||
if (address.script)
|
||||
this.watch(address.getScriptHash256());
|
||||
}
|
||||
|
||||
// For the pubkey hash in outputs:
|
||||
this.watch(address.getKeyHash());
|
||||
// For the pubkey in inputs:
|
||||
this.watch(address.getPublicKey());
|
||||
address = bcoin.address.parse(address);
|
||||
this.watch(address.hash);
|
||||
};
|
||||
|
||||
Pool.prototype.unwatchAddress = function unwatchAddress(address) {
|
||||
if (addres.script) {
|
||||
// For the redeem script hash in p2sh outputs:
|
||||
this.unwatch(address.getScriptHash160());
|
||||
// For the redeem script in p2sh inputs:
|
||||
this.unwatch(address.getScript());
|
||||
}
|
||||
|
||||
if (address.program) {
|
||||
// For programs inside P2SH
|
||||
this.unwatch(address.getProgramHash());
|
||||
// For witness scripthash
|
||||
if (address.script)
|
||||
this.unwatch(address.getScriptHash256());
|
||||
}
|
||||
|
||||
// For the pubkey hash in p2pk/multisig outputs:
|
||||
this.unwatch(address.getKeyHash());
|
||||
// For the pubkey in p2pkh inputs:
|
||||
this.unwatch(address.getPublicKey());
|
||||
address = bcoin.address.parse(address);
|
||||
this.unwatch(address.hash);
|
||||
};
|
||||
|
||||
Pool.prototype.watchWallet = function watchWallet(wallet) {
|
||||
var self = this;
|
||||
|
||||
wallet.addresses.forEach(function(address) {
|
||||
Object.keys(wallet.addressMap).forEach(function(address) {
|
||||
this.watchAddress(address);
|
||||
}, this);
|
||||
|
||||
wallet.on('add address', wallet._poolOnAdd = function(address) {
|
||||
self.watchAddress(address);
|
||||
});
|
||||
|
||||
wallet.on('remove address', wallet._poolOnRemove = function(address) {
|
||||
self.unwatchAddress(address);
|
||||
});
|
||||
};
|
||||
|
||||
Pool.prototype.unwatchWallet = function unwatchWallet(wallet) {
|
||||
wallet.addresses.forEach(function(address) {
|
||||
Object.keys(wallet.addressMap).forEach(function(address) {
|
||||
this.unwatchAddress(address);
|
||||
}, this);
|
||||
wallet.removeListener('add address', wallet._poolOnAdd);
|
||||
wallet.removeListener('remove address', wallet._poolOnRemove);
|
||||
delete wallet._poolOnAdd;
|
||||
delete wallet._poolOnRemove;
|
||||
};
|
||||
|
||||
Pool.prototype.searchWallet = function(ts, height, callback) {
|
||||
|
||||
@ -26,11 +26,6 @@ function WalletDB(node, options) {
|
||||
if (WalletDB.global)
|
||||
return WalletDB.global;
|
||||
|
||||
if (!(node instanceof bcoin.node)) {
|
||||
options = node;
|
||||
node = null;
|
||||
}
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
@ -549,7 +544,7 @@ WalletDB.prototype.ownTX = function ownTX(tx, callback) {
|
||||
return callback(err);
|
||||
|
||||
if (input || output)
|
||||
return callback(null, input || [], output || []);
|
||||
return callback(null, input, output);
|
||||
|
||||
return callback();
|
||||
});
|
||||
@ -560,6 +555,4 @@ WalletDB.prototype.ownTX = function ownTX(tx, callback) {
|
||||
* Expose
|
||||
*/
|
||||
|
||||
var self = this;
|
||||
var self = this;
|
||||
module.exports = WalletDB;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user