Skip to content

Commit

Permalink
feat: changed activation way of MN reward location reallocation, adde…
Browse files Browse the repository at this point in the history
…d functional tests
  • Loading branch information
knst committed Apr 26, 2023
1 parent 36ab095 commit 5ea6da9
Show file tree
Hide file tree
Showing 15 changed files with 87 additions and 39 deletions.
31 changes: 31 additions & 0 deletions src/chainparams.cpp
Expand Up @@ -235,6 +235,13 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 2420; // 60% of 4032
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods

consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 19999999999; // TODO: To be determined later
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize = 4032;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdStart = 3226; // 80% of 4032
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdMin = 2420; // 60% of 4032
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nFalloffCoeff = 5; // this corresponds to 10 periods

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000082094584a23266cbb5f8"); // 1850400
Expand Down Expand Up @@ -466,6 +473,14 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods

consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 19999999999; // TODO: To be determined later
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize = 100;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdStart = 80; // 80% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nFalloffCoeff = 5; // this corresponds to 10 periods

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000000002d68cb6c090031f"); // 864000

Expand Down Expand Up @@ -669,6 +684,14 @@ class CDevNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods

consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 1661990400; // Sep 1st, 2022
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize = 120;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdStart = 80; // 80% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdMin = 60; // 60% of 100
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nFalloffCoeff = 5; // this corresponds to 10 periods

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000");

Expand Down Expand Up @@ -933,6 +956,14 @@ class CRegTestParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nThresholdMin = 288; // 60% of 480
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nFalloffCoeff = 5; // this corresponds to 10 periods

consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].bit = 10;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nTimeout = 999999999999ULL;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize = 1030;
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdStart = 800; // 80% of 1000
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nThresholdMin = 600; // 60% of 1000
consensus.vDeployments[Consensus::DEPLOYMENT_MN_RR].nFalloffCoeff = 5; // this corresponds to 10 periods

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");

Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Expand Up @@ -22,6 +22,7 @@ enum DeploymentPos {
DEPLOYMENT_DIP0024, // Deployment of DIP0024 (Quorum Rotation) and decreased governance proposal fee
DEPLOYMENT_V19, // Deployment of Basic BLS, AssetLocks
DEPLOYMENT_V20, // Deployment of EHF, LLMQ Randomness Beacon
DEPLOYMENT_MN_RR, // Deployment of Masternode Reward Location Reallocation
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
Expand Down
16 changes: 4 additions & 12 deletions src/evo/creditpool.cpp
Expand Up @@ -10,7 +10,6 @@
#include <chain.h>
#include <llmq/utils.h>
#include <logging.h>
#include <spork.h>
#include <util/validation.h>
#include <validation.h>

Expand Down Expand Up @@ -246,7 +245,8 @@ CCreditPoolManager::CCreditPoolManager(CEvoDB& _evoDb)

CCreditPoolDiff::CCreditPoolDiff(CCreditPool starter, const CBlockIndex *pindex, const Consensus::Params& consensusParams) :
pool(std::move(starter)),
pindex(pindex)
pindex(pindex),
params(consensusParams)
{
assert(pindex);
}
Expand All @@ -267,13 +267,13 @@ bool CCreditPoolDiff::setTarget(const CTransaction& tx, TxValidationState& state
targetLocked = cbTx.assetLockedAmount;


if (isIgnoringMNRewardReallocation(*sporkManager)) return true;
if (!llmq::utils::IsMNRewardReallocationActive(pindex)) return true;

CAmount blockReward = 0;
for (const CTxOut& txout : tx.vout) {
blockReward += txout.nValue;
}
masternodeReward = GetMasternodePayment(cbTx.nHeight, blockReward, Params().GetConsensus().BRRHeight);
masternodeReward = GetMasternodePayment(cbTx.nHeight, blockReward, params.BRRHeight);
LogPrintf("CreditPool: set target to %lld with MN reward %lld\n", *targetLocked, masternodeReward);

return true;
Expand Down Expand Up @@ -348,11 +348,3 @@ bool CCreditPoolDiff::processTransaction(const CTransaction& tx, TxValidationSta
return state.Invalid(TxValidationResult::TX_CONSENSUS, "failed-procassetlocksinblock");
}
}

bool isIgnoringMNRewardReallocation(const CSporkManager& spork_manager) {
if (Params().NetworkIDString() != CBaseChainParams::REGTEST) return false;

bool ret = spork_manager.IsSporkActive(SPORK_24_IGNORE_MN_REWARD_REALLOCED);
LogPrintf("%s: spork IGNORE_MN_REWARD_REALLOCED value: %d\n", __func__, ret);
return ret;
}
5 changes: 1 addition & 4 deletions src/evo/creditpool.h
Expand Up @@ -21,7 +21,6 @@

class CBlockIndex;
class TxValidationState;
class CSporkManager;

namespace Consensus
{
Expand Down Expand Up @@ -110,6 +109,7 @@ class CCreditPoolDiff {
std::optional<CAmount> targetLocked;

const CBlockIndex *pindex{nullptr};
const Consensus::Params& params;
public:
explicit CCreditPoolDiff(CCreditPool starter, const CBlockIndex *pindex, const Consensus::Params& consensusParams);

Expand All @@ -122,7 +122,6 @@ class CCreditPoolDiff {

/**
* This function should be called by miner for initalization of MasterNode reward
*
*/
void addRewardRealloced(const CAmount reward);

Expand Down Expand Up @@ -178,8 +177,6 @@ class CCreditPoolManager
CCreditPool constructCreditPool(const CBlockIndex* block_index, CCreditPool prev, const Consensus::Params& consensusParams);
};

bool isIgnoringMNRewardReallocation(const CSporkManager& spork_manager);

extern std::unique_ptr<CCreditPoolManager> creditPoolManager;

#endif
2 changes: 0 additions & 2 deletions src/evo/specialtxman.cpp
Expand Up @@ -17,10 +17,8 @@
#include <llmq/commitment.h>
#include <llmq/utils.h>
#include <primitives/block.h>
#include <spork.h>
#include <validation.h>

#include <masternode/payments.h>
bool CheckSpecialTx(const CTransaction& tx, const CBlockIndex* pindexPrev, const CCoinsViewCache& view, const CCreditPool& creditPool, bool check_sigs, TxValidationState& state)
{
AssertLockHeld(cs_main);
Expand Down
8 changes: 8 additions & 0 deletions src/llmq/utils.cpp
Expand Up @@ -678,6 +678,14 @@ bool IsV20Active(const CBlockIndex* pindex)
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache) == ThresholdState::ACTIVE;
}

bool IsMNRewardReallocationActive(const CBlockIndex* pindex)
{
if (!IsV20Active(pindex)) return false;

LOCK(cs_llmq_vbc);
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache) == ThresholdState::ACTIVE;
}

bool IsInstantSendLLMQTypeShared()
{
if (Params().GetConsensus().llmqTypeInstantSend == Params().GetConsensus().llmqTypeChainLocks ||
Expand Down
1 change: 1 addition & 0 deletions src/llmq/utils.h
Expand Up @@ -86,6 +86,7 @@ bool IsDIP0024Active(const CBlockIndex* pindex);
bool IsV19Active(const CBlockIndex* pindex);
const CBlockIndex* V19ActivationIndex(const CBlockIndex* pindex);
bool IsV20Active(const CBlockIndex* pindex);
bool IsMNRewardReallocationActive(const CBlockIndex* pindex);

/// Returns the state of `-llmq-data-recovery`
bool QuorumDataRecoveryEnabled();
Expand Down
9 changes: 6 additions & 3 deletions src/masternode/payments.cpp
Expand Up @@ -16,12 +16,12 @@
#include <masternode/sync.h>
#include <primitives/block.h>
#include <script/standard.h>
#include <spork.h>
#include <tinyformat.h>
#include <util/ranges.h>
#include <util/system.h>
#include <validation.h>
#include <evo/creditpool.h>

#include <string>

CMasternodePayments mnpayments;
Expand Down Expand Up @@ -280,8 +280,9 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward,

CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward, Params().GetConsensus().BRRHeight);

bool fV20Active_context = llmq::utils::IsV20Active(::ChainActive().Tip());
if (fV20Active_context && !isIgnoringMNRewardReallocation(*sporkManager)) {
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip());

if (fMNRewardReallocated) {
LogPrintf("CMasternodePayments::%s -- MN reward %lld reallocated to credit pool\n", __func__, masternodeReward);
voutMasternodePaymentsRet.emplace_back(masternodeReward, CScript() << OP_RETURN);
return true;
Expand All @@ -294,12 +295,14 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward,
}

CAmount operatorReward = 0;

if (dmnPayee->nOperatorReward != 0 && dmnPayee->pdmnState->scriptOperatorPayout != CScript()) {
// This calculation might eventually turn out to result in 0 even if an operator reward percentage is given.
// This will however only happen in a few years when the block rewards drops very low.
operatorReward = (masternodeReward * dmnPayee->nOperatorReward) / 10000;
masternodeReward -= operatorReward;
}

if (masternodeReward > 0) {
voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout);
}
Expand Down
4 changes: 2 additions & 2 deletions src/miner.cpp
Expand Up @@ -233,12 +233,12 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(CChainState& chai
}
assert(creditPoolDiff);

if (!isIgnoringMNRewardReallocation(spork_manager)) {
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev);
if (fMNRewardReallocated) {
if (!CMasternodePayments::GetMasternodeTxOuts(nHeight, blockReward, pblocktemplate->voutMasternodePayments)) {
LogPrint(BCLog::MNPAYMENTS, "%s -- no masternode to pay (MN list probably empty)\n", __func__);
}
for (const auto& txout : pblocktemplate->voutMasternodePayments) {
// subtract MN payment from miner reward
LogPrintf("CreateNewBlock() add MN reward %lld to credit pool\n", txout.nValue);
creditPoolDiff->addRewardRealloced(txout.nValue);
}
Expand Down
4 changes: 1 addition & 3 deletions src/spork.h
Expand Up @@ -38,7 +38,6 @@ enum SporkId : int32_t {
SPORK_19_CHAINLOCKS_ENABLED = 10018,
SPORK_21_QUORUM_ALL_CONNECTED = 10020,
SPORK_23_QUORUM_POSE = 10022,
SPORK_24_IGNORE_MN_REWARD_REALLOCED = 10023,

SPORK_INVALID = -1,
};
Expand All @@ -64,15 +63,14 @@ struct CSporkDef
};

#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef{name, defaultValue, #name}
[[maybe_unused]] static constexpr std::array<CSporkDef, 8> sporkDefs = {
[[maybe_unused]] static constexpr std::array<CSporkDef, 7> sporkDefs = {
MAKE_SPORK_DEF(SPORK_2_INSTANTSEND_ENABLED, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_3_INSTANTSEND_BLOCK_FILTERING, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_9_SUPERBLOCKS_ENABLED, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_17_QUORUM_DKG_ENABLED, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_21_QUORUM_ALL_CONNECTED, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_23_QUORUM_POSE, 4070908800ULL), // OFF
MAKE_SPORK_DEF(SPORK_24_IGNORE_MN_REWARD_REALLOCED, 4070908800ULL), // OFF
};
#undef MAKE_SPORK_DEF
extern std::unique_ptr<CSporkManager> sporkManager;
Expand Down
5 changes: 0 additions & 5 deletions src/test/evo_deterministicmns_tests.cpp
Expand Up @@ -271,11 +271,6 @@ void FuncDIP3Protx(TestChainSetup& setup)
sporkManager->SetSporkAddress(EncodeDestination(PKHash(sporkKey.GetPubKey())));
sporkManager->SetPrivKey(EncodeSecret(sporkKey));

// broadcast new spork
if (sporkManager->UpdateSpork(SporkId::SPORK_24_IGNORE_MN_REWARD_REALLOCED, 0, *setup.m_node.connman)) {
LogPrintf("spork SPORK_24_IGNORE_MN_REWARD_REALLOCED updated\n");
}

auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns);

int nHeight = ::ChainActive().Height();
Expand Down
7 changes: 6 additions & 1 deletion src/versionbitsinfo.cpp
Expand Up @@ -46,5 +46,10 @@ const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_B
/*.name =*/"v20",
/*.gbt_force =*/true,
/*.check_mn_protocol =*/false,
}
},
{
/*.name =*/"mn_rr",
/*.gbt_force =*/true,
/*.check_mn_protocol =*/false,
},
};
22 changes: 20 additions & 2 deletions test/functional/feature_asset_locks.py
Expand Up @@ -169,8 +169,6 @@ def set_sporks(self):
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", spork_disabled)
self.nodes[0].sporkupdate("SPORK_3_INSTANTSEND_BLOCK_FILTERING", spork_disabled)
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", spork_disabled)
self.nodes[0].sporkupdate("SPORK_24_IGNORE_MN_REWARD_REALLOCED", spork_enabled)

