locks. reject.
This commit is contained in:
parent
17d2f1586b
commit
b1d53adb6a
@ -266,6 +266,32 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function save(entry) {
|
||||||
|
if (save.locked)
|
||||||
|
return save.queue.push(entry);
|
||||||
|
|
||||||
|
save.locked = true;
|
||||||
|
|
||||||
|
self.db.save(entry, null, true, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err, 0);
|
||||||
|
|
||||||
|
save.locked = false;
|
||||||
|
|
||||||
|
if (save.queue.length === 0) {
|
||||||
|
if (save.ended)
|
||||||
|
return callback(null, height + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
save(save.queue.shift());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
save.locked = false;
|
||||||
|
save.queue = [];
|
||||||
|
save.ended = false;
|
||||||
|
|
||||||
this.db.getChainHeight(function(err, chainHeight) {
|
this.db.getChainHeight(function(err, chainHeight) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@ -288,7 +314,7 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
var start = Math.max(0, height - 2);
|
var start = Math.max(0, height - 2);
|
||||||
self.reset(start, function(e) {
|
self.reset(start, function(e) {
|
||||||
if (e)
|
if (e)
|
||||||
throw e;
|
return callback(e, 0);
|
||||||
return callback(err, start + 1);
|
return callback(err, start + 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -319,7 +345,12 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
blocks.forEach(function(data) {
|
blocks.forEach(function(data) {
|
||||||
var block, entry, start;
|
var block, entry, start;
|
||||||
|
|
||||||
data = parseHeader(data);
|
try {
|
||||||
|
data = parseHeader(data);
|
||||||
|
} catch (e) {
|
||||||
|
return callback(e, Math.max(0, height - 2));
|
||||||
|
}
|
||||||
|
|
||||||
data.height = height;
|
data.height = height;
|
||||||
|
|
||||||
// Make sure the genesis block is correct.
|
// Make sure the genesis block is correct.
|
||||||
@ -334,7 +365,7 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
stream.destroy();
|
stream.destroy();
|
||||||
return self.reset(start, function(err) {
|
return self.reset(start, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
throw err;
|
return callback(err, 0);
|
||||||
return callback(new Error('Corrupt headers.'), start + 1);
|
return callback(new Error('Corrupt headers.'), start + 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -349,7 +380,7 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
stream.destroy();
|
stream.destroy();
|
||||||
return self.reset(start, function(err) {
|
return self.reset(start, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
throw err;
|
return callback(err, 0);
|
||||||
return callback(new Error('Bad headers.'), start + 1);
|
return callback(new Error('Bad headers.'), start + 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -360,7 +391,7 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
if (entry.height <= chainHeight)
|
if (entry.height <= chainHeight)
|
||||||
self.db.addCache(entry);
|
self.db.addCache(entry);
|
||||||
else
|
else
|
||||||
self.db.save(entry, null, true);
|
save(entry);
|
||||||
|
|
||||||
if ((height + 1) % 50000 === 0)
|
if ((height + 1) % 50000 === 0)
|
||||||
utils.debug('Received %d headers from electrum.org.', height + 1);
|
utils.debug('Received %d headers from electrum.org.', height + 1);
|
||||||
@ -371,7 +402,9 @@ Chain.prototype._preload = function _preload(callback) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
stream.on('end', function() {
|
stream.on('end', function() {
|
||||||
return callback(null, height + 1);
|
save.ended = true;
|
||||||
|
if (!save.locked && save.queue.length === 0)
|
||||||
|
return callback(null, height + 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -909,8 +942,12 @@ Chain.prototype._setBestChain = function _setBestChain(entry, block, callback) {
|
|||||||
|
|
||||||
// We don't have a genesis block yet.
|
// We don't have a genesis block yet.
|
||||||
if (!this.tip) {
|
if (!this.tip) {
|
||||||
if (entry.hash !== network.genesis.hash)
|
if (entry.hash !== network.genesis.hash) {
|
||||||
return utils.asyncify(callback)(new Error('Bad genesis block.'));
|
return utils.asyncify(callback)(new VerifyError(block,
|
||||||
|
'invalid',
|
||||||
|
'bad-genblk',
|
||||||
|
100));
|
||||||
|
}
|
||||||
|
|
||||||
return done();
|
return done();
|
||||||
}
|
}
|
||||||
@ -946,13 +983,11 @@ Chain.prototype.reset = function reset(height, callback, force) {
|
|||||||
if (!unlock)
|
if (!unlock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
callback = utils.ensure(callback);
|
callback = utils.wrap(callback, unlock);
|
||||||
|
|
||||||
this.db.reset(height, function(err, result) {
|
this.db.reset(height, function(err, result) {
|
||||||
if (err) {
|
if (err)
|
||||||
unlock();
|
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the orphan map completely. There may
|
// Reset the orphan map completely. There may
|
||||||
// have been some orphans on a forked chain we
|
// have been some orphans on a forked chain we
|
||||||
@ -960,7 +995,6 @@ Chain.prototype.reset = function reset(height, callback, force) {
|
|||||||
self.purgeOrphans();
|
self.purgeOrphans();
|
||||||
self.purgePending();
|
self.purgePending();
|
||||||
|
|
||||||
unlock();
|
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -972,25 +1006,16 @@ Chain.prototype.resetTime = function resetTime(ts, callback, force) {
|
|||||||
if (!unlock)
|
if (!unlock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
callback = utils.ensure(callback);
|
callback = utils.wrap(callback, unlock);
|
||||||
|
|
||||||
this.byTime(ts, function(err, entry) {
|
this.byTime(ts, function(err, entry) {
|
||||||
if (err) {
|
if (err)
|
||||||
unlock();
|
return callback(err);
|
||||||
callback(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry)
|
||||||
unlock();
|
return callback();
|
||||||
callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.reset(entry.height, function(err) {
|
self.reset(entry.height, callback, true);
|
||||||
unlock();
|
|
||||||
callback(err);
|
|
||||||
}, true);
|
|
||||||
}, true);
|
}, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1009,6 +1034,8 @@ Chain.prototype.add = function add(block, callback, force) {
|
|||||||
if (!unlock)
|
if (!unlock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
callback = utils.wrap(callback, unlock);
|
||||||
|
|
||||||
(function next(block, initial) {
|
(function next(block, initial) {
|
||||||
var hash = block.hash('hex');
|
var hash = block.hash('hex');
|
||||||
var prevHash = block.prevBlock;
|
var prevHash = block.prevBlock;
|
||||||
@ -1240,13 +1267,15 @@ Chain.prototype.add = function add(block, callback, force) {
|
|||||||
|
|
||||||
// Emit our block (and potentially resolved
|
// Emit our block (and potentially resolved
|
||||||
// orphan) only if it is on the main chain.
|
// orphan) only if it is on the main chain.
|
||||||
if (mainChain)
|
if (mainChain) {
|
||||||
self.emit('block', block, entry);
|
self.emit('block', block, entry);
|
||||||
else
|
if (!initial)
|
||||||
|
self.emit('resolved', block, entry);
|
||||||
|
} else {
|
||||||
self.emit('competitor', block, entry);
|
self.emit('competitor', block, entry);
|
||||||
|
if (!initial)
|
||||||
if (!initial)
|
self.emit('competitor resolved', block, entry);
|
||||||
self.emit('resolved', block, entry);
|
}
|
||||||
|
|
||||||
// No orphan chain.
|
// No orphan chain.
|
||||||
if (!self.orphan.map[hash])
|
if (!self.orphan.map[hash])
|
||||||
@ -1285,8 +1314,6 @@ Chain.prototype.add = function add(block, callback, force) {
|
|||||||
if (self.isFull())
|
if (self.isFull())
|
||||||
self.emit('full');
|
self.emit('full');
|
||||||
|
|
||||||
unlock();
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
callback(err);
|
callback(err);
|
||||||
else
|
else
|
||||||
@ -1368,31 +1395,23 @@ Chain.prototype.byTime = function byTime(ts, callback, force) {
|
|||||||
var end = this.height;
|
var end = this.height;
|
||||||
var pos, delta;
|
var pos, delta;
|
||||||
|
|
||||||
var unlock = this._lock(byTime, [ts, callback], force);
|
// var unlock = this._lock(byTime, [ts, callback], force);
|
||||||
if (!unlock)
|
// if (!unlock)
|
||||||
return;
|
// return;
|
||||||
|
// callback = utils.wrap(callback, unlock);
|
||||||
callback = utils.asyncify(callback);
|
|
||||||
|
|
||||||
function done(err, result) {
|
function done(err, result) {
|
||||||
if (err) {
|
if (err)
|
||||||
unlock();
|
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
if (result)
|
||||||
unlock();
|
|
||||||
return callback(null, result);
|
return callback(null, result);
|
||||||
}
|
|
||||||
|
|
||||||
self.db.get(start, function(err, entry) {
|
self.db.get(start, callback);
|
||||||
unlock();
|
|
||||||
callback(err, entry);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ts >= this.tip.ts)
|
if (ts >= this.tip.ts)
|
||||||
return done(null, this.tip);
|
return utils.asyncify(done)(null, this.tip);
|
||||||
|
|
||||||
// Do a binary search for a block
|
// Do a binary search for a block
|
||||||
// mined within an hour of the
|
// mined within an hour of the
|
||||||
@ -1501,29 +1520,25 @@ Chain.prototype.getProgress = function getProgress() {
|
|||||||
Chain.prototype.getHashRange = function getHashRange(start, end, callback, force) {
|
Chain.prototype.getHashRange = function getHashRange(start, end, callback, force) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var unlock = this._lock(getHashRange, [start, end, callback], force);
|
// var unlock = this._lock(getHashRange, [start, end, callback], force);
|
||||||
if (!unlock)
|
// if (!unlock)
|
||||||
return;
|
// return;
|
||||||
|
// callback = utils.wrap(callback, unlock);
|
||||||
function done(err, result) {
|
|
||||||
unlock();
|
|
||||||
callback(err, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.byTime(start, function(err, start) {
|
this.byTime(start, function(err, start) {
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return callback(err);
|
||||||
|
|
||||||
self.byTime(end, function(err, end) {
|
self.byTime(end, function(err, end) {
|
||||||
var hashes;
|
var hashes;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return callback(err);
|
||||||
|
|
||||||
hashes = [];
|
hashes = [];
|
||||||
|
|
||||||
if (!start || !end)
|
if (!start || !end)
|
||||||
return done(null, hashes);
|
return callback(null, hashes);
|
||||||
|
|
||||||
utils.forRange(start.height, end.height + 1, function(i, next) {
|
utils.forRange(start.height, end.height + 1, function(i, next) {
|
||||||
self.db.get(i, function(err, entry) {
|
self.db.get(i, function(err, entry) {
|
||||||
@ -1539,8 +1554,8 @@ Chain.prototype.getHashRange = function getHashRange(start, end, callback, force
|
|||||||
});
|
});
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
if (err)
|
if (err)
|
||||||
return done(err);
|
return callback(err);
|
||||||
return done(null, hashes);
|
return callback(null, hashes);
|
||||||
});
|
});
|
||||||
}, true);
|
}, true);
|
||||||
}, true);
|
}, true);
|
||||||
@ -1556,6 +1571,7 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) {
|
|||||||
var unlock = this._lock(getLocator, [start, callback], force);
|
var unlock = this._lock(getLocator, [start, callback], force);
|
||||||
if (!unlock)
|
if (!unlock)
|
||||||
return;
|
return;
|
||||||
|
callback = utils.wrap(callback, unlock);
|
||||||
|
|
||||||
if (start) {
|
if (start) {
|
||||||
if (Buffer.isBuffer(start))
|
if (Buffer.isBuffer(start))
|
||||||
@ -1589,10 +1605,8 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return getTop(function(err, top) {
|
return getTop(function(err, top) {
|
||||||
if (err) {
|
if (err)
|
||||||
unlock();
|
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
|
||||||
|
|
||||||
i = top;
|
i = top;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -1622,7 +1636,6 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
unlock();
|
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
return callback(null, hashes);
|
return callback(null, hashes);
|
||||||
@ -1952,11 +1965,10 @@ Chain.prototype.isSegwitActive = function isSegwitActive(callback) {
|
|||||||
if (!this.tip)
|
if (!this.tip)
|
||||||
return utils.asyncify(callback)(null, false);
|
return utils.asyncify(callback)(null, false);
|
||||||
|
|
||||||
unlock = this._lock(isSegwitActive, [callback]);
|
// unlock = this._lock(isSegwitActive, [callback]);
|
||||||
if (!unlock)
|
// if (!unlock)
|
||||||
return;
|
// return;
|
||||||
|
// callback = utils.wrap(callback, unlock);
|
||||||
callback = utils.wrap(callback, unlock);
|
|
||||||
|
|
||||||
if (network.type === 'segnet4') {
|
if (network.type === 'segnet4') {
|
||||||
return this.tip.getPrevious(function(err, prev) {
|
return this.tip.getPrevious(function(err, prev) {
|
||||||
@ -2090,6 +2102,12 @@ Chain.prototype.evalLocks = function evalLocks(entry, minHeight, minTime, callba
|
|||||||
|
|
||||||
Chain.prototype.checkLocks = function checkLocks(tx, flags, entry, callback) {
|
Chain.prototype.checkLocks = function checkLocks(tx, flags, entry, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
// var unlock = this._lock(checkLocks, [tx, flags, entry, callback], force);
|
||||||
|
// if (!unlock)
|
||||||
|
// return;
|
||||||
|
// callback = utils.wrap(callback, unlock);
|
||||||
|
|
||||||
this.getLocks(tx, flags, entry, function(err, minHeight, minTime) {
|
this.getLocks(tx, flags, entry, function(err, minHeight, minTime) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|||||||
@ -140,6 +140,7 @@ Peer.prototype._init = function init() {
|
|||||||
|
|
||||||
this.parser.on('error', function(err) {
|
this.parser.on('error', function(err) {
|
||||||
utils.debug(err.stack + '');
|
utils.debug(err.stack + '');
|
||||||
|
peer.sendReject(null, 'malformed', 'error parsing message', 100);
|
||||||
self._error(err);
|
self._error(err);
|
||||||
// Something is wrong here.
|
// Something is wrong here.
|
||||||
// Ignore this peer.
|
// Ignore this peer.
|
||||||
|
|||||||
@ -1925,19 +1925,28 @@ Pool.prototype.isMisbehaving = function isMisbehaving(host) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype.reject = function reject(peer, obj, code, reason, score) {
|
Pool.prototype.reject = function reject(peer, obj, code, reason, score) {
|
||||||
|
if (obj) {
|
||||||
|
utils.debug('Rejecting %s %s from %s: ccode=%s reason=%s',
|
||||||
|
obj.type, obj.hash('hex'), peer.host, code, reason);
|
||||||
|
|
||||||
|
peer.reject({
|
||||||
|
ccode: code,
|
||||||
|
reason: reason,
|
||||||
|
data: obj.hash()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
utils.debug('Rejecting packet from %s: ccode=%s reason=%s',
|
||||||
|
peer.host, code, reason);
|
||||||
|
|
||||||
|
peer.reject({
|
||||||
|
ccode: code,
|
||||||
|
reason: reason,
|
||||||
|
data: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (score != null)
|
if (score != null)
|
||||||
peer.setMisbehavior(score);
|
peer.setMisbehavior(score);
|
||||||
|
|
||||||
utils.debug('Rejecting %s %s: ccode=%s reason=%s',
|
|
||||||
obj.type, obj.hash('hex'), code, reason);
|
|
||||||
|
|
||||||
peer.reject({
|
|
||||||
ccode: code,
|
|
||||||
reason: reason,
|
|
||||||
data: obj.hash()
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user