diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index 3484c16eb0438..e3c4d0cff4134 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -60,8 +60,7 @@ void CActiveMasternodeManager::Init() LOCK(cs_main); if (!fMasternodeMode) return; - - if (!deterministicMNManager->IsDIP3Enforced()) return; + if (!FullDIP0003Mode()) return; // Check that our local network configuration is correct if (!fListen) { @@ -130,8 +129,7 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con LOCK(cs_main); if (!fMasternodeMode) return; - - if (!deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight)) return; + if (!FullDIP0003Mode()) return; if (state == MASTERNODE_READY) { auto mnList = deterministicMNManager->GetListForBlock(pindexNew->GetBlockHash()); diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 923e43dd8188f..3c4e447b2d9f4 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -118,7 +118,7 @@ static CBlock FindDevNetGenesisBlock(const Consensus::Params& params, const CBlo static Consensus::LLMQParams llmq5_60 = { .type = Consensus::LLMQ_5_60, .name = "llmq_5_60", - .size = 5, + .size = 3, .minSize = 3, .threshold = 3, @@ -221,16 +221,19 @@ class CMainParams : public CChainParams { consensus.nSuperblockCycle = 16616; consensus.nGovernanceMinQuorum = 10; consensus.nGovernanceFilterElements = 20000; + /////////////////////////////////////////////// + consensus.nGenerationAmount = 700000000 * COIN; + consensus.nGenerationHeight = 362250; + /////////////////////////////////////////////// consensus.nMasternodeMinimumConfirmations = 15; consensus.nMasternodeCollateral = 500000 * COIN; - consensus.nCollateralBugHeight = 331460; consensus.BIP34Height = 951; consensus.BIP34Hash = uint256S("0x000001f35e70f7c5705f64c6c5cc3dea9449e74d5b5c7cf74dad1bcca14a8012"); consensus.BIP65Height = 619382; consensus.BIP66Height = 245817; consensus.DIP0001Height = 12096; consensus.DIP0003Height = 330000; - consensus.DIP0003EnforcementHeight = NEVER32; + consensus.DIP0003EnforcementHeight = consensus.nGenerationHeight + 50; consensus.DIP0003EnforcementHash = uint256(); consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.posLimit = uint256S("0007ffff00000000000000000000000000000000000000000000000000000000"); @@ -251,39 +254,39 @@ class CMainParams : public CChainParams { consensus.nMinerConfirmationWindow = 2016; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = NEVER64; // Deployment of BIP68, BIP112, and BIP113. consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = NEVER64; // Deployment of DIP0001 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = NEVER64; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // Deployment of BIP147 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = NEVER64; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 50; // Deployment of DIP0003 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 50; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 10; // Deployment of DIP0008 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThreshold = 10; @@ -398,41 +401,44 @@ class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = "test"; - consensus.nSubsidyHalvingInterval = NEVER32; // unused + consensus.nSubsidyHalvingInterval = NEVER32; consensus.nMasternodePaymentsStartBlock = 50; consensus.nMasternodePaymentsIncreaseBlock = NEVER32; consensus.nMasternodePaymentsIncreasePeriod = NEVER32; consensus.nInstantSendConfirmationsRequired = 2; consensus.nInstantSendKeepLock = 6; - consensus.nInstantSendSigsRequired = 6; - consensus.nInstantSendSigsTotal = 10; - consensus.nBudgetPaymentsStartBlock = NEVER32; - consensus.nBudgetPaymentsCycleBlocks = NEVER32; - consensus.nBudgetPaymentsWindowBlocks = NEVER32; - consensus.nSuperblockStartBlock = NEVER32; - consensus.nSuperblockStartHash = uint256(); // do not check this on testnet - consensus.nSuperblockCycle = 24; // Superblocks can be issued hourly on testnet + consensus.nInstantSendSigsRequired = 2; + consensus.nInstantSendSigsTotal = 4; + consensus.nBudgetPaymentsStartBlock = 50; + consensus.nBudgetPaymentsCycleBlocks = 50; + consensus.nBudgetPaymentsWindowBlocks = 100; + consensus.nSuperblockStartBlock = 100; + consensus.nSuperblockStartHash = uint256(); + consensus.nSuperblockCycle = 24; consensus.nGovernanceMinQuorum = 1; consensus.nGovernanceFilterElements = 500; + /////////////////////////////////////////////// + consensus.nGenerationAmount = 700000000 * COIN; + consensus.nGenerationHeight = 80; + /////////////////////////////////////////////// consensus.nMasternodeMinimumConfirmations = 15; - consensus.nMasternodeCollateral = 5000 * COIN; - consensus.nCollateralBugHeight = 0; + consensus.nMasternodeCollateral = 1000 * COIN; consensus.BIP34Height = 1; consensus.BIP34Hash = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000"); consensus.BIP65Height = 0; consensus.BIP66Height = 0; consensus.DIP0001Height = 1; - consensus.DIP0003Height = 50; - consensus.DIP0003EnforcementHeight = 250; + consensus.DIP0003Height = 75; + consensus.DIP0003EnforcementHeight = consensus.nGenerationHeight + 50; consensus.DIP0003EnforcementHash = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000"); consensus.powLimit = uint256S("0000fffff0000000000000000000000000000000000000000000000000000000"); consensus.posLimit = uint256S("007ffff000000000000000000000000000000000000000000000000000000000"); - consensus.nLastPoWBlock = 125; - consensus.nPowTargetTimespan = 450; - consensus.nPowTargetSpacing = 150; + consensus.nLastPoWBlock = consensus.DIP0003Height; + consensus.nPowTargetTimespan = 60; + consensus.nPowTargetSpacing = 60; consensus.nPosTargetSpacing = consensus.nPowTargetSpacing; consensus.nPosTargetTimespan = consensus.nPowTargetTimespan; - consensus.nMinimumStakeValue = 10000 * COIN; + consensus.nMinimumStakeValue = 100 * COIN; consensus.nStakeMinAge = 10 * 60; consensus.nStakeMaxAge = 60 * 60 * 24 * 30; consensus.nModifierInterval = 60 * 20; @@ -442,40 +448,41 @@ class CTestNetParams : public CChainParams { consensus.nPowDGWHeight = NEVER32; // unused consensus.nRuleChangeActivationThreshold = 1512; consensus.nMinerConfirmationWindow = 2016; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = NEVER64; // Deployment of BIP68, BIP112, and BIP113. consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = NEVER64; // Deployment of DIP0001 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = NEVER64; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // Deployment of BIP147 consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1573325000; + consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = NEVER64; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 50; // Deployment of DIP0003 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].bit = 3; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nWindowSize = 100; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 50; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0003].nThreshold = 10; // Deployment of DIP0008 consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].bit = 4; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = 1544655600; - consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = NEVER32; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nWindowSize = 100; consensus.vDeployments[Consensus::DEPLOYMENT_DIP0008].nThreshold = 10; @@ -493,16 +500,26 @@ class CTestNetParams : public CChainParams { nDefaultPort = 29999; nPruneAfterHeight = 1000; - genesis = CreateGenesisBlock(1567646780, 24712, 0x1f00ffff, 1, 0 * COIN, true); + uint32_t nTime = 1573325000; + uint32_t nNonce = 0; + + if (nNonce == 0) { + while (UintToArith256(genesis.GetHash()) > + UintToArith256(consensus.powLimit)) + { + nNonce++; + genesis = CreateGenesisBlock(nTime, nNonce, 0x1f00ffff, 1, 0 * COIN, true); + if (nNonce % 128 == 0) printf("\rgenesis %08x", nNonce); + } + } + + genesis = CreateGenesisBlock(nTime, nNonce, 0x1f00ffff, 1, 0 * COIN, true); consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x0000d3b6747d6f7fe976c218fe7834d2fa79b661a6debe69a0af9b8faea3b0fa")); vFixedSeeds.clear(); vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); vSeeds.clear(); - vSeeds.push_back(CDNSSeedData("pacglobal.io", "seed2.pacglobal.io")); - vSeeds.push_back(CDNSSeedData("pacglobal.io", "seed3.pacglobal.io")); // Testnet PACGlobal addresses start with 'y' base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,140); @@ -519,25 +536,23 @@ class CTestNetParams : public CChainParams { nExtCoinType = 1; // long living quorum params - consensus.llmqs[Consensus::LLMQ_50_60] = llmq50_60; - consensus.llmqs[Consensus::LLMQ_400_60] = llmq400_60; - consensus.llmqs[Consensus::LLMQ_400_85] = llmq400_85; - consensus.llmqChainLocks = Consensus::LLMQ_50_60; - consensus.llmqForInstaPAC = Consensus::LLMQ_50_60; + consensus.llmqs[Consensus::LLMQ_5_60] = llmq5_60; + consensus.llmqChainLocks = Consensus::LLMQ_5_60; + consensus.llmqForInstaPAC = Consensus::LLMQ_5_60; fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; - fRequireStandard = false; + fRequireStandard = true; fRequireRoutableExternalIP = false; fMineBlocksOnDemand = false; - fAllowMultipleAddressesFromGroup = false; + fAllowMultipleAddressesFromGroup = true; fAllowMultiplePorts = true; nPoolMinParticipants = 3; nPoolMaxParticipants = 5; nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes - vSporkAddresses = {"yarEgAKyKCAanupC45vXhdWe6DAQf7RKPh"}; + vSporkAddresses = {"yTpFjxs3Rtwe7MXfC1i5XACz2K5UYi2GpL"}; nMinSporkKeys = 1; fBIP9CheckMasternodesUpgraded = true; @@ -582,7 +597,6 @@ class CDevNetParams : public CChainParams { consensus.nGovernanceFilterElements = 500; consensus.nMasternodeMinimumConfirmations = 1; consensus.nMasternodeCollateral = 500000 * COIN; - consensus.nCollateralBugHeight = 0; consensus.BIP34Height = 1; // BIP34 activated immediately on devnet consensus.BIP65Height = 1; // BIP65 activated immediately on devnet consensus.BIP66Height = 1; // BIP66 activated immediately on devnet diff --git a/src/chainparamsseeds.h b/src/chainparamsseeds.h index 286ee99c4404c..f7d9e546406ec 100644 --- a/src/chainparamsseeds.h +++ b/src/chainparamsseeds.h @@ -8,17 +8,7 @@ * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. */ static SeedSpec6 pnSeed6_main[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xcb,0x9a,0x6e}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xcb,0x9b,0x1a}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xcb,0x37,0x86}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x74,0xcb,0xdd,0xf9}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0xa3,0x29}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd9,0x0b,0x8d}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd9,0x0b,0x8c}, 7112}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x5f,0xd8,0x98,0x22}, 7112} }; static SeedSpec6 pnSeed6_test[] = { - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x9d,0xe6,0xf4,0xe9}, 29999}, - {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xa5,0x16,0x64,0x7f}, 29999} }; #endif // PAC_CHAINPARAMSSEEDS_H diff --git a/src/consensus/params.h b/src/consensus/params.h index c23fea1ec44ba..221f72cb084e3 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -39,6 +39,13 @@ struct BIP9Deployment { int64_t nWindowSize; /** A number of blocks, in the range of 1..nWindowSize, which must signal for a fork in order to lock it in. */ int64_t nThreshold; + /** Constant for nTimeout very far in the future. */ + static constexpr int64_t NO_TIMEOUT = std::numeric_limits::max(); + /** Special value for nStartTime indicating that the deployment is always active. + * This is useful for testing, as it means tests don't need to deal with the activation + * process (which takes at least 3 BIP9 intervals). Only tests that specifically test the + * behaviour during activation cannot use this. */ + static constexpr int64_t ALWAYS_ACTIVE = -1; }; enum LLMQType : uint8_t @@ -136,9 +143,10 @@ struct Params { int nSuperblockCycle; // in blocks int nGovernanceMinQuorum; // Min absolute vote count to trigger an action int nGovernanceFilterElements; + CAmount nGenerationAmount; + int nGenerationHeight; int nMasternodeMinimumConfirmations; CAmount nMasternodeCollateral; - int nCollateralBugHeight; /** Block height and hash at which BIP34 becomes active */ int BIP34Height; uint256 BIP34Hash; diff --git a/src/evo/cbtx.cpp b/src/evo/cbtx.cpp index 85ed1c297e986..0c829253668ba 100644 --- a/src/evo/cbtx.cpp +++ b/src/evo/cbtx.cpp @@ -38,12 +38,12 @@ bool CheckCbTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidatio return state.DoS(100, false, REJECT_INVALID, "bad-cbtx-height"); } - if (pindexPrev) { - bool fDIP0008Active = VersionBitsState(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_DIP0008, versionbitscache) == THRESHOLD_ACTIVE; - if (fDIP0008Active && cbTx.nVersion < 2) { - return state.DoS(100, false, REJECT_INVALID, "bad-cbtx-version"); - } - } +// if (pindexPrev) { +// bool fDIP0008Active = VersionBitsState(pindexPrev, Params().GetConsensus(), Consensus::DEPLOYMENT_DIP0008, versionbitscache) == THRESHOLD_ACTIVE; +// if (fDIP0008Active && cbTx.nVersion < 2) { +// return state.DoS(100, false, REJECT_INVALID, "bad-cbtx-version"); +// } +// } return true; } diff --git a/src/evo/providertx.cpp b/src/evo/providertx.cpp index ada2b45eb9418..6b239d0d1d7c3 100644 --- a/src/evo/providertx.cpp +++ b/src/evo/providertx.cpp @@ -185,12 +185,6 @@ bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValid if (mnList.HasUniqueProperty(ptx.keyIDOwner) || mnList.HasUniqueProperty(ptx.pubKeyOperator)) { return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-key"); } - - if (!deterministicMNManager->IsDIP3Enforced(pindexPrev->nHeight)) { - if (ptx.keyIDOwner != ptx.keyIDVoting) { - return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-not-same"); - } - } } if (!CheckInputsHash(tx, ptx, state)) { @@ -330,15 +324,10 @@ bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal } } - if (!deterministicMNManager->IsDIP3Enforced(pindexPrev->nHeight)) { - if (dmn->pdmnState->keyIDOwner != ptx.keyIDVoting) { - return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-not-same"); - } - } - if (!CheckInputsHash(tx, ptx, state)) { return false; } + if (!CheckHashSig(ptx, dmn->pdmnState->keyIDOwner, state)) { return false; } diff --git a/src/governance.cpp b/src/governance.cpp index 18a2b11812a19..a6c4d6c182267 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -1268,9 +1268,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& co nCachedBlockHeight = pindex->nHeight; LogPrint("gobject", "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight); - if (deterministicMNManager->IsDIP3Enforced(pindex->nHeight)) { - RemoveInvalidVotes(); - } + RemoveInvalidVotes(); CheckPostponedObjects(connman); diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 9a032b0169949..e394ed5ba4607 100644 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -147,9 +147,7 @@ bool CDKGSessionHandler::InitNewQuorum(int newQuorumHeight, const uint256& newQu curSession = std::make_shared(params, blsWorker, dkgManager); - if (!deterministicMNManager->IsDIP3Enforced(newQuorumHeight)) { - return false; - } + if (!FullDIP0003Mode()) return false; auto mns = CLLMQUtils::GetAllQuorumMembers(params.type, newQuorumHash); diff --git a/src/llmq/quorums_dkgsessionmgr.cpp b/src/llmq/quorums_dkgsessionmgr.cpp index c68d95d00ad8d..534da421e5dca 100644 --- a/src/llmq/quorums_dkgsessionmgr.cpp +++ b/src/llmq/quorums_dkgsessionmgr.cpp @@ -56,8 +56,9 @@ void CDKGSessionManager::UpdatedBlockTip(const CBlockIndex* pindexNew, bool fIni if (fInitialDownload) return; - if (!deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight)) - return; + + if (!FullDIP0003Mode()) return; + if (!sporkManager.IsSporkActive(SPORK_17_QUORUM_DKG_ENABLED)) return; diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index c7e77617a51f8..1be10777a10b8 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -21,49 +21,6 @@ CMasternodePayments mnpayments; -bool IsOldBudgetBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet) { - const Consensus::Params& consensusParams = Params().GetConsensus(); - bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); - - if (nBlockHeight < consensusParams.nBudgetPaymentsStartBlock) { - strErrorRet = strprintf("Incorrect block %d, old budgets are not activated yet", nBlockHeight); - return false; - } - - if (nBlockHeight >= consensusParams.nSuperblockStartBlock) { - strErrorRet = strprintf("Incorrect block %d, old budgets are no longer active", nBlockHeight); - return false; - } - - // we are still using budgets, but we have no data about them anymore, - // all we know is predefined budget cycle and window - - int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks; - if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock && - nOffset < consensusParams.nBudgetPaymentsWindowBlocks) { - // NOTE: old budget system is disabled since 12.1 - if(masternodeSync.IsSynced()) { - // no old budget blocks should be accepted here on mainnet, - // testnet/devnet/regtest should produce regular blocks only - LogPrint("gobject", "%s -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n", __func__); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - return isBlockRewardValueMet; - } - // when not synced, rely on online nodes (all networks) - LogPrint("gobject", "%s -- WARNING: Skipping old budget block value checks, accepting block\n", __func__); - return true; - } - // LogPrint("gobject", "%s -- Block is not in budget cycle window, checking block value against block reward\n", __func__); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - return isBlockRewardValueMet; -} - /** * IsBlockValueValid * @@ -77,65 +34,57 @@ bool IsOldBudgetBlockValueValid(const CBlock& block, int nBlockHeight, CAmount b bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet) { - const Consensus::Params& consensusParams = Params().GetConsensus(); - bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); + int n = block.IsProofOfStake() ? 1 : 0; + CAmount nValueIn = 0; + if (block.IsProofOfStake()) { + CCoinsViewCache view(pcoinsTip); + nValueIn += view.GetValueIn(*block.vtx[1]); + } - strErrorRet = ""; + CAmount blockValue = block.vtx[n]->GetValueOut() - nValueIn; + bool isBlockRewardValueMet = (blockValue <= blockReward); - bool isProofOfStake = !block.IsProofOfWork(); - const auto& coinbaseTransaction = block.vtx[isProofOfStake]; + strErrorRet = ""; - if (nBlockHeight < consensusParams.nBudgetPaymentsStartBlock) { - // old budget system is not activated yet, just make sure we do not exceed the regular block reward - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are not activated yet", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - return isBlockRewardValueMet; - } else if (nBlockHeight < consensusParams.nSuperblockStartBlock) { - // superblocks are not enabled yet, check if we can pass old budget rules - return IsOldBudgetBlockValueValid(block, nBlockHeight, blockReward, strErrorRet); - } + LogPrintf(" - blockValue %lld <= blockReward %lld\n", blockValue, blockReward); - if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward); + CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight); + bool isSuperblockMaxValueMet = (blockValue <= nSuperblockMaxValue); - CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight); - bool isSuperblockMaxValueMet = (block.vtx[0]->GetValueOut() <= nSuperblockMaxValue); + LogPrintf(" - blockValue %lld <= nSuperblockMaxValue %lld\n", blockValue, nSuperblockMaxValue); - LogPrint("gobject", "block.vtx[0]->GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0]->GetValueOut(), nSuperblockMaxValue); + bool isGenerationHeight = (nBlockHeight == Params().GetConsensus().nGenerationHeight); + if (isGenerationHeight) + return true; if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) { // can't possibly be a superblock, so lets just check for block reward limits if (!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height", nBlockHeight, blockValue, blockReward); } return isBlockRewardValueMet; } // bail out in case superblock limits were exceeded if (!isSuperblockMaxValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value", - nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue); + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value", nBlockHeight, blockValue, nSuperblockMaxValue); return false; } - if(!masternodeSync.IsSynced() || fLiteMode) { - if(fDebug) LogPrintf("%s -- WARNING: Not enough data, checked superblock max bounds only\n", __func__); + if (!masternodeSync.IsSynced() || fLiteMode) { + LogPrintf(" - %s -- WARNING: Not enough data, checked superblock max bounds only\n", __func__); // not enough data for full checks but at least we know that the superblock limits were honored. // We rely on the network to have followed the correct chain in this case return true; } // we are synced and possibly on a superblock now - if (!sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) { // should NOT allow superblocks at all, when superblocks are disabled // revert to block reward limits in this case - LogPrint("gobject", "%s -- Superblocks are disabled, no superblocks allowed\n", __func__); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + LogPrintf(" - %s -- Superblocks are disabled, no superblocks allowed\n", __func__); + if (!isBlockRewardValueMet) { + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled", nBlockHeight, blockValue, blockReward); } return isBlockRewardValueMet; } @@ -143,17 +92,17 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar if (!CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { // we are on a valid superblock height but a superblock was not triggered // revert to block reward limits in this case - if(!isBlockRewardValueMet) { + if (!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + nBlockHeight, blockValue, blockReward); } return isBlockRewardValueMet; } // this actually also checks for correct payees and not only amount - if (!CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { + if (!CSuperblockManager::IsValid(*block.vtx[n], nBlockHeight, blockReward)) { // triggered but invalid? that's weird - LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[0]->ToString()); + LogPrintf(" - %s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[n]->ToString()); // should NOT allow invalid superblocks, when superblocks are enabled strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); return false; @@ -165,6 +114,22 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) { + // for nGenerationAmount - make sure this only ever goes to the spork key + if (nBlockHeight == Params().GetConsensus().nGenerationHeight) { + CBitcoinAddress address = Params().SporkAddresses().front(); + CScript payeeAddr = GetScriptForDestination(address.Get()); + for (const auto& tx : txNew.vout) { + if (tx.nValue == Params().GetConsensus().nGenerationAmount) { + if (tx.scriptPubKey == payeeAddr) { + LogPrintf("Found correct recipient at height %d\n", nBlockHeight); + return true; + } + } + } + LogPrintf("Didn't find correct recipient at height %d\n", nBlockHeight); + return false; + } + if(fLiteMode) { //there is no budget data to use to check anything, let's just accept the longest chain if(fDebug) LogPrintf("%s -- WARNING: Not enough data, skipping block payee checks\n", __func__); @@ -229,6 +194,15 @@ void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blo LogPrint("mnpayments", "%s -- no masternode to pay (MN list probably empty)\n", __func__); } + /////////////////////////////////////////////////////////////////////////////////////// + if (nBlockHeight == Params().GetConsensus().nGenerationHeight) { + CBitcoinAddress address = Params().SporkAddresses().front(); + CScript payeeAddr = GetScriptForDestination(address.Get()); + CTxOut managementTx = CTxOut(Params().GetConsensus().nGenerationAmount, payeeAddr); + txNew.vout.push_back(managementTx); + } + /////////////////////////////////////////////////////////////////////////////////////// + txNew.vout.insert(txNew.vout.end(), voutMasternodePaymentsRet.begin(), voutMasternodePaymentsRet.end()); txNew.vout.insert(txNew.vout.end(), voutSuperblockPaymentsRet.begin(), voutSuperblockPaymentsRet.end()); @@ -361,6 +335,9 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward, // -- Only look ahead up to 8 blocks to allow for propagation of the latest 2 blocks of votes bool CMasternodePayments::IsScheduled(const CDeterministicMNCPtr& dmnIn, int nNotBlockHeight) const { + // can't verify historical blocks here + if (!FullDIP0003Mode()) return true; + auto projectedPayees = deterministicMNManager->GetListAtChainTip().GetProjectedMNPayees(8); for (const auto &dmn : projectedPayees) { if (dmn->proTxHash == dmnIn->proTxHash) { @@ -372,11 +349,6 @@ bool CMasternodePayments::IsScheduled(const CDeterministicMNCPtr& dmnIn, int nNo bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const { - if (!deterministicMNManager->IsDIP3Enforced(nBlockHeight)) { - // can't verify historical blocks here - return true; - } - std::vector voutMasternodePayments; if (!GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePayments)) { LogPrintf("CMasternodePayments::%s -- ERROR failed to get payees for block at height %s\n", __func__, nBlockHeight); @@ -395,6 +367,7 @@ bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlo CTxDestination dest; if (!ExtractDestination(txout.scriptPubKey, dest)) assert(false); + LogPrintf("found -> %s\n", txNew.ToString().c_str()); LogPrintf("CMasternodePayments::%s -- ERROR failed to find expected payee %s in block at height %s\n", __func__, CBitcoinAddress(dest).ToString(), nBlockHeight); return false; } diff --git a/src/masternode-sync.cpp b/src/masternode-sync.cpp index 5f5744a3aa7d8..67d571609bc06 100644 --- a/src/masternode-sync.cpp +++ b/src/masternode-sync.cpp @@ -184,7 +184,9 @@ void CMasternodeSync::ProcessTick(CConnman& connman) // NORMAL NETWORK MODE - TESTNET/MAINNET { - if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) { + if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync") && + Params().NetworkIDString() == CBaseChainParams::MAIN) + { // We already fully synced from this node recently, // disconnect to free this connection slot for another peer. pnode->fDisconnect = true; diff --git a/src/miner.cpp b/src/miner.cpp index 27ba61c20782e..f2427d5ce5491 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -171,27 +171,26 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc // Create coinbase transaction. CMutableTransaction coinbaseTx; + CMutableTransaction coinstakeTx; coinbaseTx.vin.resize(1); coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; CAmount blockReward = GetBlockSubsidy(pindexPrev->nHeight, Params().GetConsensus()); std::vector vwtxPrev; + bool fStakeFound = false; if(fProofOfStake) { assert(pwalletMain); boost::this_thread::interruption_point(); pblock->nBits = GetNextWorkRequired(pindexPrev, chainparams.GetConsensus()); - CMutableTransaction coinstakeTx; int64_t nSearchTime = pblock->nTime; // search to current time - bool fStakeFound = false; if (nSearchTime >= nLastCoinStakeSearchTime) { unsigned int nTxNewTime = 0; if (pwalletMain->CreateCoinStake(*pwalletMain, pblock->nBits, blockReward, coinstakeTx, nTxNewTime, vwtxPrev)) { pblock->nTime = nTxNewTime; coinbaseTx.vout[0].SetEmpty(); FillBlockPayments(coinstakeTx, nHeight, blockReward, pblocktemplate->voutMasternodePayments, pblocktemplate->voutSuperblockPayments); - pblock->vtx.emplace_back(MakeTransactionRef(coinstakeTx)); fStakeFound = true; } nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; @@ -254,11 +253,14 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc throw std::runtime_error(strprintf("%s: CalcCbTxMerkleRootQuorums failed: %s", __func__, FormatStateMessage(state))); } } - SetTxPayload(coinbaseTx, cbTx); } pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx)); + if (fStakeFound) { + pblock->vtx.resize(pblock->vtx.size() + 1); + pblock->vtx[1] = MakeTransactionRef(std::move(coinstakeTx)); + } pblocktemplate->vTxFees[0] = -nFees; // Fill in header diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index c7a2084e2fb56..ee6a7218ddf87 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -104,8 +104,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason) reason = "bare-multisig"; return false; } else if (txout.IsDust(MinRelayFee())) { - reason = "dust"; - return false; + return true; } } diff --git a/src/pow.cpp b/src/pow.cpp index a61eb13605f2e..e8b747829bbe2 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -20,6 +20,42 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta return pindex; } +unsigned int Lwma3CalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params) +{ + const int64_t T = params.nPosTargetSpacing; + const int64_t N = 150; + const int64_t k = N * (N + 1) * T / 2; + const int64_t height = pindexLast->nHeight; + const arith_uint256 powLimit = UintToArith256(params.powLimit); + + if (height < N) { return powLimit.GetCompact(); } + + arith_uint256 sumTarget, nextTarget; + int64_t thisTimestamp, previousTimestamp; + int64_t t = 0, j = 0; + + const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor(height - N); + previousTimestamp = blockPreviousTimestamp->GetBlockTime(); + + // Loop through N most recent blocks. + for (int64_t i = height - N + 1; i <= height; i++) { + const CBlockIndex* block = pindexLast->GetAncestor(i); + thisTimestamp = (block->GetBlockTime() > previousTimestamp) ? + block->GetBlockTime() : previousTimestamp + 1; + int64_t solvetime = std::min(6 * T, thisTimestamp - previousTimestamp); + previousTimestamp = thisTimestamp; + j++; + t += solvetime * j; // Weighted solvetime sum. + arith_uint256 target; + target.SetCompact(block->nBits); + sumTarget += target / (k * N); + } + nextTarget = t * sumTarget; + if (nextTarget > powLimit) { nextTarget = powLimit; } + + return nextTarget.GetCompact(); +} + unsigned int DualKGW3(const CBlockIndex* pindexLast, bool fProofOfStake, const Consensus::Params& params) { const CBlockIndex *BlockLastSolved = pindexLast; @@ -262,12 +298,14 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const Consensus: if (Params().NetworkIDString() == CBaseChainParams::TESTNET) { if (pindexLast->nHeight + 1 > params.nLastPoWBlock) - return DualKGW3(pindexLast, true, params); + return Lwma3CalculateNextWorkRequired(pindexLast, params); return UintToArith256(params.powLimit).GetCompact(); } else { // proof of stake + if (pindexLast->nHeight + 1 > params.DIP0003EnforcementHeight) + return Lwma3CalculateNextWorkRequired(pindexLast, params); if (pindexLast->nHeight + 1 > params.nLastPoWBlock + nDiffSmoothingPeriod) return DualKGW3(pindexLast, true, params); if (pindexLast->nHeight + 1 > params.nLastPoWBlock) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 23fca8d2a78d8..2ff08002f245a 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -366,8 +366,6 @@ struct CMutableTransaction */ uint256 GetHash() const; - std::string ToString() const; - friend bool operator==(const CMutableTransaction& a, const CMutableTransaction& b) { return a.GetHash() == b.GetHash(); @@ -378,6 +376,7 @@ struct CMutableTransaction return !(a == b); } + std::string ToString() const; }; typedef std::shared_ptr CTransactionRef; diff --git a/src/validation.cpp b/src/validation.cpp index e809c71ee565e..90da000c40802 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1200,7 +1200,10 @@ CAmount GetBlockSubsidy(int nPrevBits, int nPrevHeight, const Consensus::Params& return 1000000 * COIN; } - return GetMasternodePayment(nPrevHeight + 1, 0) + (1 * COIN); + if (nPrevHeight + 1 < Params().GetConsensus().DIP0003EnforcementHeight) + return GetMasternodePayment(nPrevHeight + 1, 0) + (1 * COIN); + else + return GetMasternodePayment(nPrevHeight + 1, 0) + (100 * COIN); } // proof of work @@ -2323,7 +2326,9 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd int64_t nTime5_3 = GetTimeMicros(); nTimeValueValid += nTime5_3 - nTime5_2; LogPrint("bench", " - IsBlockValueValid: %.2fms [%.2fs]\n", 0.001 * (nTime5_3 - nTime5_2), nTimeValueValid * 0.000001); - if (!IsBlockPayeeValid(*block.vtx[0], pindex->nHeight, blockReward)) { + bool isProofOfStake = !block.IsProofOfWork(); + const auto& coinbaseTransaction = block.vtx[isProofOfStake]; + if (!IsBlockPayeeValid(*block.vtx[isProofOfStake], pindex->nHeight, blockReward)) { mapRejectedBlocks.insert(std::make_pair(block.GetHash(), GetTime())); return state.DoS(0, error("ConnectBlock(PAC): couldn't find masternode or superblock payments"), REJECT_INVALID, "bad-cb-payee"); @@ -2332,12 +2337,8 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd int64_t nTime5_4 = GetTimeMicros(); nTimePayeeValid += nTime5_4 - nTime5_3; LogPrint("bench", " - IsBlockPayeeValid: %.2fms [%.2fs]\n", 0.001 * (nTime5_4 - nTime5_3), nTimePayeeValid * 0.000001); - bool isProofOfStake = !block.IsProofOfWork(); - const auto& coinbaseTransaction = block.vtx[isProofOfStake]; - if (!ProcessSpecialTxsInBlock(block, pindex, state, fJustCheck, fScriptChecks)) { - return error("ConnectBlock(PAC): ProcessSpecialTxsInBlock for block %s failed with %s", - pindex->GetBlockHash().ToString(), FormatStateMessage(state)); + return error("ConnectBlock(PAC): ProcessSpecialTxsInBlock for block failed with %s", FormatStateMessage(state)); } int64_t nTime5_5 = GetTimeMicros(); nTimeProcessSpecial += nTime5_5 - nTime5_4; @@ -4848,6 +4849,11 @@ int ConfirmationsPerNetwork() { CBaseChainParams::TESTNET ? 20 : 100); } +//! Returns whether full DIP3 enforcement is active +bool FullDIP0003Mode() { + return (chainActive.Height() > Params().GetConsensus().DIP0003EnforcementHeight); +} + class CMainCleanup { public: diff --git a/src/validation.h b/src/validation.h index a26f2ee59db08..9105f0b0291e3 100644 --- a/src/validation.h +++ b/src/validation.h @@ -604,6 +604,9 @@ bool IgnoreSigopsLimits(int nHeight); //! Returns true if we have entered PoS consensus state bool IsPoS(); +//! Returns whether full DIP3 enforcement is active +bool FullDIP0003Mode(); + //! Return the current minimum relay tx fee CFeeRate CurrentRelayFee(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 02342cc96de46..bd04ed7d613d2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2807,6 +2807,10 @@ bool CWallet::SelectCoins(const std::vector& vAvailableCoins, const CAm if(!out.fSpendable) continue; + // never select from collateral type amounts + if (out.tx->tx->vout[out.i].nValue == Params().GetConsensus().nMasternodeCollateral) + continue; + if(nCoinType == ONLY_DENOMINATED) { COutPoint outpoint = COutPoint(out.tx->GetHash(),out.i); int nRounds = GetCappedOutpointPrivateSendRounds(outpoint); @@ -3345,11 +3349,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT return false; } - if (recipient.nAmount < COIN && nExtraPayloadSize == 0) - { - strFailReason = _("Output amounts must be equal to or greater than 1 PAC"); - return false; - } nValue += recipient.nAmount; if (recipient.fSubtractFeeFromAmount) @@ -3436,20 +3435,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT txout.nValue -= nFeeRet % nSubtractFeeFromAmount; } } - - if (txout.IsDust(MinRelayFee())) - { - if (recipient.fSubtractFeeFromAmount && nFeeRet > 0) - { - if (txout.nValue < 0) - strFailReason = _("The transaction amount is too small to pay the fee"); - else - strFailReason = _("The transaction amount is too small to send after the fee has been deducted"); - } - else - strFailReason = _("Transaction amount too small"); - return false; - } txNew.vout.push_back(txout); }