Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: rebase bcc onto staging #2

Merged
merged 5 commits into from
May 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 75 additions & 110 deletions lib/blockchain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,13 +420,6 @@ class Chain extends AsyncEmitter {
// Get the new deployment state.
const state = await this.getDeployments(block.time, prev);

// Enforce BIP91/BIP148.
if (state.hasBIP91() || state.hasBIP148()) {
const {segwit} = this.network.deployments;
if (!consensus.hasBit(block.version, segwit.bit))
throw new VerifyError(block, 'invalid', 'bad-no-segwit', 0);
}

// Get timestamp for tx.isFinal().
const time = state.hasMTP() ? mtp : block.time;

Expand All @@ -452,50 +445,9 @@ class Chain extends AsyncEmitter {
}
}

// Check the commitment hash for segwit.
let commit = null;
if (state.hasWitness()) {
commit = block.getCommitmentHash();
if (commit) {
// 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.getWitnessNonce()) {
throw new VerifyError(block,
'invalid',
'bad-witness-nonce-size',
100,
true);
}

if (!commit.equals(block.createCommitmentHash())) {
throw new VerifyError(block,
'invalid',
'bad-witness-merkle-match',
100,
true);
}
}
}

// Blocks that do not commit to
// witness data cannot contain it.
if (!commit) {
if (block.hasWitness()) {
throw new VerifyError(block,
'invalid',
'unexpected-witness',
100,
true);
}
}

