ZIP 203: Enforce coinbase nExpiryHeight consensus rule from NU5

This commit is contained in:
Jack Grigg 2021-06-30 22:22:05 +01:00
parent 6145cb8ae1
commit 6bbe0906a8
2 changed files with 24 additions and 5 deletions

View File

@ -769,7 +769,7 @@ TEST(ChecktransactionTests, OverwinterExpiryHeight) {
CTransaction tx(mtx); CTransaction tx(mtx);
MockCValidationState state; MockCValidationState state;
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-expiry-height-too-high", false)).Times(1); EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-expiry-height-too-high", false)).Times(1);
CheckTransactionWithoutProofVerification(tx, state); ContextualCheckTransaction(tx, state, Params(), 1, true);
} }
{ {

View File

@ -1136,11 +1136,25 @@ bool ContextualCheckTransaction(
if (tx.IsCoinBase()) { if (tx.IsCoinBase()) {
// TODO: Check that Orchard coinbase outputs can be decrypted with the all-zeros OVK // TODO: Check that Orchard coinbase outputs can be decrypted with the all-zeros OVK
} else {
// ZIP 203: From NU5, the upper limit on nExpiryHeight is removed for coinbase
// transactions.
if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
REJECT_INVALID, "bad-tx-expiry-height-too-high");
}
} }
} else { } else {
// Rules that apply generally before NU5. These were previously // Rules that apply generally before NU5. These were previously
// noncontextual checks that became contextual after NU5 activation. // noncontextual checks that became contextual after NU5 activation.
if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
return state.DoS(
dosLevelPotentiallyRelaxing,
error("CheckTransaction(): expiry height is too high"),
REJECT_INVALID, "bad-tx-expiry-height-too-high");
}
// Check that Orchard transaction components are not present prior to // Check that Orchard transaction components are not present prior to
// NU5. NOTE: This is an internal zcashd consistency check; it does not // NU5. NOTE: This is an internal zcashd consistency check; it does not
// correspond to a consensus rule in the protocol specification, but is // correspond to a consensus rule in the protocol specification, but is
@ -1406,10 +1420,6 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
return state.DoS(100, error("CheckTransaction(): unknown tx version group id"), return state.DoS(100, error("CheckTransaction(): unknown tx version group id"),
REJECT_INVALID, "bad-tx-version-group-id"); REJECT_INVALID, "bad-tx-version-group-id");
} }
if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) {
return state.DoS(100, error("CheckTransaction(): expiry height is too high"),
REJECT_INVALID, "bad-tx-expiry-height-too-high");
}
} }
auto orchard_bundle = tx.GetOrchardBundle(); auto orchard_bundle = tx.GetOrchardBundle();
@ -4673,6 +4683,15 @@ bool ContextualCheckBlock(
} }
} }
// ZIP 203: From NU5 onwards, nExpiryHeight is set to the block height in coinbase
// transactions.
if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5)) {
if (block.vtx[0].nExpiryHeight != nHeight) {
return state.DoS(100, error("%s: block height mismatch in nExpiryHeight", __func__),
REJECT_INVALID, "bad-cb-height");
}
}
if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_CANOPY)) { if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_CANOPY)) {
// Funding streams are checked inside ContextualCheckTransaction. // Funding streams are checked inside ContextualCheckTransaction.
// This empty conditional branch exists to enforce this ZIP 207 consensus rule: // This empty conditional branch exists to enforce this ZIP 207 consensus rule: