Compare commits

..

5 Commits

Author SHA1 Message Date
Konstantin Akimov
c09090bf9a
nit - removed unused vars from feature_llmq_singlenode.py 2024-12-19 20:55:32 +07:00
Konstantin Akimov
fbd453b473
better fix for dkgsessionhandler - missing WAIT() 2024-12-19 20:55:00 +07:00
Konstantin Akimov
24e7f5645a
improve logs for feature_llmq_singlenode - TODO drop connections() logs 2024-12-19 20:33:21 +07:00
Konstantin Akimov
9ad216a1fc
fix - slow-down infinity loop for single-node-quorum generation 2024-12-19 20:33:21 +07:00
Konstantin Akimov
50eaba5eb2
fix - wait any CL not the best 2024-12-19 20:33:21 +07:00
2 changed files with 39 additions and 14 deletions

View File

@ -558,12 +558,14 @@ void CDKGSessionHandler::HandleDKGRound(CConnman& connman, PeerManager& peerman)
auto finalCommitment = curSession->FinalizeSingleCommitment();
if (finalCommitment.IsNull()) {
LogPrintf("final commitment is null here -- is-member=%d\n", curSession->AreWeMember());
WaitForNextPhase(QuorumPhase::Initialized, QuorumPhase::Contribute, curQuorumHash);
return;
}
if (auto inv_opt = quorumBlockProcessor.AddMineableCommitment(finalCommitment); inv_opt.has_value()) {
peerman.RelayInv(inv_opt.value());
}
WaitForNextPhase(QuorumPhase::Initialized, QuorumPhase::Contribute, curQuorumHash);
return;
}

View File

@ -11,8 +11,14 @@ This functional test is similar to feature_llmq_signing.py but difference are bi
'''
import time
from test_framework.test_framework import DashTestFramework
from test_framework.util import assert_raises_rpc_error, wait_until_helper
from test_framework.util import (
assert_raises_rpc_error,
assert_greater_than,
wait_until_helper,
)
id = "0000000000000000000000000000000000000000000000000000000000000001"
@ -59,6 +65,12 @@ class LLMQSigningTest(DashTestFramework):
assert not wait_until_helper(lambda: not self.check_sigs(hasrecsigs, isconflicting1, isconflicting2), timeout = timeout, do_assert = False)
def log_connections(self):
connections = []
for idx in range(len(self.nodes)):
connections.append(self.nodes[idx].getconnectioncount())
self.log.info(f"nodes connection count: {connections}")
def run_test(self):
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()
@ -72,11 +84,14 @@ class LLMQSigningTest(DashTestFramework):
skip_count = 24 - (self.nodes[0].getblockcount() % 24)
if skip_count != 0:
self.bump_mocktime(1)
time.sleep(1)
self.generate(self.nodes[0], skip_count)
self.generate(self.nodes[0], 30)
self.log_connections()
assert_greater_than(len(self.nodes[0].quorum('list')['llmq_1_100']), 0)
self.log.info("We have quorum waiting for ChainLock")
self.wait_for_best_chainlock(self.nodes[0], self.nodes[0].getbestblockhash())
self.wait_for_chainlocked_block(self.nodes[0], self.nodes[0].getbestblockhash())
self.log.info("Send funds and wait InstantSend lock")
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
@ -98,8 +113,8 @@ class LLMQSigningTest(DashTestFramework):
quorumHash = self.mninfo[1].node.quorum("selectquorum", 111, id)["quorumHash"]
self.mninfo[0].node.quorum("sign", 111, id, msgHash, quorumHash, False)
sign1 = self.mninfo[0].node.quorum("sign", 111, id, msgHash)
sign2 = self.mninfo[1].node.quorum("sign", 111, id, msgHash)
self.mninfo[0].node.quorum("sign", 111, id, msgHash)
self.mninfo[1].node.quorum("sign", 111, id, msgHash)
self.wait_for_sigs(True, False, True, 15)
has0 = self.nodes[0].quorum("hasrecsig", 111, id, msgHash)
@ -107,10 +122,11 @@ class LLMQSigningTest(DashTestFramework):
has2 = self.nodes[2].quorum("hasrecsig", 111, id, msgHash)
assert (has0 or has1 or has2)
# Test `quorum verify` rpc
self.log.info("Test `quorum verify` rpc")
self.log_connections()
node = self.mninfo[0].node
recsig = node.quorum("getrecsig", 111, id, msgHash)
# Find quorum automatically
self.log.info("Find quorum automatically")
height = node.getblockcount()
height_bad = node.getblockheader(recsig["quorumHash"])["height"]
hash_bad = node.getblockhash(0)
@ -118,32 +134,39 @@ class LLMQSigningTest(DashTestFramework):
assert node.quorum("verify", 111, id, msgHash, recsig["sig"], "", height)
assert not node.quorum("verify", 111, id, msgHashConflict, recsig["sig"])
assert not node.quorum("verify", 111, id, msgHash, recsig["sig"], "", height_bad)
# Use specific quorum
self.log.info("Use specific quorum")
assert node.quorum("verify", 111, id, msgHash, recsig["sig"], recsig["quorumHash"])
assert not node.quorum("verify", 111, id, msgHashConflict, recsig["sig"], recsig["quorumHash"])
assert_raises_rpc_error(-8, "quorum not found", node.quorum, "verify", 111, id, msgHash, recsig["sig"], hash_bad)
# Mine one more quorum, so that we have 2 active ones, nothing should change
self.log.info("Mine one more quorum, so that we have 2 active ones, nothing should change")
self.mine_single_node_quorum()
self.assert_sigs_nochange(True, False, True, 3)
# Mine 2 more quorums, so that the one used for the the recovered sig should become inactive, nothing should change
self.log_connections()
self.log.info("Mine 2 more quorums, so that the one used for the the recovered sig should become inactive, nothing should change")
self.mine_single_node_quorum()
self.mine_single_node_quorum()
self.assert_sigs_nochange(True, False, True, 3)
# fast forward until 0.5 days before cleanup is expected, recovered sig should still be valid
self.log.info("Fast forward until 0.5 days before cleanup is expected, recovered sig should still be valid")
self.bump_mocktime(recsig_time + int(60 * 60 * 24 * 6.5) - self.mocktime, update_schedulers=False)
# Cleanup starts every 5 seconds
self.log.info("Cleanup starts every 5 seconds")
self.wait_for_sigs(True, False, True, 15)
# fast forward 1 day, recovered sig should not be valid anymore
self.log.info("Fast forward 1 day, recovered sig should not be valid anymore")
self.bump_mocktime(int(60 * 60 * 24 * 1), update_schedulers=False)
# Cleanup starts every 5 seconds
self.log.info("Cleanup starts every 5 seconds")
self.wait_for_sigs(False, False, False, 15)
self.log_connections()
self.log.info("Test chainlocks and InstantSend with new quorums and 2 nodes")
self.wait_for_best_chainlock(self.nodes[0], self.nodes[0].getbestblockhash())
block_hash = self.nodes[0].getbestblockhash()
self.log.info(f"Chainlock on block: {block_hash} is expected")
self.wait_for_best_chainlock(self.nodes[0], block_hash)
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
self.log.info(f"InstantSend lock on tx: {txid} is expected")
self.wait_for_instantlock(txid, self.nodes[0])
if __name__ == '__main__':