// Check block weight (different from block size
// Check block size (different from block size
// check in non-contextual verification).
if (block.getWeight() > consensus.MAX_BLOCK_WEIGHT) {
if (block.getBaseSize() > state.maxBlockSize()) {
throw new VerifyError(block,
'invalid',
'bad-blk-weight',
Expand Down Expand Up @@ -540,6 +492,13 @@ class Chain extends AsyncEmitter {
if (height >= this.network.block.bip65height)
state.flags |= Script.flags.VERIFY_CHECKLOCKTIMEVERIFY;

// UAHF is now enabled.
const mtp = await this.getMedianTime(prev);
if (mtp >= consensus.UAHF_TIME) {
state.flags = Script.flags.VERIFY_STRICTENC;
state.flags = Script.flags.VERIFY_SIGHASH_FORKID;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these need to be |= instead of =.

Copy link
Member Author

@tuxcanfly tuxcanfly May 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is coming from the rebase. We can check this later.

edit: #6

}

// CHECKSEQUENCEVERIFY and median time
// past locktimes are now usable (bip9 & bip113).
if (await this.isActive(prev, deployments.csv)) {
Expand All @@ -548,41 +507,6 @@ class Chain extends AsyncEmitter {
state.lockFlags |= common.lockFlags.MEDIAN_TIME_PAST;
}

// Check the state of the segwit deployment.
const witness = await this.getState(prev, deployments.segwit);

// Segregrated witness (bip141) is now usable
// along with SCRIPT_VERIFY_NULLDUMMY (bip147).
if (witness === thresholdStates.ACTIVE) {
state.flags |= Script.flags.VERIFY_WITNESS;
state.flags |= Script.flags.VERIFY_NULLDUMMY;
}

// Segsignal is now enforced (bip91).
if (this.options.bip91) {
if (witness === thresholdStates.STARTED) {
if (await this.isActive(prev, deployments.segsignal))
state.bip91 = true;
}
}

// UASF is now enforced (bip148) (mainnet-only).
if (this.options.bip148 && this.network === Network.main) {
if (witness !== thresholdStates.LOCKED_IN
&& witness !== thresholdStates.ACTIVE) {
// The BIP148 MTP check is nonsensical in
// that it includes the _current_ entry's
// timestamp. This requires some hackery,
// since bcoin only operates on the sane
// assumption that deployment checks should
// only ever examine the values of the
// previous block (necessary for mining).
const mtp = await this.getMedianTime(prev, time);
if (mtp >= 1501545600 && mtp <= 1510704000)
state.bip148 = true;
}
}

return state;
}

Expand Down Expand Up @@ -621,6 +545,9 @@ class Chain extends AsyncEmitter {
if (!this.state.hasBIP148() && state.hasBIP148())
this.logger.warning('BIP148 has been activated.');

if (!this.state.hasUAHF() && state.hasUAHF())
this.logger.warning('UAHF has been activated.');

this.state = state;
}

Expand Down Expand Up @@ -2262,38 +2189,56 @@ class Chain extends AsyncEmitter {
return pow.bits;
}

if ((prev.height + 1) % pow.retargetInterval === 0) {
// Back 2 weeks
const height = prev.height - (pow.retargetInterval - 1);
assert(height >= 0);

const first = await this.getAncestor(prev, height);
assert(first);

return this.retarget(prev, first);
}

// Do not retarget
if ((prev.height + 1) % pow.retargetInterval !== 0) {
if (pow.targetReset) {
// Special behavior for testnet:
if (time > prev.time + pow.targetSpacing * 2)
return pow.bits;

while (prev.height !== 0
&& prev.height % pow.retargetInterval !== 0
&& prev.bits === pow.bits) {
const cache = this.getPrevCache(prev);

if (cache)
prev = cache;
else
prev = await this.getPrevious(prev);

assert(prev);
if (pow.targetReset) {
// Special behavior for testnet:
if (time > prev.time + pow.targetSpacing * 2)
return pow.bits;

while (prev.height !== 0
&& prev.height % pow.retargetInterval !== 0
&& prev.bits === pow.bits) {
const cache = this.getPrevCache(prev);

if (cache) {
prev = cache;
continue;
}

prev = await this.getPrevious(prev);
assert(prev);
}
return prev.bits;
}

// Back 2 weeks
const height = prev.height - (pow.retargetInterval - 1);
assert(height >= 0);
if (prev.bits === pow.bits)
return prev.bits;

const first = await this.getAncestor(prev, height);
assert(first);
const prev6 = await this.getAncestor(prev, (prev.height + 1) - 7);
assert(prev6);
const mtp6 = (await this.getMedianTime(prev)) - (await this.getMedianTime(prev6));

return this.retarget(prev, first);
}
if (mtp6 < 12 * 3600)
return prev.bits;

const target = consensus.fromCompact(prev.bits);
target.iadd(target.ushrn(2));

if (target.cmp(pow.limit) > 0)
return pow.bits;

return consensus.toCompact(target);
};

/**
* Retarget. This is called when the chain height
Expand Down Expand Up @@ -2894,6 +2839,26 @@ class DeploymentState {
}
}

/**
* Test whether UAHF is active.
* @returns {Boolean}
*/

DeploymentState.prototype.hasUAHF = function hasUAHF() {
return (this.flags & Script.flags.VERIFY_SIGHASH_FORKID) !== 0;
};

/**
* Test whether UAHF is active.
* @returns {Boolean}
*/

DeploymentState.prototype.maxBlockSize = function maxBlockSize() {
return this.hasUAHF()
? consensus.MAX_FORK_BLOCK_SIZE
: consensus.MAX_BLOCK_SIZE;
};

/**
* Orphan
* @ignore
Expand Down
2 changes: 1 addition & 1 deletion lib/blockchain/chaindb.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ChainDB {
this.logger.info('Opening ChainDB...');

await this.db.open();
await this.db.verify(layout.V.build(), 'chain', 5);
await this.db.verify(layout.V.build(), 'chain', 0x80 | 5);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this change for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a flag for the chain type, so as to not confuse between forks.


const state = await this.getState();

Expand Down
2 changes: 1 addition & 1 deletion lib/net/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ exports.USER_AGENT = `/bcoin:${pkg.version}/`;
* @default
*/

exports.MAX_MESSAGE = 4 * 1000 * 1000;
exports.MAX_MESSAGE = 8 * 1000 * 1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we account for the next hard fork to 32MB, surely we're not just going to manually change this at the exact right time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, we need to do that in next hard fork PR.


/**
* Amount of time to ban misbheaving peers.
Expand Down
Loading