Skip to content

Commit

Permalink
feat: new spork SPORK_24_MN_RR_READY to signalize than EHF signal for…
Browse files Browse the repository at this point in the history
… new release can be signed
  • Loading branch information
knst committed Oct 6, 2023
1 parent dd17803 commit 0237234
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/llmq/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ LLMQContext::LLMQContext(CChainState& chainstate, CConnman& connman, CEvoDB& evo
llmq::quorumInstantSendManager = std::make_unique<llmq::CInstantSendManager>(*llmq::chainLocksHandler, chainstate, connman, *llmq::quorumManager, *sigman, *shareman, sporkman, mempool, *::masternodeSync, peerman, unit_tests, wipe);
return llmq::quorumInstantSendManager.get();
}()},
ehfSignalsHandler{std::make_unique<llmq::CEHFSignalsHandler>(chainstate, connman, *sigman, *shareman, *llmq::quorumManager, mempool, mnhfman)}
ehfSignalsHandler{std::make_unique<llmq::CEHFSignalsHandler>(chainstate, connman, *sigman, *shareman, sporkman, *llmq::quorumManager, mempool, mnhfman)}
{
// NOTE: we use this only to wipe the old db, do NOT use it for anything else
// TODO: remove it in some future version
Expand Down
13 changes: 8 additions & 5 deletions src/llmq/ehf_signals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,23 @@

#include <index/txindex.h> // g_txindex

#include <validation.h>
#include <txmempool.h>
#include <primitives/transaction.h>
#include <spork.h>
#include <txmempool.h>
#include <validation.h>

namespace llmq {


CEHFSignalsHandler::CEHFSignalsHandler(CChainState& chainstate, CConnman& connman,
CSigningManager& sigman, CSigSharesManager& shareman,
CQuorumManager& qman, CTxMemPool& mempool,
CSporkManager& sporkman, CQuorumManager& qman, CTxMemPool& mempool,
CMNHFManager& mnhfManager) :
chainstate(chainstate),
connman(connman),
sigman(sigman),
shareman(shareman),
sporkman(sporkman),
qman(qman),
mempool(mempool),
mnhfManager(mnhfManager)
Expand Down Expand Up @@ -54,8 +56,9 @@ void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew)
return;
}


trySignEHFSignal(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit, pindexNew);
if (sporkman.IsSporkActive(SPORK_24_MN_RR_READY)) {
trySignEHFSignal(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit, pindexNew);
}
}

void CEHFSignalsHandler::trySignEHFSignal(int bit, const CBlockIndex* const pindex)
Expand Down
4 changes: 3 additions & 1 deletion src/llmq/ehf_signals.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

class CChainState;
class CConnman;
class CSporkManager;
class CTxMemPool;

namespace llmq
Expand All @@ -29,6 +30,7 @@ class CEHFSignalsHandler : public CRecoveredSigsListener
CConnman& connman;
CSigningManager& sigman;
CSigSharesManager& shareman;
CSporkManager& sporkman;
CQuorumManager& qman;
CTxMemPool& mempool;
CMNHFManager& mnhfManager;
Expand All @@ -37,7 +39,7 @@ class CEHFSignalsHandler : public CRecoveredSigsListener
public:
explicit CEHFSignalsHandler(CChainState& chainstate, CConnman& connman,
CSigningManager& sigman, CSigSharesManager& shareman,
CQuorumManager& qman, CTxMemPool& mempool,
CSporkManager& sporkman, CQuorumManager& qman, CTxMemPool& mempool,
CMNHFManager& mnhfManager);
~CEHFSignalsHandler();

Expand Down
4 changes: 3 additions & 1 deletion src/spork.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum SporkId : int32_t {
SPORK_19_CHAINLOCKS_ENABLED = 10018,
SPORK_21_QUORUM_ALL_CONNECTED = 10020,
SPORK_23_QUORUM_POSE = 10022,
SPORK_24_MN_RR_READY = 10023,

SPORK_INVALID = -1,
};
Expand All @@ -66,14 +67,15 @@ struct CSporkDef
};

#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef{name, defaultValue, #name}
[[maybe_unused]] static constexpr std::array<CSporkDef, 7> sporkDefs = {
[[maybe_unused]] static constexpr std::array<CSporkDef, 8> 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_MN_RR_READY, 4070908800ULL), // OFF
};
#undef MAKE_SPORK_DEF
extern std::unique_ptr<CSporkManager> sporkManager;
Expand Down
3 changes: 3 additions & 0 deletions src/test/block_reward_reallocation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
}
BOOST_CHECK(!llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip()));

// Active EHF "MN_RR"
Params().UpdateMNActivationParam(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit, ::ChainActive().Height(), ::ChainActive().Tip()->GetMedianTimePast(), /*fJustCheck=*/ false);

