diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 8c3944eb..806ee2c9 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -59,7 +59,6 @@ public: consensus.nBlockSequentialAlgoRuleStart1 = 740000; // block where sequential algo rule starts consensus.nBlockSequentialAlgoRuleStart2 = 766000; // block where sequential algo rule starts - consensus.nBlockSequentialAlgoRuleStart3 = 2000000; // block where sequential algo rule starts ** TODO CHANGE LATER ** consensus.nBlockSequentialAlgoMaxCount1 = 6; // maximum sequential blocks of same algo consensus.nBlockSequentialAlgoMaxCount2 = 3; // maximum sequential blocks of same algo consensus.nBlockSequentialAlgoMaxCount3 = 6; // maximum sequential blocks of same algo @@ -69,7 +68,9 @@ public: consensus.nBlockAlgoNormalisedWorkDecayStart1 = 866000; // block where weight decay starts consensus.nBlockAlgoNormalisedWorkDecayStart2 = 932000; // block where weight decay starts consensus.nGeoAvgWork_Start = 1400000; - consensus.nAlgoSwitchBlock1 = 100000000; + consensus.nFork1MinBlock = 1764000; // minimum block height where fork 1 takes effect (algo switch, BIP66, BIP65, seq algo count change) + consensus.nMajorityEnableAlgoSwitch1 = 600; + consensus.nAlgoSwitch1EnableWindow = 2000; /** * The message start string is designed to be unlikely to occur in normal data. @@ -202,7 +203,6 @@ public: consensus.nBlockSequentialAlgoRuleStart1 = 200; // block where sequential algo rule starts consensus.nBlockSequentialAlgoRuleStart2 = 250; // block where sequential algo rule starts - consensus.nBlockSequentialAlgoRuleStart3 = 300; // block where sequential algo rule starts consensus.nBlockSequentialAlgoMaxCount1 = 6; // maximum sequential blocks of same algo consensus.nBlockSequentialAlgoMaxCount2 = 3; // maximum sequential blocks of same algo consensus.nBlockSequentialAlgoMaxCount3 = 6; // maximum sequential blocks of same algo @@ -212,8 +212,10 @@ public: consensus.nBlockAlgoNormalisedWorkDecayStart1 = 0; // block where weight decay starts consensus.nBlockAlgoNormalisedWorkDecayStart2 = 0; // block where weight decay starts consensus.nGeoAvgWork_Start = 150; - consensus.nAlgoSwitchBlock1 = 100; - + consensus.nFork1MinBlock = 300; + consensus.nMajorityEnableAlgoSwitch1 = 60; + consensus.nAlgoSwitch1EnableWindow = 200; + pchMessageStart[0] = 0x01; pchMessageStart[1] = 0xf5; pchMessageStart[2] = 0x55; diff --git a/src/consensus/params.h b/src/consensus/params.h index 5baee1c8..266661e9 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -36,7 +36,6 @@ struct Params { int64_t nMaxAdjustUpV2; int64_t nBlockSequentialAlgoRuleStart1; int64_t nBlockSequentialAlgoRuleStart2; - int64_t nBlockSequentialAlgoRuleStart3; int nBlockSequentialAlgoMaxCount1; int nBlockSequentialAlgoMaxCount2; int nBlockSequentialAlgoMaxCount3; @@ -45,7 +44,9 @@ struct Params { int64_t nBlockAlgoNormalisedWorkDecayStart1; int64_t nBlockAlgoNormalisedWorkDecayStart2; int64_t nGeoAvgWork_Start; - int64_t nAlgoSwitchBlock1; + int64_t nFork1MinBlock; + int nMajorityEnableAlgoSwitch1; + int nAlgoSwitch1EnableWindow; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacingV1; } diff --git a/src/main.cpp b/src/main.cpp index 86b7c11d..a8856106 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,6 +84,7 @@ void EraseOrphansFor(NodeId peer); * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); +static bool IsAlgoSwitch1Active(const CBlockIndex* pstart, const Consensus::Params& consensusParams); static void CheckBlockIndex(); /** Constant stuff for coinbase transactions we create: */ @@ -1973,14 +1974,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin unsigned int flags = SCRIPT_VERIFY_P2SH; // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded: - if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { - flags |= SCRIPT_VERIFY_DERSIG; - } + if (pindex->nHeight >= chainparams.GetConsensus().nFork1MinBlock) + { + if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { + flags |= SCRIPT_VERIFY_DERSIG; + } - // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 - // blocks, when 75% of the network has upgraded: - if (block.nVersion >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { - flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 + // blocks, when 75% of the network has upgraded: + if (block.nVersion >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { + flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; + } } CBlockUndo blockundo; @@ -2946,13 +2950,31 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.Invalid(error("%s: block's timestamp is too early", __func__), REJECT_INVALID, "time-too-old"); - // Check valid algo - if ( (algo == ALGO_QUBIT) && (nHeight >= consensusParams.nAlgoSwitchBlock1) ) - return state.Invalid(error("%s: invalid QUBIT block", __func__), - REJECT_INVALID, "invalid-algo"); - if ( (algo == ALGO_YESCRYPT) && (nHeight < consensusParams.nAlgoSwitchBlock1) ) - return state.Invalid(error("%s: invalid YESCRYPT block", __func__), - REJECT_INVALID, "invalid-algo"); + // Check for algo switch 1 + // Active when: + // previous YESCRYPT block was mined or; + // mining majority and fork height reached + bool bAlgoSwitch1 = false; + if (nHeight >= consensusParams.nFork1MinBlock) + { + bAlgoSwitch1 = IsAlgoSwitch1Active(pindexPrev, consensusParams); + if (!bAlgoSwitch1) + bAlgoSwitch1 = + (block.nVersion > 3) && + IsSuperMajority(4, pindexPrev, consensusParams.nMajorityEnableAlgoSwitch1, consensusParams); + } + if (bAlgoSwitch1) + { + if (algo == ALGO_QUBIT) + return state.Invalid(error("%s: invalid QUBIT block", __func__), + REJECT_INVALID, "invalid-algo"); + } + else + { + if (algo == ALGO_YESCRYPT) + return state.Invalid(error("%s: invalid YESCRYPT block", __func__), + REJECT_INVALID, "invalid-algo"); + } if(fCheckpointsEnabled) { @@ -2967,20 +2989,23 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight)); } - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - // if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - // return state.Invalid(error("%s: rejected nVersion=1 block", __func__), - // REJECT_OBSOLETE, "bad-version"); + if (nHeight >= consensusParams.nFork1MinBlock) + { + // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: + // if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + // return state.Invalid(error("%s: rejected nVersion=1 block", __func__), + // REJECT_OBSOLETE, "bad-version"); - // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=2 block", __func__), - REJECT_OBSOLETE, "bad-version"); + // Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded: + if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(error("%s : rejected nVersion=2 block", __func__), + REJECT_OBSOLETE, "bad-version"); - // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) - return state.Invalid(error("%s : rejected nVersion=3 block", __func__), - REJECT_OBSOLETE, "bad-version"); + // Reject block.nVersion=3 blocks when 95% (75% on testnet) of the network has upgraded: + if (block.nVersion < 4 && IsSuperMajority(4, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) + return state.Invalid(error("%s : rejected nVersion=3 block", __func__), + REJECT_OBSOLETE, "bad-version"); + } return true; } @@ -3003,12 +3028,15 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - if (block.nVersion >= 2 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)) + if (nHeight >= consensusParams.nFork1MinBlock) { - CScript expect = CScript() << nHeight; - if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || - !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + if (block.nVersion >= 2 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)) + { + CScript expect = CScript() << nHeight; + if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || + !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { + return state.DoS(100, error("%s: block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + } } } @@ -3057,7 +3085,9 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc // Maximum sequence count allowed int nMaxSeqCount; - if (nHeight > chainparams.GetConsensus().nBlockSequentialAlgoRuleStart3) + if ( (nHeight > chainparams.GetConsensus().nFork1MinBlock) && + (block.nVersion > 3) && + IsSuperMajority(4, pindexPrev, chainparams.GetConsensus().nMajorityEnableAlgoSwitch1, chainparams.GetConsensus()) ) nMaxSeqCount = chainparams.GetConsensus().nBlockSequentialAlgoMaxCount3; else if (nHeight > chainparams.GetConsensus().nBlockSequentialAlgoRuleStart2) @@ -3172,6 +3202,17 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned return (nFound >= nRequired); } +static bool IsAlgoSwitch1Active(const CBlockIndex* pstart, const Consensus::Params& consensusParams) +{ + bool algoFound = false; + for (int i = 0; i < consensusParams.nAlgoSwitch1EnableWindow && !algoFound && pstart != NULL; i++) + { + if (pstart->GetAlgo() == ALGO_YESCRYPT) + algoFound = true; + pstart = pstart->pprev; + } + return (algoFound); +} bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) { diff --git a/src/primitives/pureheader.h b/src/primitives/pureheader.h index fe2999ac..5d4c879a 100644 --- a/src/primitives/pureheader.h +++ b/src/primitives/pureheader.h @@ -23,7 +23,7 @@ const int NUM_ALGOS = 5; enum { // primary version - BLOCK_VERSION_DEFAULT = 2, // change this in later release for BIP66 (3) and BIP65 (4) softforks + BLOCK_VERSION_DEFAULT = 4, // change this in later release for BIP66 (3) and BIP65 (4) softforks // algo BLOCK_VERSION_ALGO = (7 << 9), diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 8a1b9102..c8b08f44 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -540,11 +540,29 @@ Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, c Object rv; rv.push_back(Pair("id", name)); rv.push_back(Pair("version", version)); + rv.push_back(Pair("minheight", consensusParams.nFork1MinBlock)); + bool bHeightActive = ((int)chainActive.Height() >= consensusParams.nFork1MinBlock); + rv.push_back(Pair("condition-minheight", bHeightActive)); rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams))); return rv; } +Object AlgoSwitch1ForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + Object rv; + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + Object bh; + int nHeight = (int)chainActive.Height(); + bh.push_back(Pair("status", nHeight >= consensusParams.nFork1MinBlock)); + bh.push_back(Pair("height", nHeight)); + bh.push_back(Pair("height-active", consensusParams.nFork1MinBlock)); + rv.push_back(Pair("enforce-condition-blockheight", bh)); + rv.push_back(Pair("enforce-condition-majority", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnableAlgoSwitch1, consensusParams))); + return rv; +} + Value getblockchaininfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -608,6 +626,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) // softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); + softforks.push_back(AlgoSwitch1ForkDesc("algoswitch1", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); if (fPruneMode)