diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..536b3c3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 + +[Makefile] +indent_style = tab diff --git a/configure.ac b/configure.ac index efe514a..072664f 100755 --- a/configure.ac +++ b/configure.ac @@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 0) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2019) +define(_COPYRIGHT_YEAR, 2020) AC_INIT([Ohmcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[www.ohmcoin.io],[ohmcoin]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/ohmcoin-config.h]) diff --git a/src/Makefile.am b/src/Makefile.am index c417edf..0c3c36a 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,6 +116,8 @@ BITCOIN_CORE_H = \ compat/sanity.h \ consensus/merkle.h \ consensus/validation.h \ + consensus/params.h \ + consensus/upgrades.h \ compressor.h \ primitives/block.h \ primitives/deterministicmint.h \ @@ -219,6 +221,8 @@ libbitcoin_server_a_SOURCES = \ checkpoints.cpp \ httprpc.cpp \ httpserver.cpp \ + consensus/params.cpp \ + consensus/upgrades.cpp \ init.cpp \ leveldbwrapper.cpp \ main.cpp \ @@ -364,6 +368,7 @@ libbitcoin_common_a_SOURCES = \ coins.cpp \ compressor.cpp \ consensus/merkle.cpp \ + consensus/upgrades.cpp \ primitives/block.cpp \ primitives/deterministicmint.cpp \ primitives/transaction.cpp \ diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4d21778..a2f0348 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -393,23 +393,25 @@ class CMainParams : public CChainParams nDefaultPort = 52020; bnProofOfWorkLimit = ~uint256(0) >> 20; nMaxReorganizationDepth = 100; - nEnforceBlockUpgradeMajority = 750; - nRejectBlockOutdatedMajority = 950; - nToCheckBlockUpgradeMajority = 1000; + nEnforceBlockUpgradeMajority = 2250; + nRejectBlockOutdatedMajority = 2850; + nToCheckBlockUpgradeMajority = 3000; // 24 hours (legacy) nMinerThreads = 0; - nTargetTimespan = 1 * 30; // OHMC: 30 Seconds - nTargetSpacing = 1 * 30; // OHMC: 30 Seconds nMaturity = 4; nKarmanodeCountDrift = 20; nMaxMoneyOut = 30000000 * COIN; + /* Legacy Blocktime */ + nTargetTimespanLegacy = 1 * 60 * 40; // OHMC: 40 Minutes + nTargetSpacingLegacy = 1 * 30; // OHMC: 30 Seconds + /* New Blocktime */ + nTargetTimespan = 1 * 60 * 60 * 2; // OHMC New: 120 Minutes + nTargetSpacing = 1 * 60 * 4; // OHMC New: 240 Seconds /** Height or Time Based Activations **/ nLastPOWBlock = 1001; nModifierUpdateBlock = 615800; - nZerocoinStartHeight = 999999999; - /** * Build the genesis block. Note that the output of the genesis coinbase cannot * be spent as it did not originally exist in the database. @@ -477,7 +479,7 @@ class CMainParams : public CChainParams "8441436038339044149526344321901146575444541784240209246165157233507787077498171257724679629263863563732899121548" "31438167899885040445364023527381951378636564391212010397122822120720357"; - + nZerocoinStartHeight = 999999999; nZerocoinLastOldParams = 99999999; // Updated to defer zerocoin v2 for further testing. nMaxZerocoinSpendsPerTransaction = 7; // Assume about 20kb each @@ -485,8 +487,23 @@ class CMainParams : public CChainParams nMintRequiredConfirmations = 20; //the maximum amount of confirmations until accumulated in 19 nRequiredAccumulation = 1; nDefaultSecurityLevel = 100; //full security level for accumulators - nZerocoinHeaderVersion = 6; //Block headers must be this version once zerocoin is active + nZerocoinHeaderVersion = 99; //Block headers must be this version once zerocoin is active nBudgetFeeConfirmations = 3; // Number of confirmations for the finalization fee + + // Network upgrades + consensus.vUpgrades[Consensus::BASE_NETWORK].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKTIME].nActivationHeight = 2977924; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKTIME].nProtocolVersion = 71020; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKREWARD].nActivationHeight = 2977924; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKREWARD].nProtocolVersion = 71020; + consensus.vUpgrades[Consensus::UPGRADE_V3_1_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_2_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + } const Checkpoints::CCheckpointData& Checkpoints() const @@ -516,20 +533,25 @@ class CTestNetParams : public CMainParams nRejectBlockOutdatedMajority = 75; nToCheckBlockUpgradeMajority = 100; nMinerThreads = 0; - nTargetTimespan = 1 * 60; // Ohmcoin: 1 day - nTargetSpacing = 1 * 10; // Ohmcoin: 1 minute + /* Legacy Blocktime */ + nTargetTimespanLegacy = 1 * 60 * 40; // OHMC: 40 Minutes + nTargetSpacingLegacy = 1 * 22; // OHMC: 22 Seconds + /* New Blocktime */ + nTargetTimespan = 1 * 60 * 60 * 1; // OHMC New: 60 Minutes + nTargetSpacing = 1 * 60 * 2; // OHMC New: 120 Seconds + nMaturity = 15; nKarmanodeCountDrift = 4; nModifierUpdateBlock = 51197; //approx Mon, 17 Apr 2017 04:00:00 GMT nMaxMoneyOut = 43199500 * COIN; nLastPOWBlock = 200; - nZerocoinStartHeight = 200; + nZerocoinStartHeight = 999999999; nZerocoinLastOldParams = 50000; //! Modify the testnet genesis block so the timestamp is valid for a later start. - genesis.nTime = 1454124731; - genesis.nNonce = 2402015; + genesis.nTime = 1597378077; + genesis.nNonce = 8142020; hashGenesisBlock = genesis.GetHash(); //assert(hashGenesisBlock == uint256("0xfab709a0c107fe7cf6b0d552c514ef3228f9e0f107cd3c9b2fcea96512342cd8")); @@ -563,6 +585,18 @@ class CTestNetParams : public CMainParams strObfuscationPoolDummyAddress = "y57cqfGRkekRyDRNeJiLtYVEbvhXrNbmox"; nBudgetFeeConfirmations = 3; // Number of confirmations for the finalization fee. We have to make this very short // here because we only have a 8 block finalization window on testnet + + // Network upgrades + consensus.vUpgrades[Consensus::BASE_NETWORK].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKTIME].nActivationHeight = 33001; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKREWARD].nActivationHeight = 33002; + consensus.vUpgrades[Consensus::UPGRADE_V3_1_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_2_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; } const Checkpoints::CCheckpointData& Checkpoints() const { @@ -590,8 +624,12 @@ class CRegTestParams : public CTestNetParams nRejectBlockOutdatedMajority = 950; nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 1; - nTargetTimespan = 24 * 60 * 60; // Ohmcoin: 1 day - nTargetSpacing = 1 * 60; // Ohmcoin: 1 minutes + /* Legacy Blocktime */ + nTargetTimespanLegacy = 1 * 60 * 60 * 24; // OHMC: 24 Hours + nTargetSpacingLegacy = 1 * 30; // OHMC: 22 Seconds + /* New Blocktime */ + nTargetTimespan = 1 * 60 * 60 * 2; // OHMC New: 120 Minutes + nTargetSpacing = 1 * 60 * 4; // OHMC New: 240 Seconds bnProofOfWorkLimit = ~uint256(0) >> 1; genesis.nTime = 1454124731; genesis.nBits = 0x207fffff; @@ -623,11 +661,30 @@ class CRegTestParams : public CTestNetParams // "PublicKey": "04866dc02c998b7e1ab16fe14e0d86554595da90c36acb706a4d763b58ed0edb1f82c87e3ced065c5b299b26e12496956b9e5f9f19aa008b5c46229b15477c875a" // } strSporkKey = "04866dc02c998b7e1ab16fe14e0d86554595da90c36acb706a4d763b58ed0edb1f82c87e3ced065c5b299b26e12496956b9e5f9f19aa008b5c46229b15477c875a"; + + // Network upgrades + consensus.vUpgrades[Consensus::BASE_NETWORK].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKTIME].nActivationHeight = 33002; + consensus.vUpgrades[Consensus::UPGRADE_V3_0_BLOCKREWARD].nActivationHeight = 33002; + consensus.vUpgrades[Consensus::UPGRADE_V3_1_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_V3_2_DUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; } + const Checkpoints::CCheckpointData& Checkpoints() const { return dataRegtest; } + + void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) + { + assert(idx > Consensus::BASE_NETWORK && idx < Consensus::MAX_NETWORK_UPGRADES); + consensus.vUpgrades[idx].nActivationHeight = nActivationHeight; + } }; static CRegTestParams regTestParams; @@ -715,3 +772,8 @@ bool SelectParamsFromCommandLine() SelectParams(network); return true; } + +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) +{ + regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight); +} diff --git a/src/chainparams.h b/src/chainparams.h index 9771041..1ac49a3 100755 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -11,6 +11,7 @@ #include "chainparamsbase.h" #include "checkpoints.h" #include "primitives/block.h" +#include "consensus/params.h" #include "protocol.h" #include "uint256.h" @@ -46,6 +47,7 @@ class CChainParams }; const uint256& HashGenesisBlock() const { return hashGenesisBlock; } + const Consensus::Params& GetConsensus() const { return consensus; } const MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } @@ -71,11 +73,18 @@ class CChainParams bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } + /** Legacy blocktime setting */ + int64_t TargetTimespanLegacy() const { return nTargetTimespanLegacy; } + int64_t TargetSpacingLegacy() const { return nTargetSpacingLegacy; } + int64_t IntervalLegacy() const { return nTargetTimespanLegacy / nTargetSpacingLegacy; } + /** New blocktime setting */ int64_t TargetTimespan() const { return nTargetTimespan; } int64_t TargetSpacing() const { return nTargetSpacing; } int64_t Interval() const { return nTargetTimespan / nTargetSpacing; } + /** Majurity Checks */ int COINBASE_MATURITY() const { return nMaturity; } unsigned int StakeMaturity() const { return nStakeMaturity; } + /** Max Money Checks */ CAmount MaxMoneyOut() const { return nMaxMoneyOut; } /** The karmanode count that we will allow the see-saw reward payments to be off by */ int KarmanodeCountDrift() const { return nKarmanodeCountDrift; } @@ -129,6 +138,8 @@ class CChainParams int nToCheckBlockUpgradeMajority; int64_t nTargetTimespan; int64_t nTargetSpacing; + int64_t nTargetTimespanLegacy; + int64_t nTargetSpacingLegacy; int nLastPOWBlock; int nKarmanodeCountDrift; int nMaturity; @@ -142,6 +153,7 @@ class CChainParams CBaseChainParams::Network networkID; std::string strNetworkID; CBlock genesis; + Consensus::Params consensus; std::vector vFixedSeeds; bool fMiningRequiresPeers; bool fAllowMinDifficultyBlocks; @@ -207,4 +219,9 @@ void SelectParams(CBaseChainParams::Network network); */ bool SelectParamsFromCommandLine(); +/** + * Allows modifying the network upgrade regtest parameters. + */ +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/consensus/params.cpp b/src/consensus/params.cpp new file mode 100644 index 0000000..5675308 --- /dev/null +++ b/src/consensus/params.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2019 The Zcash developers +// Copyright (c) 2020 The PIVX developers +// Copyright (c) 2020 The OHMC developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "consensus/params.h" +#include "consensus/upgrades.h" +#include "util.h" + +namespace Consensus { + +bool Params::NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const +{ + if (idx >= Consensus::MAX_NETWORK_UPGRADES) + return error("%s: Upgrade index out of bounds: %d >= %d", + __func__, idx, Consensus::MAX_NETWORK_UPGRADES); + + if (nHeight < 0) + return error("%s: Requested state for upgrade %s at negative height %d", + __func__, NetworkUpgradeInfo[idx].strName, nHeight); + + return NetworkUpgradeState(nHeight, *this, idx) == UPGRADE_ACTIVE; +} + +} // End consensus namespace diff --git a/src/consensus/params.h b/src/consensus/params.h index e85949f..5cf4b8d 100755 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,17 +1,81 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers +// Copyright (c) 2020 The PIVX developers +// Copyright (c) 2020 The OHMC developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CONSENSUS_PARAMS_H #define BITCOIN_CONSENSUS_PARAMS_H +#include "optional.h" #include "uint256.h" #include #include namespace Consensus { +/** +* Index into Params.vUpgrades and NetworkUpgradeInfo +* +* Being array indices, these MUST be numbered consecutively. +* +* The order of these indices MUST match the order of the upgrades on-chain, as +* several functions depend on the enum being sorted. +*/ +enum UpgradeIndex : uint32_t { + BASE_NETWORK, // Base Network + UPGRADE_V3_0_BLOCKTIME, // Block time consensus change + UPGRADE_V3_0_BLOCKREWARD, // Block reward consensus change + UPGRADE_V3_1_DUMMY, + UPGRADE_V3_2_DUMMY, + UPGRADE_TESTDUMMY, + // NOTE: Also add new upgrades to NetworkUpgradeInfo in upgrades.cpp + MAX_NETWORK_UPGRADES +}; + +struct NetworkUpgrade { + /** + * The first protocol version which will understand the new consensus rules + */ + int nProtocolVersion; + + /** + * Height of the first block for which the new consensus rules will be active + */ + int nActivationHeight; + + /** + * Special value for nActivationHeight indicating that the upgrade is always active. + * This is useful for testing, as it means tests don't need to deal with the activation + * process (namely, faking a chain of somewhat-arbitrary length). + * + * New blockchains that want to enable upgrade rules from the beginning can also use + * this value. However, additional care must be taken to ensure the genesis block + * satisfies the enabled rules. + */ + static constexpr int ALWAYS_ACTIVE = 0; + + /** + * Special value for nActivationHeight indicating that the upgrade will never activate. + * This is useful when adding upgrade code that has a testnet activation height, but + * should remain disabled on mainnet. + */ + static constexpr int NO_ACTIVATION_HEIGHT = -1; + + /** + * The hash of the block at height nActivationHeight, if known. This is set manually + * after a network upgrade activates. + * + * We use this in IsInitialBlockDownload to detect whether we are potentially being + * fed a fake alternate chain. We use NU activation blocks for this purpose instead of + * the checkpoint blocks, because network upgrades (should) have significantly more + * scrutiny than regular releases. nMinimumChainWork MUST be set to at least the chain + * work of this block, otherwise this detection will have false positives. + */ + Optional hashActivationBlock; +}; + enum DeploymentPos { DEPLOYMENT_TESTDUMMY, @@ -84,6 +148,16 @@ struct Params { int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } uint256 nMinimumChainWork; uint256 defaultAssumeValid; + + // Map with network updates + NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]; + + /** + * Returns true if the given network upgrade is active as of the given block + * height. Caller must check that the height is >= 0 (and handle unknown + * heights). + */ + bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const; }; } // namespace Consensus diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp new file mode 100644 index 0000000..207fd48 --- /dev/null +++ b/src/consensus/upgrades.cpp @@ -0,0 +1,140 @@ +// Copyright (c) 2018 The Zcash developers +// Copyright (c) 2020 The PIVX developers +// Copyright (c) 2020 The OHMC developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "consensus/upgrades.h" + +/** + * General information about each network upgrade. + * Ordered by Consensus::UpgradeIndex. + * + * If the upgrade name has many words, use the '_' character to divide them. + * We are using it in the -nuparams startup arg and input it with spaces is just ugly. + */ +const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = { + { + /*.strName =*/ "Base", + /*.strInfo =*/ "OHMC network", + }, + { + /*.strName =*/ "v3_0_blocktime", + /*.strInfo =*/ "Activation of OHMC version 3.0 Block Time upgrade", + }, + { + /*.strName =*/ "v3_0_blockreward", + /*.strInfo =*/ "Activation of OHMC version 3.0 Block Reward upgrade", + }, + { + /*.strName =*/ "v3_1_dummy", + /*.strInfo =*/ "Placeholder for future OHMC version 3.1 upgrade", + }, + { + /*.strName =*/ "v3_2_dummy", + /*.strInfo =*/ "Placeholder for future OHMC version 3.2 upgrade", + }, + { + /*.strName =*/ "Test_dummy", + /*.strInfo =*/ "Test dummy info", + }, +}; + +UpgradeState NetworkUpgradeState( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + assert(nHeight >= 0); + assert(idx >= Consensus::BASE_NETWORK && idx < Consensus::MAX_NETWORK_UPGRADES); + auto nActivationHeight = params.vUpgrades[idx].nActivationHeight; + + if (nActivationHeight == Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + return UPGRADE_DISABLED; + } else if (nHeight >= nActivationHeight) { + // From ZIP200: + // + // ACTIVATION_HEIGHT + // The block height at which the network upgrade rules will come into effect. + // + // For removal of ambiguity, the block at height ACTIVATION_HEIGHT - 1 is + // subject to the pre-upgrade consensus rules. + return UPGRADE_ACTIVE; + } else { + return UPGRADE_PENDING; + } +} + +bool NetworkUpgradeActive( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + return NetworkUpgradeState(nHeight, params, idx) == UPGRADE_ACTIVE; +} + +int CurrentEpoch(int nHeight, const Consensus::Params& params) { + for (auto idxInt = Consensus::MAX_NETWORK_UPGRADES - 1; idxInt > Consensus::BASE_NETWORK; idxInt--) { + if (NetworkUpgradeActive(nHeight, params, Consensus::UpgradeIndex(idxInt))) { + return idxInt; + } + } + return Consensus::BASE_NETWORK; +} + +bool IsActivationHeight( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + assert(idx >= Consensus::BASE_NETWORK && idx < Consensus::MAX_NETWORK_UPGRADES); + + // Don't count BASE_NETWORK as an activation height + if (idx == Consensus::BASE_NETWORK) { + return false; + } + + return nHeight >= 0 && nHeight == params.vUpgrades[idx].nActivationHeight; +} + +bool IsActivationHeightForAnyUpgrade( + int nHeight, + const Consensus::Params& params) +{ + if (nHeight < 0) { + return false; + } + + for (int idx = Consensus::BASE_NETWORK + 1; idx < (int) Consensus::MAX_NETWORK_UPGRADES; idx++) { + if (nHeight == params.vUpgrades[idx].nActivationHeight) + return true; + } + + return false; +} + +Optional NextEpoch(int nHeight, const Consensus::Params& params) { + if (nHeight < 0) { + return nullopt; + } + + // BASE_NETWORK is never pending + for (auto idx = Consensus::BASE_NETWORK + 1; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) { + if (NetworkUpgradeState(nHeight, params, Consensus::UpgradeIndex(idx)) == UPGRADE_PENDING) { + return idx; + } + } + + return nullopt; +} + +Optional NextActivationHeight( + int nHeight, + const Consensus::Params& params) +{ + auto idx = NextEpoch(nHeight, params); + if (idx) { + return params.vUpgrades[idx.get()].nActivationHeight; + } + return nullopt; +} diff --git a/src/consensus/upgrades.h b/src/consensus/upgrades.h new file mode 100644 index 0000000..4f0f071 --- /dev/null +++ b/src/consensus/upgrades.h @@ -0,0 +1,85 @@ +// Copyright (c) 2018 The Zcash developers +// Copyright (c) 2020 The PIVX developers +// Copyright (c) 2020 The OHMC developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_UPGRADES_H +#define BITCOIN_CONSENSUS_UPGRADES_H + +#include "consensus/params.h" +#include "optional.h" + +enum UpgradeState { + UPGRADE_DISABLED, + UPGRADE_PENDING, + UPGRADE_ACTIVE +}; + +struct NUInfo { + /** User-facing name for the upgrade */ + std::string strName; + /** User-facing information string about the upgrade */ + std::string strInfo; +}; + +extern const struct NUInfo NetworkUpgradeInfo[]; + +/** + * Checks the state of a given network upgrade based on block height. + * Caller must check that the height is >= 0 (and handle unknown heights). + */ +UpgradeState NetworkUpgradeState( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx); + +/** + * Returns true if the given network upgrade is active as of the given block + * height. Caller must check that the height is >= 0 (and handle unknown + * heights). + */ +bool NetworkUpgradeActive( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx); + +/** + * Returns the index of the most recent upgrade as of the given block height + * (corresponding to the current "epoch"). Consensus::BASE_NETWORK is the + * default value if no upgrades are active. Caller must check that the height + * is >= 0 (and handle unknown heights). + */ +int CurrentEpoch(int nHeight, const Consensus::Params& params); + +/** + * Returns true if the given block height is the activation height for the given + * upgrade. + */ +bool IsActivationHeight( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex upgrade); + +/** + * Returns true if the given block height is the activation height for any upgrade. + */ +bool IsActivationHeightForAnyUpgrade( + int nHeight, + const Consensus::Params& params); + +/** + * Returns the index of the next upgrade after the given block height, or + * nullopt if there are no more known upgrades. + */ +Optional NextEpoch(int nHeight, const Consensus::Params& params); + +/** + * Returns the activation height for the next upgrade after the given block height, + * or nullopt if there are no more known upgrades. + */ +Optional NextActivationHeight( + int nHeight, + const Consensus::Params& params); + +#endif // PIVX_CONSENSUS_UPGRADES_H diff --git a/src/crypter.cpp b/src/crypter.cpp index f9467de..e179356 100755 --- a/src/crypter.cpp +++ b/src/crypter.cpp @@ -265,6 +265,7 @@ bool CCryptoKeyStore::SetCrypted() bool CCryptoKeyStore::Lock() { + if (!SetCrypted()) return false; { @@ -513,4 +514,4 @@ bool CCryptoKeyStore::GetDeterministicSeed(const uint256& hashSeed, uint256& see // return error("Failed to decrypt deterministic seed %s", IsLocked() ? "Wallet is locked!" : ""); -} \ No newline at end of file +} diff --git a/src/init.cpp b/src/init.cpp index c9d5008..4ca0252 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -18,6 +18,7 @@ #include "amount.h" #include "checkpoints.h" #include "compat/sanity.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "httpserver.h" #include "httprpc.h" @@ -56,6 +57,9 @@ #include #endif +#include +#include + #include #include #include @@ -726,6 +730,42 @@ bool AppInitServers(boost::thread_group& threadGroup) return true; } +bool InitNUParams() +{ + if (!mapMultiArgs["-nuparams"].empty()) { + // Allow overriding network upgrade parameters for testing + if (Params().NetworkIDString() != "regtest") { + return InitError("Network upgrade parameters may only be overridden on regtest."); + } + const std::vector& deployments = mapMultiArgs["-nuparams"]; + for (auto i : deployments) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, i, boost::is_any_of(":")); + if (vDeploymentParams.size() != 2) { + return InitError("Network upgrade parameters malformed, expecting hexBranchId:activationHeight"); + } + int nActivationHeight; + if (!ParseInt32(vDeploymentParams[1], &nActivationHeight)) { + return InitError(strprintf("Invalid nActivationHeight (%s)", vDeploymentParams[1])); + } + bool found = false; + // Exclude base network from upgrades + for (auto j = Consensus::BASE_NETWORK + 1; j < Consensus::MAX_NETWORK_UPGRADES; ++j) { + if (vDeploymentParams[0] == NetworkUpgradeInfo[j].strName) { + UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex(j), nActivationHeight); + found = true; + LogPrintf("Setting network upgrade activation parameters for %s to height=%d\n", vDeploymentParams[0], nActivationHeight); + break; + } + } + if (!found) { + return InitError(strprintf("Invalid network upgrade (%s)", vDeploymentParams[0])); + } + } + } + return true; +} + /** Initialize ohmcoin. * @pre Parameters should be parsed and config file should be read. */ @@ -993,10 +1033,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS); - if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices |= NODE_BLOOM; + if (!InitNUParams()) + return false; + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Sanity check @@ -2008,4 +2050,4 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #endif return !fRequestShutdown; -} \ No newline at end of file +} diff --git a/src/init.h b/src/init.h index 02f83fd..02c1a84 100755 --- a/src/init.h +++ b/src/init.h @@ -39,4 +39,4 @@ std::string HelpMessage(HelpMessageMode mode); /** Returns licensing information (for -version) */ std::string LicenseInfo(); -#endif // BITCOIN_INIT_H \ No newline at end of file +#endif // BITCOIN_INIT_H diff --git a/src/main.cpp b/src/main.cpp index 95b1909..efc4df0 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -2170,8 +2170,27 @@ double ConvertBitsToDouble(unsigned int nBits) int64_t GetBlockValue(int nHeight) { - if (nHeight < 1001 && nHeight > 0) + if (nHeight < 1001 && nHeight > 0) { return 30000 * COIN; + } + + const Consensus::Params& consensus = Params().GetConsensus(); + bool fUpgradeActiveV3 = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKREWARD); + + if (Params().NetworkID() == CBaseChainParams::TESTNET) { + if (nHeight <= 3000 && nHeight >= 1001) { + return 1 * COIN; + } else if (nHeight <= 33001 && nHeight >= 3001) { + return 3.14159 * COIN; + } else if (nHeight >= 33002) { + if (fUpgradeActiveV3) { + return 6 * COIN; + } + return 3 * COIN; + } else { + return 1 * COIN; + } + } if (nHeight == 0) { return 1 * COIN; @@ -2185,16 +2204,11 @@ int64_t GetBlockValue(int nHeight) return 0.125 * COIN; } else if (nHeight <= 2977923 && nHeight >= 2373123) { return 0.0625 * COIN; - } else if (nHeight <= 4029124 && nHeight >= 2977924) { - return 0.03125 * COIN; - } else if (nHeight <= 6131525 && nHeight >= 4029125) { - return 0.015625 * COIN; - } else if (nHeight <= 8233926 && nHeight >= 6131526) { - return 0.0078125 * COIN; - } else if (nHeight <= 10336327 && nHeight >= 8233927) { - return 0.00390625 * COIN; - } else if (nHeight >= 10336328) { - return 0.001953125 * COIN; + } else if (nHeight >= 2977924) { + if (fUpgradeActiveV3) { + return 6 * COIN; + } + return 3 * COIN; } else { return 1 * COIN; } @@ -4513,6 +4527,7 @@ bool CheckWork(const CBlock block, CBlockIndex* const pindexPrev) bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex* const pindexPrev) { + const Consensus::Params& consensus = Params().GetConsensus(); uint256 hash = block.GetHash(); if (hash == Params().HashGenesisBlock()) @@ -4545,8 +4560,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return state.DoS(0, 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 && - CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { + if (block.nVersion < 2 && CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) { return state.Invalid(error("%s : rejected nVersion=1 block", __func__), REJECT_OBSOLETE, "bad-version"); } @@ -4563,6 +4577,15 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta REJECT_OBSOLETE, "bad-version"); } + // Reject outdated version blocks + if ((block.nVersion < 6 && nHeight >= 1) && + (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKTIME) || + consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V3_0_BLOCKREWARD))) + { + std::string stringErr = strprintf("rejected block version %d at height %d", block.nVersion, nHeight); + return state.Invalid(false, REJECT_OBSOLETE, "bad-version", stringErr); + } + return true; } @@ -7035,8 +7058,13 @@ int ActiveProtocol() // own ModifierUpgradeBlock() { - if (IsSporkActive(SPORK_18_NEW_PROTOCOL_ENFORCEMENT_5)) + if (IsSporkActive(SPORK_23_NEW_BLOCKTIME_ENFORCEMENT)) + // Enforce protocol 71025 and greater. return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; + if (IsSporkActive(SPORK_18_NEW_PROTOCOL_ENFORCEMENT_5)) + // Enforce protocol 71011 + return MIN_PEER_MNANNOUNCE; + // Default protocol return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT; } @@ -7327,7 +7355,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes // to unreasonably increase our timeout. - if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { + if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacingLegacy() * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) { LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id); pto->fDisconnect = true; } @@ -7454,4 +7482,4 @@ class CMainCleanup mapOrphanTransactions.clear(); mapOrphanTransactionsByPrev.clear(); } -} instance_of_cmaincleanup; \ No newline at end of file +} instance_of_cmaincleanup; diff --git a/src/main.h b/src/main.h index 3b3ea15..d9c1721 100755 --- a/src/main.h +++ b/src/main.h @@ -659,4 +659,4 @@ struct CBlockTemplate { int64_t GetVirtualTransactionSize(const CTransaction& tx); int64_t GetVirtualTransactionSize(int64_t nCost); -#endif // BITCOIN_MAIN_H \ No newline at end of file +#endif // BITCOIN_MAIN_H diff --git a/src/miner.cpp b/src/miner.cpp index 1538b7a..bce77db 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -120,12 +120,18 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, // transaction (which in most cases can be a no-op). bool fIncludeWitness = IsSporkActive(SPORK_20_SEGWIT_ACTIVATION); - // Make sure to create the correct block version after zerocoin is enabled - bool fZerocoinActive = chainActive.Height() >= Params().Zerocoin_StartHeight(); - if (fZerocoinActive) - pblock->nVersion = 6; - else + // Blocktime and Reward update. + bool fEnforceBlockTimeUpdate = IsSporkActive(SPORK_23_NEW_BLOCKTIME_ENFORCEMENT); + bool fUpgradeActiveV3 = Params().GetConsensus().NetworkUpgradeActive(chainActive.Tip()->nHeight, Consensus::UPGRADE_V3_0_BLOCKTIME); + bool fZerocoinActive = false; // we don't have zerocoin... TODO: Remove! + + if (!fUpgradeActiveV3) { pblock->nVersion = 5; + } else { + if (!fEnforceBlockTimeUpdate) { + pblock->nVersion = 6; + } + } // Create coinbase tx CMutableTransaction txNew; diff --git a/src/optional.h b/src/optional.h new file mode 100644 index 0000000..1614c89 --- /dev/null +++ b/src/optional.h @@ -0,0 +1,17 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_OPTIONAL_H +#define BITCOIN_OPTIONAL_H + +#include + +//! Substitute for C++17 std::optional +template +using Optional = boost::optional; + +//! Substitute for C++17 std::nullopt +static auto& nullopt = boost::none; + +#endif // BITCOIN_OPTIONAL_H diff --git a/src/pow.cpp b/src/pow.cpp index bbfb319..5fccf30 100755 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -35,10 +35,24 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead return Params().ProofOfWorkLimit().GetCompact(); } + // Target block time spacing + int64_t nTargetSpacing = Params().TargetSpacingLegacy(); + if (pindexLast->nHeight > Params().LAST_POW_BLOCK()) { uint256 bnTargetLimit = (~uint256(0) >> 24); - int64_t nTargetSpacing = 30; - int64_t nTargetTimespan = 60 * 40; + // Block time targeting + int64_t nTargetTimespan = Params().TargetTimespanLegacy(); + int64_t nInterval = Params().IntervalLegacy(); + + // New time activation check + bool fVerAct = CBlockIndex::IsSuperMajority(6, pindexLast, Params().RejectBlockOutdatedMajority()); + bool fUpgradeActiveV3 = Params().GetConsensus().NetworkUpgradeActive(pindexLast->nHeight, Consensus::UPGRADE_V3_0_BLOCKTIME); + // Actiavte on 95% upgrade threshold, or forced by upgrade block height. + if (fVerAct || fUpgradeActiveV3) { + nTargetSpacing = Params().TargetSpacing(); + nTargetTimespan = Params().TargetTimespan(); + nInterval = Params().Interval(); + } int64_t nActualSpacing = 0; if (pindexLast->nHeight != 0) @@ -52,7 +66,6 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead uint256 bnNew; bnNew.SetCompact(pindexLast->nBits); - int64_t nInterval = nTargetTimespan / nTargetSpacing; bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); @@ -92,7 +105,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead uint256 bnNew(PastDifficultyAverage); - int64_t _nTargetTimespan = CountBlocks * Params().TargetSpacing(); + int64_t _nTargetTimespan = CountBlocks * nTargetSpacing; if (nActualTimespan < _nTargetTimespan / 3) nActualTimespan = _nTargetTimespan / 3; diff --git a/src/primitives/block.h b/src/primitives/block.h index a924ea8..6a07e08 100755 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -26,7 +26,7 @@ class CBlockHeader { public: // header - static const int32_t CURRENT_VERSION=6; + static const int32_t CURRENT_VERSION = 7; // NOTE: If increment this, make sure to adjust miner.cpp !!! int32_t nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -53,8 +53,8 @@ class CBlockHeader READWRITE(nNonce); //zerocoin active, header changes to include accumulator checksum - if(nVersion > 5) - READWRITE(nAccumulatorCheckpoint); + /*if(nVersion > 5) + READWRITE(nAccumulatorCheckpoint);*/ } void SetNull() diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index c34e72a..9056ea8 100755 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -9,16 +9,20 @@ #include "checkpoints.h" #include "clientversion.h" #include "consensus/validation.h" +#include "consensus/upgrades.h" #include "main.h" #include "rpcserver.h" #include "sync.h" #include "txdb.h" #include "util.h" #include "utilmoneystr.h" +#include "kernel.h" #include #include +#include "karmanodeman.h" + using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, bool include_hex, int serialize_flags); @@ -82,6 +86,10 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); + int64_t KNPayment = GetKarmanodePayment(blockindex->nHeight, GetBlockValue(blockindex->nHeight)); + int64_t StakerPayment = blockindex->nMint - KNPayment; + double KNRewardPercent = floor(((double)KNPayment / (double)blockindex->nMint) * 100); + result.push_back(Pair("hash", block.GetHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain @@ -117,6 +125,16 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx if (pnext) result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.push_back(Pair("flags", strprintf("%s", blockindex->IsProofOfStake() ? "proof-of-stake" : "proof-of-work"))); + result.push_back(Pair("nflags:", strprintf("%i", blockindex->nFlags))); + result.push_back(Pair("mint", ValueFromAmount(GetBlockValue(blockindex->nHeight)))); + + result.push_back(Pair("knReward", ValueFromAmount(KNPayment))); + result.push_back(Pair("knRewardPercent", KNRewardPercent)); + result.push_back(Pair("stakerPayment", ValueFromAmount(StakerPayment))); + result.push_back(Pair("modifier", strprintf("%16x", blockindex->nStakeModifier))); + result.push_back(Pair("modifierchecksum", strprintf("%08x", GetStakeModifierChecksum(blockindex)))); + result.push_back(Pair("moneysupply",ValueFromAmount(blockindex->nMoneySupply))); UniValue zohmcObj(UniValue::VOBJ); @@ -550,6 +568,72 @@ UniValue verifychain(const UniValue& params, bool fHelp) return fVerified; } +/** Implementation of IsSuperMajority with better feedback */ +static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +{ + UniValue rv(UniValue::VOBJ); + Consensus::UpgradeIndex idx; + switch(version) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + idx = Consensus::BASE_NETWORK; + break; + case 7: + idx = Consensus::UPGRADE_V3_0_BLOCKTIME; + break; + default: + rv.push_back(Pair("status", false)); + return rv; + } + rv.push_back(Pair("status", consensusParams.NetworkUpgradeActive(pindex->nHeight, idx))); + return rv; +} +static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex) +{ + const Consensus::Params& consensus = Params().GetConsensus(); + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("version", version)); + rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensus))); + return rv; +} + +static UniValue NetworkUpgradeDesc(const Consensus::Params& consensusParams, Consensus::UpgradeIndex idx, int height) +{ + UniValue rv(UniValue::VOBJ); + auto upgrade = NetworkUpgradeInfo[idx]; + rv.push_back(Pair("activationheight", consensusParams.vUpgrades[idx].nActivationHeight)); + switch (NetworkUpgradeState(height, consensusParams, idx)) { + case UPGRADE_DISABLED: rv.push_back(Pair("status", "disabled")); break; + case UPGRADE_PENDING: rv.push_back(Pair("status", "pending")); break; + case UPGRADE_ACTIVE: rv.push_back(Pair("status", "active")); break; + } + rv.push_back(Pair("info", upgrade.strInfo)); + return rv; +} + +void NetworkUpgradeDescPushBack( + UniValue& networkUpgrades, + const Consensus::Params& consensusParams, + Consensus::UpgradeIndex idx, + int height) +{ + // Network upgrades with an activation height of NO_ACTIVATION_HEIGHT are + // hidden. This is used when network upgrade implementations are merged + // without specifying the activation height. + if (consensusParams.vUpgrades[idx].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + std::string name = NetworkUpgradeInfo[idx].strName; + std::replace(name.begin(), name.end(), '_', ' '); // Beautify the name + networkUpgrades.push_back(Pair( + name, + NetworkUpgradeDesc(consensusParams, idx, height))); + } +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -565,12 +649,29 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" + " \"softforks\": [ (array) status of softforks in progress\n" + " {\n" + " \"id\": \"xxxx\", (string) name of softfork\n" + " \"version\": xx, (numeric) block version\n" + " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n" + " \"status\": xx, (boolean) true if threshold reached\n" + " },\n" + " }, ...\n" + " ],\n" + " \"upgrades\": { (object) status of network upgrades\n" + " \"name\" : { (string) name of upgrade\n" + " \"activationheight\": xxxxxx, (numeric) block height of activation\n" + " \"status\": \"xxxx\", (string) status of upgrade\n" + " \"info\": \"xxxx\", (string) additional information about upgrade\n" + " }, ...\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") + HelpExampleRpc("getblockchaininfo", "")); LOCK(cs_main); + const Consensus::Params& consensusParams = Params().GetConsensus(); + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); @@ -579,6 +680,16 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + CBlockIndex* tip = chainActive.Tip(); + UniValue softforks(UniValue::VARR); + //softforks.push_back(SoftForkDesc("blocktime", 7, tip)); + obj.push_back(Pair("softforks", softforks)); + UniValue upgrades(UniValue::VOBJ); + for (int i = Consensus::BASE_NETWORK + 1; i < (int) Consensus::MAX_NETWORK_UPGRADES; i++) { + NetworkUpgradeDescPushBack(upgrades, consensusParams, Consensus::UpgradeIndex(i), tip->nHeight); + } + obj.push_back(Pair("upgrades", upgrades)); + return obj; } diff --git a/src/spork.cpp b/src/spork.cpp index bab0550..978516b 100755 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -136,6 +136,7 @@ int64_t GetSporkValue(int nSporkID) if (nSporkID == SPORK_20_SEGWIT_ACTIVATION) r = SPORK_20_SEGWIT_ACTIVATION_DEFAULT; if (nSporkID == SPORK_21_SEGWIT_ON_COINBASE) r = SPORK_21_SEGWIT_ON_COINBASE_DEFAULT; if (nSporkID == SPORK_22_ZEROCOIN_MAINTENANCE_MODE) r = SPORK_22_ZEROCOIN_MAINTENANCE_MODE_DEFAULT; + if (nSporkID == SPORK_23_NEW_BLOCKTIME_ENFORCEMENT) r = SPORK_23_NEW_BLOCKTIME_ENFORCEMENT_DEFAULT; if (r == -1) LogPrintf("GetSpork::Unknown Spork %d\n", nSporkID); @@ -287,6 +288,7 @@ int CSporkManager::GetSporkIDByName(std::string strName) if (strName == "SPORK_20_SEGWIT_ACTIVATION") return SPORK_20_SEGWIT_ACTIVATION; if (strName == "SPORK_21_SEGWIT_ON_COINBASE") return SPORK_21_SEGWIT_ON_COINBASE_DEFAULT; if (strName == "SPORK_22_ZEROCOIN_MAINTENANCE_MODE") return SPORK_22_ZEROCOIN_MAINTENANCE_MODE; + if (strName == "SPORK_23_NEW_BLOCKTIME_ENFORCEMENT") return SPORK_23_NEW_BLOCKTIME_ENFORCEMENT; return -1; } @@ -310,5 +312,6 @@ std::string CSporkManager::GetSporkNameByID(int id) if (id == SPORK_20_SEGWIT_ACTIVATION) return "SPORK_20_SEGWIT_ACTIVATION"; if (id == SPORK_21_SEGWIT_ON_COINBASE) return "SPORK_21_SEGWIT_ON_COINBASE"; if (id == SPORK_22_ZEROCOIN_MAINTENANCE_MODE) return "SPORK_22_ZEROCOIN_MAINTENANCE_MODE"; + if (id == SPORK_23_NEW_BLOCKTIME_ENFORCEMENT) return "SPORK_23_NEW_BLOCKTIME_ENFORCEMENT"; return "Unknown"; } diff --git a/src/spork.h b/src/spork.h index 1ed895b..41fcc9a 100755 --- a/src/spork.h +++ b/src/spork.h @@ -27,7 +27,7 @@ using namespace boost; Sporks 11,12, and 16 to be removed with 1st zerocoin release */ #define SPORK_START 10001 -#define SPORK_END 10021 +#define SPORK_END 10022 #define SPORK_2_SWIFTTX 10001 #define SPORK_3_SWIFTTX_BLOCK_FILTERING 10002 @@ -48,14 +48,15 @@ using namespace boost; #define SPORK_20_SEGWIT_ACTIVATION 10019 #define SPORK_21_SEGWIT_ON_COINBASE 10020 #define SPORK_22_ZEROCOIN_MAINTENANCE_MODE 10021 +#define SPORK_23_NEW_BLOCKTIME_ENFORCEMENT 10022 #define SPORK_2_SWIFTTX_DEFAULT 978307200 //2001-1-1 #define SPORK_3_SWIFTTX_BLOCK_FILTERING_DEFAULT 1424217600 //2015-2-18 #define SPORK_5_MAX_VALUE_DEFAULT 1000 //1000 OHMC -#define SPORK_7_KARMANODE_SCANNING_DEFAULT 978307200 //2001-1-1 -#define SPORK_8_KARMANODE_PAYMENT_ENFORCEMENT_DEFAULT 4070908800 //OFF -#define SPORK_9_KARMANODE_BUDGET_ENFORCEMENT_DEFAULT 4070908800 //OFF -#define SPORK_10_KARMANODE_PAY_UPDATED_NODES_DEFAULT 4070908800 //OFF +#define SPORK_7_KARMANODE_SCANNING_DEFAULT 978307200 //2001-1-1 +#define SPORK_8_KARMANODE_PAYMENT_ENFORCEMENT_DEFAULT 4070908800 //OFF +#define SPORK_9_KARMANODE_BUDGET_ENFORCEMENT_DEFAULT 4070908800 //OFF +#define SPORK_10_KARMANODE_PAY_UPDATED_NODES_DEFAULT 4070908800 //OFF //#define SPORK_11_LOCK_INVALID_UTXO_DEFAULT 4070908800 //OFF - NOTE: this is block height not time! #define SPORK_13_ENABLE_SUPERBLOCKS_DEFAULT 4070908800 //OFF #define SPORK_14_NEW_PROTOCOL_ENFORCEMENT_DEFAULT 4070908800 //ON @@ -66,9 +67,11 @@ using namespace boost; #define SPORK_19_MN_WINNER_MINIMUM_AGE_DEFAULT 8000 // Age in seconds. This should be > KARMANODE_REMOVAL_SECONDS to avoid // misconfigured new nodes in the list. // Set this to zero to emulate classic behaviour -#define SPORK_20_SEGWIT_ACTIVATION_DEFAULT 4070908800 //OFF -#define SPORK_21_SEGWIT_ON_COINBASE_DEFAULT 4070908800 //OFF +#define SPORK_20_SEGWIT_ACTIVATION_DEFAULT 4070908800 //OFF +#define SPORK_21_SEGWIT_ON_COINBASE_DEFAULT 4070908800 //OFF #define SPORK_22_ZEROCOIN_MAINTENANCE_MODE_DEFAULT 4070908800 //OFF +// Sporks that forces new blocktime upgrade and protocol 71020 +#define SPORK_23_NEW_BLOCKTIME_ENFORCEMENT_DEFAULT 4070908800 //OFF DEFAULT class CSporkMessage; class CSporkManager; diff --git a/src/version.h b/src/version.h index 60a7837..863acfd 100755 --- a/src/version.h +++ b/src/version.h @@ -12,7 +12,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 71011; +static const int PROTOCOL_VERSION = 71025; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -22,7 +22,7 @@ static const int GETHEADERS_VERSION = 70077; //! disconnect from peers older than this proto version static const int MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT = 71010; -static const int MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT = 71011; +static const int MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT = 71025; static const int MIN_PEER_VERSION_FIXED_SIGTIME = 70004; @@ -42,5 +42,7 @@ static const int MEMPOOL_GD_VERSION = 60002; //! "filter*" commands are disabled without NODE_BLOOM after and including this version static const int NO_BLOOM_VERSION = 70005; +//! In this version, the blocktime and reward structure were changed +static const int MIN_PEER_VERSION_ADJ_BLOCKTIME = 71020; #endif // BITCOIN_VERSION_H