chain: do not consider potentially malleated blocks invalid.
This commit is contained in:
parent
9dfe86e612
commit
8e1b2ea8e9
@ -285,13 +285,27 @@ Chain.prototype.isGenesis = function isGenesis(block) {
|
||||
|
||||
Chain.prototype.verify = co(function* verify(block, prev) {
|
||||
var ret = new VerifyResult();
|
||||
var i, height, ts, tx, medianTime, commitmentHash, ancestors, state;
|
||||
var i, err, height, ts, tx, medianTime;
|
||||
var commitmentHash, ancestors, state;
|
||||
|
||||
if (!block.verify(ret)) {
|
||||
throw new VerifyError(block,
|
||||
err = new VerifyError(block,
|
||||
'invalid',
|
||||
ret.reason,
|
||||
ret.score);
|
||||
|
||||
// High hash is the only thing an
|
||||
// adversary couldn't mutate in
|
||||
// otherwise valid non-contextual
|
||||
// checks. The block timestamp
|
||||
// can't be mutated, but our
|
||||
// adjusted time might be off.
|
||||
// We may be able to accept the
|
||||
// block later.
|
||||
if (ret.reason !== 'high-hash')
|
||||
err.malleated = true;
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Skip the genesis block. Skip all blocks in spv mode.
|
||||
@ -349,17 +363,28 @@ Chain.prototype.verify = co(function* verify(block, prev) {
|
||||
if (state.hasWitness()) {
|
||||
commitmentHash = block.commitmentHash;
|
||||
if (commitmentHash) {
|
||||
// These are totally malleable. Someone
|
||||
// may have even accidentally sent us
|
||||
// the non-witness version of the block.
|
||||
// We don't want to consider this block
|
||||
// "invalid" if either of these checks
|
||||
// fail.
|
||||
if (!block.witnessNonce) {
|
||||
throw new VerifyError(block,
|
||||
err = new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-witness-merkle-size',
|
||||
100);
|
||||
err.malleated = true;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (commitmentHash !== block.getCommitmentHash('hex')) {
|
||||
throw new VerifyError(block,
|
||||
err = new VerifyError(block,
|
||||
'invalid',
|
||||
'bad-witness-merkle-match',
|
||||
100);
|
||||
err.malleated = true;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,10 +393,12 @@ Chain.prototype.verify = co(function* verify(block, prev) {
|
||||
// witness data cannot contain it.
|
||||
if (!commitmentHash) {
|
||||
if (block.hasWitness()) {
|
||||
throw new VerifyError(block,
|
||||
err = new VerifyError(block,
|
||||
'invalid',
|
||||
'unexpected-witness',
|
||||
100);
|
||||
err.malleated = true;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@ -842,7 +869,8 @@ Chain.prototype.reconnect = co(function* reconnect(entry) {
|
||||
view = yield this.verifyContext(block, prev);
|
||||
} catch (e) {
|
||||
if (e.type === 'VerifyError') {
|
||||
this.invalid[entry.hash] = true;
|
||||
if (!e.malleated)
|
||||
this.invalid[entry.hash] = true;
|
||||
this.emit('invalid', block, entry.height);
|
||||
}
|
||||
throw e;
|
||||
@ -897,7 +925,8 @@ Chain.prototype.setBestChain = co(function* setBestChain(entry, block, prev) {
|
||||
block.setHeight(-1);
|
||||
|
||||
if (e.type === 'VerifyError') {
|
||||
this.invalid[entry.hash] = true;
|
||||
if (!e.malleated)
|
||||
this.invalid[entry.hash] = true;
|
||||
this.emit('invalid', block, entry.height);
|
||||
}
|
||||
|
||||
@ -1082,7 +1111,8 @@ Chain.prototype._add = co(function* add(block) {
|
||||
// blocks coming in, not the resolving
|
||||
// orphans.
|
||||
if (initial && !block.verify(ret)) {
|
||||
this.invalid[hash] = true;
|
||||
if (ret.reason === 'high-hash')
|
||||
this.invalid[hash] = true;
|
||||
this.emit('invalid', block, block.getCoinbaseHeight());
|
||||
throw new VerifyError(block, 'invalid', ret.reason, ret.score);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user