self.wait_for_sporks_same()

def ensure_tx_is_not_mined(self, tx_id):
Expand Down Expand Up @@ -496,5 +494,25 @@ def run_test(self):
assert_equal(new_total, get_credit_pool_amount(node))
assert_equal(node.getmempoolinfo()['size'], 0)

self.activate_mn_rr(expected_activation_height=3089)
self.log.info(f'height: {node.getblock(node.getbestblockhash())["height"]} credit: {get_credit_pool_amount(node)}')
reward = 6132959502
assert_equal(new_total, get_credit_pool_amount(node))
node.generate(1)
self.sync_all()
new_total += reward
assert_equal(new_total, get_credit_pool_amount(node))

coin = coins.pop()
self.send_tx(create_assetlock(node, coin, COIN, pubkey))
new_total += reward + COIN
node.generate(1)
self.sync_all()
# part of fee is going to master node reward
# these 2 conditions need to check a range
assert_greater_than(get_credit_pool_amount(node), new_total)
assert_greater_than(new_total + tiny_amount, get_credit_pool_amount(node))


if __name__ == '__main__':
AssetLocksTest().main()
3 changes: 0 additions & 3 deletions test/functional/feature_llmq_is_cl_conflicts.py
Expand Up @@ -20,7 +20,6 @@
from test_framework.test_framework import DashTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, hex_str_to_bytes, wait_until

