event based system for chain error handling.
This commit is contained in:
parent
7a04ac25d0
commit
5d9f106e2a
@ -39,11 +39,13 @@ function Chain(options) {
|
||||
this.request = new utils.RequestCache();
|
||||
this.loading = false;
|
||||
this.tip = null;
|
||||
this.height = -1;
|
||||
this.mempool = options.mempool;
|
||||
this.blockdb = options.blockdb;
|
||||
this.locked = false;
|
||||
this.pending = [];
|
||||
this.orphanLimit = options.orphanLimit || 20 * 1024 * 1024;
|
||||
this.invalid = {};
|
||||
|
||||
this.orphan = {
|
||||
map: {},
|
||||
@ -86,6 +88,47 @@ Chain.msg = function msg(code) {
|
||||
Chain.prototype._init = function _init() {
|
||||
var self = this;
|
||||
|
||||
// Hook into events for debugging
|
||||
this.on('fork', function(data, peer) {
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
utils.debug(
|
||||
'Fork at height %d: expected=%s received=%s checkpoint=%s peer=%s',
|
||||
data.height,
|
||||
utils.revHex(data.expected),
|
||||
utils.revHex(data.received),
|
||||
data.checkpoint,
|
||||
host
|
||||
);
|
||||
});
|
||||
|
||||
this.on('invalid', function(data, peer) {
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
utils.debug(
|
||||
'Invalid block at height %d: hash=%s peer=%s',
|
||||
data.height,
|
||||
utils.revHex(data.hash),
|
||||
host
|
||||
);
|
||||
if (data.chain) {
|
||||
utils.debug(
|
||||
'Peer is sending an invalid continuation chain (%s)',
|
||||
host);
|
||||
} else if (data.seen) {
|
||||
utils.debug('Peer is sending an invalid chain (%s)', host);
|
||||
}
|
||||
});
|
||||
|
||||
this.on('exists', function(data, peer) {
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
utils.debug('Already have block %s (%s)',
|
||||
data.height, host);
|
||||
});
|
||||
|
||||
this.on('orphan', function(data, peer) {
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
utils.debug('Handled orphan %s (%s)', utils.revHex(data.hash), host);
|
||||
});
|
||||
|
||||
this.loading = true;
|
||||
|
||||
utils.debug('Chain is loading.');
|
||||
@ -725,6 +768,7 @@ Chain.prototype._saveEntry = function _saveEntry(entry, save, callback) {
|
||||
|
||||
if (!this.tip || entry.height > this.tip.height) {
|
||||
this.tip = entry;
|
||||
this.height = this.tip.height;
|
||||
this.emit('tip', this.tip);
|
||||
}
|
||||
|
||||
@ -772,6 +816,8 @@ Chain.prototype.resetHeight = function resetHeight(height) {
|
||||
}
|
||||
|
||||
this.tip = this.db.get(height);
|
||||
assert(this.tip);
|
||||
this.height = this.tip.height;
|
||||
this.emit('tip', this.tip);
|
||||
};
|
||||
|
||||
@ -784,6 +830,7 @@ Chain.prototype.resetTime = function resetTime(ts) {
|
||||
|
||||
Chain.prototype.add = function add(initial, peer, callback) {
|
||||
var self = this;
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
var code = Chain.codes.unchanged;
|
||||
var total = 0;
|
||||
|
||||
@ -797,7 +844,23 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
(function next(block) {
|
||||
var hash = block.hash('hex');
|
||||
var prevHash = block.prevBlock;
|
||||
var prevHeight, entry, existing, checkpoint, prev;
|
||||
var prevHeight, entry, existing, checkpoint, prev, orphan;
|
||||
|
||||
// Special case for genesis block.
|
||||
if (block.isGenesis())
|
||||
return done(null, code);
|
||||
|
||||
// Do not revalidate known invalid blocks.
|
||||
if (self.invalid[hash] || self.invalid[prevHash]) {
|
||||
code = Chain.codes.invalid;
|
||||
self.emit('invalid', {
|
||||
height: -1,
|
||||
hash: hash,
|
||||
seen: true,
|
||||
chain: self.invalid[prevHash]
|
||||
}, peer);
|
||||
return done(null, code);;
|
||||
}
|
||||
|
||||
// Find the previous block height/index.
|
||||
prevHeight = self.heightLookup[prevHash];
|
||||
@ -808,32 +871,41 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
// orphans.
|
||||
if (block === initial && !block.verify()) {
|
||||
code = Chain.codes.invalid;
|
||||
self.invalid[hash] = true;
|
||||
self.emit('invalid', {
|
||||
height: prevHeight + 1,
|
||||
hash: hash
|
||||
hash: hash,
|
||||
seen: false,
|
||||
chain: false
|
||||
}, peer);
|
||||
return done(null, code);
|
||||
}
|
||||
|
||||
// If the block is already known to be
|
||||
// an orphan, ignore it.
|
||||
if (self.orphan.map[prevHash]) {
|
||||
orphan = self.orphan.map[prevHash];
|
||||
if (orphan) {
|
||||
// If the orphan chain forked, simply
|
||||
// reset the orphans and find a new peer.
|
||||
if (self.orphan.map[prevHash].hash('hex') !== hash) {
|
||||
if (orphan.hash('hex') !== hash) {
|
||||
self.orphan.map = {};
|
||||
self.orphan.bmap = {};
|
||||
self.orphan.count = 0;
|
||||
self.orphan.size = 0;
|
||||
self.emit('fork', {
|
||||
height: -1,
|
||||
expected: self.orphan.map[prevHash].hash('hex'),
|
||||
expected: orphan.hash('hex'),
|
||||
received: hash,
|
||||
checkpoint: false
|
||||
}, peer);
|
||||
code = Chain.codes.forked;
|
||||
return done(null, code);
|
||||
}
|
||||
self.emit('orphan', {
|
||||
height: -1,
|
||||
hash: hash,
|
||||
seen: true
|
||||
}, peer);
|
||||
code = Chain.codes.knownOrphan;
|
||||
return done(null, code);
|
||||
}
|
||||
@ -846,6 +918,11 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
self.orphan.map[prevHash] = block;
|
||||
self.orphan.bmap[hash] = block;
|
||||
code = Chain.codes.newOrphan;
|
||||
self.emit('orphan', {
|
||||
height: -1,
|
||||
hash: hash,
|
||||
seen: false
|
||||
}, peer);
|
||||
return done(null, code);
|
||||
}
|
||||
|
||||
@ -870,7 +947,11 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
// who isn't trying to fool us.
|
||||
checkpoint = network.checkpoints[entry.height];
|
||||
if (checkpoint) {
|
||||
self.emit('checkpoint', entry.height, entry.hash, checkpoint);
|
||||
self.emit('checkpoint', {
|
||||
height: entry.height,
|
||||
hash: entry.hash,
|
||||
checkpoint: checkpoint
|
||||
});
|
||||
if (hash !== checkpoint) {
|
||||
// Resetting to the last checkpoint _really_ isn't
|
||||
// necessary (even bitcoind doesn't do it), but it
|
||||
@ -883,7 +964,7 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
expected: network.checkpoints[entry.height],
|
||||
received: entry.hash,
|
||||
checkpoint: true
|
||||
});
|
||||
}, peer);
|
||||
return done(null, code);
|
||||
}
|
||||
}
|
||||
@ -898,8 +979,13 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
// NOTE: Wrap this in a nextTick to avoid
|
||||
// a stack overflow if there are a lot of
|
||||
// existing blocks.
|
||||
if (existing.hash === hash)
|
||||
if (existing.hash === hash) {
|
||||
self.emit('exists', {
|
||||
height: entry.height,
|
||||
hash: entry.hash
|
||||
}, peer);
|
||||
return utils.nextTick(handleOrphans);
|
||||
}
|
||||
|
||||
// A valid block with an already existing
|
||||
// height came in, that spells fork. We
|
||||
@ -928,7 +1014,7 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
self.emit('fork', {
|
||||
height: existing.height,
|
||||
expected: existing.hash,
|
||||
received: hash,
|
||||
received: entry.hash,
|
||||
checkpoint: false
|
||||
}, peer);
|
||||
|
||||
@ -954,9 +1040,12 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
|
||||
if (!verified) {
|
||||
code = Chain.codes.invalid;
|
||||
self.invalid[entry.hash] = true;
|
||||
self.emit('invalid', {
|
||||
height: prevHeight + 1,
|
||||
hash: hash
|
||||
height: entry.height,
|
||||
hash: entry.hash,
|
||||
seen: false,
|
||||
chain: false
|
||||
}, peer);
|
||||
return done(null, code);
|
||||
}
|
||||
@ -1057,7 +1146,7 @@ Chain.prototype.add = function add(initial, peer, callback) {
|
||||
|
||||
item = self.pending.shift();
|
||||
|
||||
self.chain.add(item[0], item[1], item[2]);
|
||||
self.add(item[0], item[1], item[2]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -1174,7 +1263,7 @@ Chain.prototype.hashRange = function hashRange(start, end) {
|
||||
|
||||
Chain.prototype.getLocator = function getLocator(start) {
|
||||
var hashes = [];
|
||||
var top = this.height();
|
||||
var top = this.height;
|
||||
var step = 1;
|
||||
var i, existing;
|
||||
|
||||
@ -1269,12 +1358,6 @@ Chain.prototype.getSize = function getSize() {
|
||||
// Legacy
|
||||
Chain.prototype.size = Chain.prototype.getSize;
|
||||
|
||||
Chain.prototype.height = function height() {
|
||||
if (!this.tip)
|
||||
return -1;
|
||||
return this.tip.height;
|
||||
};
|
||||
|
||||
Chain.prototype.getCurrentTarget = function getCurrentTarget() {
|
||||
if (!this.tip)
|
||||
return utils.toCompact(network.powLimit);
|
||||
|
||||
@ -85,7 +85,7 @@ Coin.prototype.getConfirmations = function getConfirmations(height) {
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
|
||||
top = this.chain.height();
|
||||
top = this.chain.height;
|
||||
} else {
|
||||
top = height;
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ Mempool.prototype.addTX = function addTX(tx, peer, callback) {
|
||||
return callback(new Error('TX is spending coins that it does not have.'));
|
||||
}
|
||||
|
||||
height = self.pool.chain.height() + 1;
|
||||
height = self.pool.chain.height + 1;
|
||||
ts = utils.now();
|
||||
if (!tx.isFinal(height, ts)) {
|
||||
return callback(new Error('TX is not final.'));
|
||||
|
||||
@ -148,7 +148,7 @@ Peer.prototype._init = function init() {
|
||||
this.once('version', function() {
|
||||
utils.debug(
|
||||
'Sent version (%s): height=%s',
|
||||
self.host, this.pool.chain.height());
|
||||
self.host, this.pool.chain.height);
|
||||
});
|
||||
|
||||
this._ping.timer = setInterval(function() {
|
||||
@ -176,7 +176,7 @@ Peer.prototype._init = function init() {
|
||||
|
||||
// Send hello
|
||||
this._write(this.framer.version({
|
||||
height: this.pool.chain.height(),
|
||||
height: this.pool.chain.height,
|
||||
relay: this.options.relay
|
||||
}));
|
||||
};
|
||||
|
||||
@ -84,9 +84,6 @@ function Pool(options) {
|
||||
interval: options.loadInterval || 5000
|
||||
};
|
||||
|
||||
this._pendingBlocks = [];
|
||||
this._locked = false;
|
||||
|
||||
this.requestTimeout = options.requestTimeout || 600000;
|
||||
|
||||
this.chain = new bcoin.chain({
|
||||
@ -192,16 +189,7 @@ Pool.prototype._init = function _init() {
|
||||
});
|
||||
|
||||
this.chain.on('fork', function(data, peer) {
|
||||
utils.debug(
|
||||
'Fork at height %d: expected=%s received=%s checkpoint=%s peer=%s',
|
||||
data.height,
|
||||
utils.revHex(data.expected),
|
||||
utils.revHex(data.received),
|
||||
data.checkpoint,
|
||||
peer ? peer.host : ''
|
||||
);
|
||||
|
||||
self.emit('fork', data.expected, data.received);
|
||||
self.emit('fork', data, peer);
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
@ -217,21 +205,47 @@ Pool.prototype._init = function _init() {
|
||||
});
|
||||
|
||||
this.chain.on('invalid', function(data, peer) {
|
||||
utils.debug(
|
||||
'Invalid block at height %d: hash=%s peer=%s',
|
||||
data.height,
|
||||
utils.revHex(data.hash),
|
||||
peer ? peer.host : ''
|
||||
);
|
||||
|
||||
self.block.invalid[data.hash] = true;
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
self.setMisbehavior(peer, 100);
|
||||
});
|
||||
|
||||
this.chain.on('exists', function(data, peer) {
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
self.setMisbehavior(peer, 1);
|
||||
});
|
||||
|
||||
this.chain.on('orphan', function(data, peer) {
|
||||
var host = peer ? peer.host : 'unknown';
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
// Resolve orphan chain
|
||||
if (!self.options.headers) {
|
||||
// Make sure the peer doesn't send us
|
||||
// more than 200 orphans every 3 minutes.
|
||||
if (self.isOrphaning(peer)) {
|
||||
utils.debug('Peer is orphaning (%s)', host);
|
||||
self.setMisbehavior(peer, 100);
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve orphan chain.
|
||||
self.peers.load.loadBlocks(
|
||||
self.chain.getLocator(),
|
||||
self.chain.getOrphanRoot(data.hash)
|
||||
);
|
||||
} else {
|
||||
// Increase banscore by 10 if we're using getheaders.
|
||||
if (!self.options.multiplePeers)
|
||||
self.setMisbehavior(peer, 10);
|
||||
}
|
||||
});
|
||||
|
||||
this.options.wallets.forEach(function(w) {
|
||||
self.addWallet(w);
|
||||
});
|
||||
@ -240,7 +254,7 @@ Pool.prototype._init = function _init() {
|
||||
if (this.chain.isFull()) {
|
||||
this.synced = true;
|
||||
this.emit('full');
|
||||
utils.debug('Chain is fully synced (height=%d).', this.chain.height());
|
||||
utils.debug('Chain is fully synced (height=%d).', this.chain.height);
|
||||
}
|
||||
|
||||
this.startServer();
|
||||
@ -299,7 +313,7 @@ Pool.prototype._startTimer = function _startTimer() {
|
||||
self._stopInterval();
|
||||
self.synced = true;
|
||||
self.emit('full');
|
||||
utils.debug('Chain is fully synced (height=%d).', self.chain.height());
|
||||
utils.debug('Chain is fully synced (height=%d).', self.chain.height);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -608,176 +622,53 @@ Pool.prototype._prehandleBlock = function _prehandleBlock(block, peer, callback)
|
||||
|
||||
Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
|
||||
var self = this;
|
||||
var requested;
|
||||
|
||||
if (this._locked) {
|
||||
this._pendingBlocks.push([block, peer, callback]);
|
||||
return;
|
||||
}
|
||||
callback = utils.asyncify(callback);
|
||||
|
||||
this._locked = true;
|
||||
// Fulfill our request.
|
||||
requested = self._response(block);
|
||||
|
||||
function done(err, result) {
|
||||
var item;
|
||||
|
||||
utils.nextTick(function() {
|
||||
callback(err, result);
|
||||
|
||||
self._locked = false;
|
||||
|
||||
if (self._pendingBlocks.length === 0)
|
||||
return;
|
||||
|
||||
item = self._pendingBlocks.shift();
|
||||
|
||||
self._handleBlock(item[0], item[1], item[2]);
|
||||
});
|
||||
// Someone is sending us blocks without
|
||||
// us requesting them.
|
||||
if (!requested) {
|
||||
utils.debug(
|
||||
'Recieved unrequested block: %s (%s)',
|
||||
block.rhash, peer.host);
|
||||
}
|
||||
|
||||
this._prehandleBlock(block, peer, function(err) {
|
||||
var requested;
|
||||
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
// Fulfill our request.
|
||||
requested = self._response(block);
|
||||
|
||||
// Ensure the block was not invalid last time.
|
||||
// Someone might be sending us bad blocks to DoS us.
|
||||
if (self.block.invalid[block.hash('hex')]) {
|
||||
utils.debug('Peer is sending an invalid chain (%s)', peer.host);
|
||||
self.setMisbehavior(peer, 100);
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
// Ensure this is not a continuation
|
||||
// of an invalid chain.
|
||||
if (self.block.invalid[block.prevBlock]) {
|
||||
utils.debug(
|
||||
'Peer is sending an invalid continuation chain (%s)',
|
||||
peer.host);
|
||||
self.setMisbehavior(peer, 100);
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
// Ignore if we already have.
|
||||
if (self.chain.has(block)) {
|
||||
utils.debug('Already have block %s (%s)',
|
||||
self.chain.getHeight(block), peer.host);
|
||||
self.setMisbehavior(peer, 1);
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
// Make sure the block is valid.
|
||||
if (!block.verify()) {
|
||||
utils.debug(
|
||||
'Block verification failed for %s (%s)',
|
||||
block.rhash, peer.host);
|
||||
self.block.invalid[block.hash('hex')] = true;
|
||||
self.setMisbehavior(peer, 100);
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
// Someone is sending us blocks without
|
||||
// us requesting them.
|
||||
if (!requested) {
|
||||
utils.debug(
|
||||
'Recieved unrequested block: %s (%s)',
|
||||
block.rhash, peer.host);
|
||||
}
|
||||
|
||||
// Resolve orphan chain
|
||||
if (!self.options.headers) {
|
||||
if (!self.chain.hasBlock(block.prevBlock)) {
|
||||
// Special case for genesis block.
|
||||
if (block.isGenesis())
|
||||
return done(null, false);
|
||||
|
||||
// Make sure the peer doesn't send us
|
||||
// more than 200 orphans every 3 minutes.
|
||||
if (self.isOrphaning(peer)) {
|
||||
utils.debug('Peer is orphaning (%s)', peer.host);
|
||||
self.setMisbehavior(peer, 100);
|
||||
return done(null, false);
|
||||
}
|
||||
|
||||
// NOTE: If we were to emit new orphans here, we
|
||||
// would not need to store full blocks as orphans.
|
||||
// However, the listener would not be able to see
|
||||
// the height until later.
|
||||
self._addIndex(block, peer, function(err, added) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
// Resolve orphan chain.
|
||||
self.peers.load.loadBlocks(
|
||||
self.chain.getLocator(),
|
||||
self.chain.getOrphanRoot(block)
|
||||
);
|
||||
|
||||
utils.debug('Handled orphan %s (%s)', block.rhash, peer.host);
|
||||
|
||||
return done(null, false);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!self.chain.hasBlock(block.prevBlock)) {
|
||||
// Special case for genesis block.
|
||||
if (block.isGenesis())
|
||||
return done(null, false);
|
||||
|
||||
// Increase banscore by 10 if we're using getheaders.
|
||||
if (!self.options.multiplePeers) {
|
||||
if (self.setMisbehavior(peer, 10))
|
||||
return done(null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add to index and emit/save
|
||||
self._addIndex(block, peer, function(err, added) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
if (added)
|
||||
return done(null, true);
|
||||
|
||||
return done(null, false);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Pool.prototype._addIndex = function _addIndex(block, peer, callback) {
|
||||
var self = this;
|
||||
this.chain.add(block, peer, function(err, added) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (added === 0)
|
||||
return callback(null, false);
|
||||
self.chain.add(block, peer, function(err, added) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.emit('chain-progress', self.chain.fillPercent(), peer);
|
||||
if (added === 0)
|
||||
return callback(null, false);
|
||||
|
||||
self.block.total += added;
|
||||
self.emit('chain-progress', self.chain.fillPercent(), peer);
|
||||
|
||||
if (self.chain.height() % 20 === 0) {
|
||||
utils.debug(
|
||||
'Got: %s from %s chain len %d blocks %d orp %d act %d queue %d target %s peers %d pending %d',
|
||||
block.rhash,
|
||||
new Date(block.ts * 1000).toString(),
|
||||
self.chain.height(),
|
||||
self.block.total,
|
||||
self.chain.orphan.count,
|
||||
self.request.active,
|
||||
peer._blockQueue.length,
|
||||
self.chain.currentTarget(),
|
||||
self.peers.all.length,
|
||||
self._pendingBlocks.length);
|
||||
}
|
||||
self.block.total += added;
|
||||
|
||||
return callback(null, true);
|
||||
if (self.chain.height % 20 === 0) {
|
||||
utils.debug(
|
||||
'Got: %s from %s chain len %d blocks %d orp %d act %d queue %d target %s peers %d pending %d',
|
||||
block.rhash,
|
||||
new Date(block.ts * 1000).toString(),
|
||||
self.chain.height,
|
||||
self.block.total,
|
||||
self.chain.orphan.count,
|
||||
self.request.activeBlocks,
|
||||
peer._blockQueue.length,
|
||||
self.chain.currentTarget(),
|
||||
self.peers.all.length,
|
||||
self.chain.pending.length);
|
||||
}
|
||||
|
||||
return callback(null, true);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -887,9 +778,13 @@ Pool.prototype._createPeer = function _createPeer(options) {
|
||||
|
||||
Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
|
||||
var self = this;
|
||||
var requested, added;
|
||||
|
||||
callback = utils.asyncify(callback);
|
||||
|
||||
requested = self._response(tx);
|
||||
added = self._addTX(tx, 1);
|
||||
|
||||
function addMempool(tx, peer, callback) {
|
||||
if (!self.mempool)
|
||||
return callback();
|
||||
@ -903,14 +798,9 @@ Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
|
||||
return callback(err);
|
||||
|
||||
addMempool(tx, peer, function(err) {
|
||||
var requested, added;
|
||||
|
||||
if (err && self.synced)
|
||||
utils.debug('Mempool error: %s', err.message);
|
||||
|
||||
requested = self._response(tx);
|
||||
added = self._addTX(tx, 1);
|
||||
|
||||
if (added || tx.block)
|
||||
self.emit('tx', tx, peer);
|
||||
|
||||
@ -1403,13 +1293,13 @@ Pool.prototype.searchWallet = function(w, h) {
|
||||
if (height > 0) {
|
||||
// Back one week
|
||||
if (!height || height === -1)
|
||||
height = this.chain.height() - (7 * 24 * 6);
|
||||
height = this.chain.height - (7 * 24 * 6);
|
||||
|
||||
utils.nextTick(function() {
|
||||
utils.debug('Wallet height: %s', height);
|
||||
utils.debug(
|
||||
'Reverted chain to height=%d',
|
||||
self.chain.height()
|
||||
self.chain.height
|
||||
);
|
||||
});
|
||||
|
||||
@ -1425,7 +1315,7 @@ Pool.prototype.searchWallet = function(w, h) {
|
||||
utils.debug('Wallet time: %s', new Date(ts * 1000));
|
||||
utils.debug(
|
||||
'Reverted chain to height=%d (%s)',
|
||||
self.chain.height(),
|
||||
self.chain.height,
|
||||
new Date(self.chain.tip.ts * 1000)
|
||||
);
|
||||
});
|
||||
|
||||
@ -1406,7 +1406,7 @@ TX.prototype.avoidFeeSnipping = function avoidFeeSnipping(height) {
|
||||
if (!this.chain)
|
||||
return;
|
||||
|
||||
height = this.chain.height();
|
||||
height = this.chain.height;
|
||||
}
|
||||
|
||||
if (height === -1)
|
||||
@ -1704,7 +1704,7 @@ TX.prototype.getConfirmations = function getConfirmations(height) {
|
||||
if (!this.chain)
|
||||
return 0;
|
||||
|
||||
top = this.chain.height();
|
||||
top = this.chain.height;
|
||||
} else {
|
||||
top = height;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user