diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 67e1fdf9e8a..5adc0151251 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -84,6 +84,7 @@ class CMainParams : public CChainParams { strCurrencyUnits = "ZER"; bip44CoinType = 323; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md consensus.fCoinbaseMustBeProtected = true; + consensus.nApproxReleaseHeight = 886075; consensus.nFeeStartBlockHeight = 412300; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_HALVING_INTERVAL; @@ -254,6 +255,7 @@ class CTestNetParams : public CChainParams { strCurrencyUnits = "ZET"; bip44CoinType = 1; consensus.fCoinbaseMustBeProtected = true; + consensus.nApproxReleaseHeight = 886075; consensus.nFeeStartBlockHeight = 1; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_HALVING_INTERVAL; @@ -413,6 +415,7 @@ class CRegTestParams : public CChainParams { strCurrencyUnits = "REG"; bip44CoinType = 1; consensus.fCoinbaseMustBeProtected = false; + consensus.nApproxReleaseHeight = std::numeric_limits::max(); // Disabled on regtest consensus.nFeeStartBlockHeight = 5000; consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL; consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_REGTEST_HALVING_INTERVAL; diff --git a/src/consensus/params.h b/src/consensus/params.h index 94d13b7c898..9c9f40d3fef 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -118,6 +118,9 @@ struct Params { int nPreBlossomSubsidyHalvingInterval; int nPostBlossomSubsidyHalvingInterval; + /** Deprecation block height */ + int nApproxReleaseHeight; + int Halving(int nHeight) const; int GetLastFoundersRewardBlockHeight(int nHeight) const; diff --git a/src/crypto/equihash.h b/src/crypto/equihash.h index b25a098dd1e..f9b317927f1 100644 --- a/src/crypto/equihash.h +++ b/src/crypto/equihash.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/src/deprecation.cpp b/src/deprecation.cpp index 10636f36c9f..2178deda286 100644 --- a/src/deprecation.cpp +++ b/src/deprecation.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2017-2020 The LitecoinZ Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . @@ -13,13 +14,22 @@ static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); -void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) { +CDeprecation::CDeprecation(const int approxreleaseheight) : approxreleaseheight_(approxreleaseheight) +{ + nDeprecationHeight = approxreleaseheight_ + (RELEASE_TO_DEPRECATION_WEEKS * 7 * 24 * EXPECTED_BLOCKS_PER_HOUR); +} + +CDeprecation::~CDeprecation() { +} - // Do not enforce deprecation in regtest or on testnet - std::string networkID = Params().NetworkIDString(); - if (networkID != "main") return; +int CDeprecation::getDeprecationHeight() +{ + return nDeprecationHeight; +} - int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight; +void CDeprecation::EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) +{ + int blocksToDeprecation = nDeprecationHeight - nHeight; if (blocksToDeprecation <= 0) { // In order to ensure we only log once per process when deprecation is // disabled (to avoid log spam), we only need to log in two cases: @@ -29,7 +39,7 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) { // - The node is starting if (blocksToDeprecation == 0 || forceLogging) { auto msg = strprintf(_("This version has been deprecated as of block height %d."), - DEPRECATION_HEIGHT) + " " + + nDeprecationHeight) + " " + _("You should upgrade to the latest version of ZERO."); LogPrintf("*** %s\n", msg); CAlert::Notify(msg, fThread); @@ -39,7 +49,7 @@ void EnforceNodeDeprecation(int nHeight, bool forceLogging, bool fThread) { } else if (blocksToDeprecation == DEPRECATION_WARN_LIMIT || (blocksToDeprecation < DEPRECATION_WARN_LIMIT && forceLogging)) { std::string msg = strprintf(_("This version will be deprecated at block height %d, and will automatically shut down."), - DEPRECATION_HEIGHT) + " " + + nDeprecationHeight) + " " + _("You should upgrade to the latest version of ZERO."); LogPrintf("*** %s\n", msg); CAlert::Notify(msg, fThread); diff --git a/src/deprecation.h b/src/deprecation.h index 951a4f00594..54a716235db 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2017-2020 The LitecoinZ Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . @@ -6,25 +7,40 @@ #define ZCASH_DEPRECATION_H // Deprecation policy: -// * Shut down 26 weeks' worth of blocks after the estimated release block height. -// * A warning is shown during the 4 weeks' worth of blocks prior to shut down. -static const int APPROX_RELEASE_HEIGHT = 886075; -static const int WEEKS_UNTIL_DEPRECATION = 26; -//Fixing zero day size -static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 30); +// Shut down nodes running this version of code, 16 weeks' worth of blocks after the estimated +// release block height. A warning is shown during the 14 days' worth of blocks prior to shut down. +static const int RELEASE_TO_DEPRECATION_WEEKS = 16; + +// Expected number of blocks per hour +static const int EXPECTED_BLOCKS_PER_HOUR = 30; // Number of blocks before deprecation to warn users -//Fixing zero day size -static const int DEPRECATION_WARN_LIMIT = 28 * 24 * 30; // 4 weeks - -/** - * Checks whether the node is deprecated based on the current block height, and - * shuts down the node with an error if so (and deprecation is not disabled for - * the current client version). Warning and error messages are sent to the debug - * log, the metrics UI, and (if configured) -alertnofity. - * - * fThread means run -alertnotify in a free-running thread. - */ -void EnforceNodeDeprecation(int nHeight, bool forceLogging=false, bool fThread=true); +static const int DEPRECATION_WARN_LIMIT = 14 * 24 * EXPECTED_BLOCKS_PER_HOUR; + +class CDeprecation +{ +protected: + int nDeprecationHeight; + +public: + CDeprecation(const int approxreleaseheight); + ~CDeprecation(); + + /** Return deprecation height */ + int getDeprecationHeight(); + + /** + * Checks whether the node is deprecated based on the current block height, and + * shuts down the node with an error if so (and deprecation is not disabled for + * the current client version). Warning and error messages are sent to the debug + * log, the metrics UI, and (if configured) -alertnofity. + * + * fThread means run -alertnotify in a free-running thread. + */ + void EnforceNodeDeprecation(int nHeight, bool forceLogging = false, bool fThread=true); + +private: + int approxreleaseheight_; +}; #endif // ZCASH_DEPRECATION_H diff --git a/src/gtest/test_deprecation.cpp b/src/gtest/test_deprecation.cpp index 830b10a4486..01ec79bc67f 100644 --- a/src/gtest/test_deprecation.cpp +++ b/src/gtest/test_deprecation.cpp @@ -38,7 +38,6 @@ class DeprecationTest : public ::testing::Test { uiInterface.ThreadSafeMessageBox.disconnect_all_slots(); uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, &mock_, _1, _2, _3)); SelectParams(CBaseChainParams::MAIN); - } virtual void TearDown() { @@ -62,73 +61,105 @@ class DeprecationTest : public ::testing::Test { }; TEST_F(DeprecationTest, NonDeprecatedNodeKeepsRunning) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); - EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT - 1); + deprecation.EnforceNodeDeprecation(deprecationHeight - DEPRECATION_WARN_LIMIT - 1); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, NodeNearDeprecationIsWarned) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_WARNING)); - EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT); + deprecation.EnforceNodeDeprecation(deprecationHeight - DEPRECATION_WARN_LIMIT); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, NodeNearDeprecationWarningIsNotDuplicated) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); - EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT + 1); + deprecation.EnforceNodeDeprecation(deprecationHeight - DEPRECATION_WARN_LIMIT + 1); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, NodeNearDeprecationWarningIsRepeatedOnStartup) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_WARNING)); - EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT + 1, true); + deprecation.EnforceNodeDeprecation(deprecationHeight - DEPRECATION_WARN_LIMIT + 1, true); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, DeprecatedNodeShutsDown) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); - EnforceNodeDeprecation(DEPRECATION_HEIGHT); + deprecation.EnforceNodeDeprecation(deprecationHeight); EXPECT_TRUE(ShutdownRequested()); } TEST_F(DeprecationTest, DeprecatedNodeErrorIsNotDuplicated) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); - EnforceNodeDeprecation(DEPRECATION_HEIGHT + 1); + deprecation.EnforceNodeDeprecation(deprecationHeight + 1); EXPECT_TRUE(ShutdownRequested()); } TEST_F(DeprecationTest, DeprecatedNodeErrorIsRepeatedOnStartup) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); - EnforceNodeDeprecation(DEPRECATION_HEIGHT + 1, true); + deprecation.EnforceNodeDeprecation(deprecationHeight + 1, true); EXPECT_TRUE(ShutdownRequested()); } TEST_F(DeprecationTest, DeprecatedNodeIgnoredOnRegtest) { SelectParams(CBaseChainParams::REGTEST); + + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); - EnforceNodeDeprecation(DEPRECATION_HEIGHT+1); + deprecation.EnforceNodeDeprecation(deprecationHeight+1); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, DeprecatedNodeIgnoredOnTestnet) { SelectParams(CBaseChainParams::TESTNET); + + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + EXPECT_FALSE(ShutdownRequested()); - EnforceNodeDeprecation(DEPRECATION_HEIGHT+1); + deprecation.EnforceNodeDeprecation(deprecationHeight+1); EXPECT_FALSE(ShutdownRequested()); } TEST_F(DeprecationTest, AlertNotify) { + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + int deprecationHeight = deprecation.getDeprecationHeight(); + boost::filesystem::path temp = GetTempPath() / boost::filesystem::unique_path("alertnotify-%%%%.txt"); mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_WARNING)); - EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT, false, false); + deprecation.EnforceNodeDeprecation(deprecationHeight - DEPRECATION_WARN_LIMIT, false, false); std::vector r = read_lines(temp); EXPECT_EQ(r.size(), 1u); @@ -136,7 +167,7 @@ TEST_F(DeprecationTest, AlertNotify) { // -alertnotify restricts the message to safe characters. auto expectedMsg = strprintf( "This version will be deprecated at block height %d, and will automatically shut down. You should upgrade to the latest version of Zcash.", - DEPRECATION_HEIGHT); + deprecationHeight); // Windows built-in echo semantics are different than posixy shells. Quotes and // whitespace are printed literally. diff --git a/src/main.cpp b/src/main.cpp index d8b569d2818..2392df3c2bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3559,7 +3559,8 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, // Update cached incremental witnesses GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true); - EnforceNodeDeprecation(pindexNew->nHeight); + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + deprecation.EnforceNodeDeprecation(pindexNew->nHeight); int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001); @@ -5089,7 +5090,8 @@ bool static LoadBlockIndexDB() DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip())); - EnforceNodeDeprecation(chainActive.Height(), true); + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + deprecation.EnforceNodeDeprecation(chainActive.Height(), true); return true; } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 9d2a5481f41..0af4ceddbb0 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -421,7 +421,8 @@ UniValue getdeprecationinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("subversion", FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()))); - obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT)); + CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight); + obj.pushKV("deprecationheight", deprecation.getDeprecationHeight()); return obj; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b26275a4336..0c2c2963dbc 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1034,16 +1034,16 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); } + const Consensus::Params& consensusParams = Params().GetConsensus(); + bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); // Use the approximate release height if it is greater so offline nodes // have a better estimation of the current height and will be more likely to - // determine the correct consensus branch ID. Regtest mode ignores release height. - int chainHeight = chainActive.Height() + 1; - if (Params().NetworkIDString() != "regtest") { - chainHeight = std::max(chainHeight, APPROX_RELEASE_HEIGHT); - } + // determine the correct consensus branch ID. + int chainHeight = std::max(chainActive.Height() + 1, consensusParams.nApproxReleaseHeight); + // Grab the current consensus branch ID - auto consensusBranchId = CurrentEpochBranchId(chainHeight, Params().GetConsensus()); + auto consensusBranchId = CurrentEpochBranchId(chainHeight, consensusParams); if (params.size() > 4 && !params[4].isNull()) { consensusBranchId = ParseHexToUInt32(params[4].get_str());