from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE

class TestP2PConn(P2PInterface):
def __init__(self):
Expand Down Expand Up @@ -318,8 +317,6 @@ def create_block(self, node, vtx=None):

outputs = {miner_address: str(Decimal(miner_amount) / COIN)}
if mn_amount > 0:
if mn_payee is None or mn_payee == '':
mn_payee = ADDRESS_BCRT1_UNSPENDABLE
outputs[mn_payee] = str(Decimal(mn_amount) / COIN)

coinbase = FromHex(CTransaction(), node.createrawtransaction([], outputs))
Expand Down
8 changes: 6 additions & 2 deletions test/functional/test_framework/test_framework.py
Expand Up @@ -1050,8 +1050,9 @@ def activate_by_name(self, name, expected_activation_height=None):
assert not softfork_active(self.nodes[0], name)

while not softfork_active(self.nodes[0], name):
self.bump_mocktime(batch_size)
self.nodes[0].generate(batch_size)
next_batch = batch_size if expected_activation_height is None else 1
self.bump_mocktime(next_batch)
self.nodes[0].generate(next_batch)
self.sync_blocks()
self.sync_blocks()

Expand All @@ -1075,6 +1076,9 @@ def activate_v19(self, expected_activation_height=None):
def activate_v20(self, expected_activation_height=None):
self.activate_by_name('v20', expected_activation_height)

def activate_mn_rr(self, expected_activation_height=None):
self.activate_by_name('mn_rr', expected_activation_height)

def set_dash_llmq_test_params(self, llmq_size, llmq_threshold):
self.llmq_size = llmq_size
self.llmq_threshold = llmq_threshold
Expand Down

0 comments on commit 5ea6da9

Please sign in to comment.