Skip to content
Open
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
3 changes: 3 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -413,6 +415,7 @@ class CRegTestParams : public CChainParams {
strCurrencyUnits = "REG";
bip44CoinType = 1;
consensus.fCoinbaseMustBeProtected = false;
consensus.nApproxReleaseHeight = std::numeric_limits<int>::max(); // Disabled on regtest
consensus.nFeeStartBlockHeight = 5000;
consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL;
consensus.nPostBlossomSubsidyHalvingInterval = Consensus::POST_BLOSSOM_REGTEST_HALVING_INTERVAL;
Expand Down
3 changes: 3 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/crypto/equihash.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <cstring>
#include <exception>
#include <stdexcept>
#include <functional>
#include <memory>
#include <set>
Expand Down
24 changes: 17 additions & 7 deletions src/deprecation.cpp
Original file line number Diff line number Diff line change
@@ -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 .

Expand All @@ -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:
Expand All @@ -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);
Expand All @@ -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);
Expand Down
52 changes: 34 additions & 18 deletions src/deprecation.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
// 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 .

#ifndef ZCASH_DEPRECATION_H
#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
55 changes: 43 additions & 12 deletions src/gtest/test_deprecation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -62,81 +61,113 @@ 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<std::string> r = read_lines(temp);
EXPECT_EQ(r.size(), 1u);

// -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.
Expand Down
6 changes: 4 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>())));
obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT));
CDeprecation deprecation = CDeprecation(Params().GetConsensus().nApproxReleaseHeight);
obj.pushKV("deprecationheight", deprecation.getDeprecationHeight());

return obj;
}
Expand Down
12 changes: 6 additions & 6 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down