// Reward split should stay ~60/40 after reallocation is done,
// check 10 next superblocks
for ([[maybe_unused]] auto i : irange::range(10)) {
Expand Down
20 changes: 6 additions & 14 deletions test/functional/feature_asset_locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,6 @@ def run_test(self):

self.log.info("Mine a quorum...")
self.mine_quorum()
self.log.info("Quorum is mined, need to wait until EHF MN RR will be mined to avoid influence to mempool")
mn_rr_status = 0
while mn_rr_status == 0:
time.sleep(1)
mn_rr_status = get_bip9_details(node, 'mn_rr')['EHF']
self.log.info(f"BIP9 MN_RR status: {mn_rr_status}")
node.generate(1)
self.sync_all()

self.validate_credit_pool_balance(locked_1)

Expand Down Expand Up @@ -437,8 +429,8 @@ def run_test(self):
self.log.info(f"Collecting coins in pool... Collected {total}/{10_900 * COIN}")
coin = coins.pop()
to_lock = int(coin['amount'] * COIN) - tiny_amount
if to_lock > 50 * COIN:
to_lock = 50 * COIN
if to_lock > 99 * COIN:
to_lock = 99 * COIN
total += to_lock
tx = self.create_assetlock(coin, to_lock, pubkey)
self.send_tx_simple(tx)
Expand Down Expand Up @@ -509,24 +501,24 @@ def run_test(self):
node.generate(1)
self.sync_all()

self.log.info("generate many blocks to be sure that mempool is empty afterwards...")
self.log.info("generate many blocks to be sure that mempool is empty after expiring txes...")
self.slowly_generate_batch(60)
self.log.info("Checking that credit pool is not changed...")
assert_equal(new_total, self.get_credit_pool_balance())
self.check_mempool_size()

self.activate_mn_rr(expected_activation_height=3090)
# activate MN_RR reallocation
self.activate_mn_rr()
self.log.info(f'height: {node.getblockcount()} credit: {self.get_credit_pool_balance()}')
bt = node.getblocktemplate()
platform_reward = bt['masternode'][0]['amount']
assert_equal(bt['masternode'][0]['script'], '6a') # empty OP_RETURN
owner_reward = bt['masternode'][1]['amount']
operator_reward = bt['masternode'][2]['amount'] if len(bt['masternode']) == 3 else 0
all_mn_rewards = platform_reward + owner_reward + operator_reward
all_mn_rewards += 1 * 0.75
assert_equal(all_mn_rewards, bt['coinbasevalue'] * 0.75) # 75/25 mn/miner reward split
assert_equal(platform_reward, int(all_mn_rewards * 0.375)) # 0.375 platform share
assert_equal(platform_reward, 2555399792)
assert_equal(platform_reward, 2963658930)
assert_equal(new_total, self.get_credit_pool_balance())
node.generate(1)
self.sync_all()
Expand Down
1 change: 1 addition & 0 deletions test/functional/feature_llmq_evo.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def run_test(self):
self.log.info("Test that EvoNodes are paid 4x blocks in a row")
self.test_evo_payments(window_analysis=256)

# TODO send an EHF signal!
self.activate_mn_rr()
self.log.info("Activated MN RewardReallocation at height:" + str(self.nodes[0].getblockcount()))

Expand Down
11 changes: 9 additions & 2 deletions test/functional/feature_mnehf.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def run_test(self):
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
self.activate_v20()
assert_equal(get_bip9_details(node, 'testdummy')['status'], 'defined')
assert_equal(get_bip9_details(node, 'mn_rr')['status'], 'defined')

ehf_tx_sent = self.send_tx(ehf_tx)
self.log.info(f"ehf tx: {ehf_tx_sent}")
Expand Down Expand Up @@ -202,8 +203,6 @@ def run_test(self):
self.restart_all_nodes()

self.check_fork('active')
assert_equal('active', get_bip9_details(node, 'mn_rr')['status'])

fork_active_blockhash = node.getbestblockhash()
self.log.info(f"Invalidate block: {ehf_blockhash} with tip {fork_active_blockhash}")
for inode in self.nodes:
Expand Down Expand Up @@ -256,6 +255,12 @@ def run_test(self):
self.mine_quorum()

ehf_tx_new_start = self.create_mnehf(28, pubkey)

self.log.info("activate MN_RR also by enabling spork 24")
assert_equal(get_bip9_details(node, 'mn_rr')['status'], 'defined')
self.nodes[0].sporkupdate("SPORK_24_MN_RR_READY", 0)
self.wait_for_sporks_same()

self.check_fork('defined')

self.log.info("Mine one block and ensure EHF tx for the new deployment is mined")
Expand All @@ -268,6 +273,8 @@ def run_test(self):
self.check_fork('defined')
self.slowly_generate_batch(12 * 4)
self.check_fork('active')
self.log.info(f"bip9: {get_bip9_details(node, 'mn_rr')}")
assert_equal(get_bip9_details(node, 'mn_rr')['status'], 'active')


if __name__ == '__main__':
Expand Down
18 changes: 16 additions & 2 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
check_json_precision,
copy_datadir,
force_finish_mnsync,
get_bip9_details,
get_datadir_path,
hex_str_to_bytes,
initialize_datadir,
Expand Down Expand Up @@ -1121,8 +1122,21 @@ 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 activate_mn_rr(self):
self.nodes[0].sporkupdate("SPORK_24_MN_RR_READY", 0)
self.wait_for_sporks_same()

mn_rr_status = 0
while mn_rr_status == 0:
time.sleep(1)
mn_rr_status = get_bip9_details(self.nodes[0], 'mn_rr')['EHF']
self.log.info(f"BIP9 MN_RR status: {mn_rr_status}")
self.nodes[0].generate(1)
self.sync_all()
# only couple extra blocks are needed, so, helper `activate_by_name` is not needed
while get_bip9_details(self.nodes[0], 'mn_rr')['status'] != 'active':
self.nodes[0].generate(1)
self.sync_all()

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

0 comments on commit 0237234

Please sign in to comment.