diff --git a/src/main.cpp b/src/main.cpp index f1b27f8ef..8b4d2feb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1787,7 +1787,7 @@ bool AcceptToMemoryPool( if (tx.IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "coinbase"); - // Rather not work on nonstandard transactions (unless -testnet/-regtest) + // Rather not work on nonstandard transactions (unless -regtest) string reason; if (chainparams.RequireStandard() && !IsStandardTx(tx, reason, chainparams, nextBlockHeight)) return state.DoS(0, false, REJECT_NONSTANDARD, reason); diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 5f5248956..8c1872922 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -59,8 +59,15 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const CChainParam { bool overwinterActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER); bool saplingActive = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING); + bool nu5Active = chainparams.GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5); - if (saplingActive) { + if (nu5Active) { + // NU5 standard rules apply + if (tx.nVersion > CTransaction::NU5_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::NU5_MIN_CURRENT_VERSION) { + reason = "nu5-version"; + return false; + } + } else if (saplingActive) { // Sapling standard rules apply if (tx.nVersion > CTransaction::SAPLING_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SAPLING_MIN_CURRENT_VERSION) { reason = "sapling-version"; diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index e005cd827..b21803720 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -719,6 +719,8 @@ public: static const int32_t OVERWINTER_MAX_CURRENT_VERSION = 3; static const int32_t SAPLING_MIN_CURRENT_VERSION = 4; static const int32_t SAPLING_MAX_CURRENT_VERSION = 4; + static const int32_t NU5_MIN_CURRENT_VERSION = 4; + static const int32_t NU5_MAX_CURRENT_VERSION = 5; static_assert(SPROUT_MIN_CURRENT_VERSION >= SPROUT_MIN_TX_VERSION, "standard rule for tx version should be consistent with network rule"); @@ -737,6 +739,13 @@ public: SAPLING_MAX_CURRENT_VERSION >= SAPLING_MIN_CURRENT_VERSION), "standard rule for tx version should be consistent with network rule"); + static_assert(NU5_MIN_CURRENT_VERSION >= SAPLING_MIN_TX_VERSION, + "standard rule for tx version should be consistent with network rule"); + + static_assert( (NU5_MAX_CURRENT_VERSION <= ZIP225_MAX_TX_VERSION && + NU5_MAX_CURRENT_VERSION >= NU5_MIN_CURRENT_VERSION), + "standard rule for tx version should be consistent with network rule"); + // The local variables are made const to prevent unintended modification // without updating the cached hash value. However, CTransaction is not // actually immutable; deserialization and assignment are implemented,