Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 8 additions & 30 deletions test/functional/llmq-chainlocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ def run_test(self):

# mine single block, wait for chainlock
self.nodes[0].generate(1)
self.wait_for_chainlock_tip_all_nodes()
self.wait_for_chainlocked_tip_all_nodes()

# mine many blocks, wait for chainlock
self.nodes[0].generate(20)
self.wait_for_chainlock_tip_all_nodes()
self.wait_for_chainlocked_tip_all_nodes()

# assert that all blocks up until the tip are chainlocked
for h in range(1, self.nodes[0].getblockcount()):
Expand All @@ -51,22 +51,22 @@ def run_test(self):
node0_mining_addr = self.nodes[0].getnewaddress()
node0_tip = self.nodes[0].getbestblockhash()
self.nodes[1].generatetoaddress(5, node0_mining_addr)
self.wait_for_chainlock_tip(self.nodes[1])
self.wait_for_chainlocked_tip(self.nodes[1])
assert(self.nodes[0].getbestblockhash() == node0_tip)
reconnect_isolated_node(self.nodes[0], 1)
self.nodes[1].generatetoaddress(1, node0_mining_addr)
self.wait_for_chainlock(self.nodes[0], self.nodes[1].getbestblockhash())
self.wait_for_chainlocked_block(self.nodes[0], self.nodes[1].getbestblockhash())

# Isolate node, mine on both parts of the network, and reconnect
isolate_node(self.nodes[0])
self.nodes[0].generate(5)
self.nodes[1].generatetoaddress(1, node0_mining_addr)
good_tip = self.nodes[1].getbestblockhash()
self.wait_for_chainlock_tip(self.nodes[1])
self.wait_for_chainlocked_tip(self.nodes[1])
assert(not self.nodes[0].getblock(self.nodes[0].getbestblockhash())["chainlock"])
reconnect_isolated_node(self.nodes[0], 1)
self.nodes[1].generatetoaddress(1, node0_mining_addr)
self.wait_for_chainlock(self.nodes[0], self.nodes[1].getbestblockhash())
self.wait_for_chainlocked_block(self.nodes[0], self.nodes[1].getbestblockhash())
assert(self.nodes[0].getblock(self.nodes[0].getbestblockhash())["previousblockhash"] == good_tip)
assert(self.nodes[1].getblock(self.nodes[1].getbestblockhash())["previousblockhash"] == good_tip)

Expand All @@ -89,7 +89,7 @@ def run_test(self):
self.nodes[0].reconsiderblock(good_tip)
assert(self.nodes[0].getbestblockhash() != good_tip)
self.nodes[1].generatetoaddress(1, node0_mining_addr)
self.wait_for_chainlock(self.nodes[0], self.nodes[1].getbestblockhash())
self.wait_for_chainlocked_block(self.nodes[0], self.nodes[1].getbestblockhash())
assert(self.nodes[0].getbestblockhash() == self.nodes[1].getbestblockhash())

# Enable LLMQ bases InstantSend, which also enables checks for "safe" transactions
Expand Down Expand Up @@ -122,29 +122,7 @@ def run_test(self):
# Enable network on first node again, which will cause the blocks to propagate and IS locks to happen retroactively
# for the mined TXs, which will then allow the network to create a CLSIG
reconnect_isolated_node(self.nodes[0], 1)
self.wait_for_chainlock(self.nodes[0], self.nodes[0].getbestblockhash(), 30)

def wait_for_chainlock_tip_all_nodes(self):
for node in self.nodes:
tip = node.getbestblockhash()
self.wait_for_chainlock(node, tip)

def wait_for_chainlock_tip(self, node):
tip = node.getbestblockhash()
self.wait_for_chainlock(node, tip)

def wait_for_chainlock(self, node, block_hash, timeout=15):
t = time.time()
while time.time() - t < timeout:
try:
block = node.getblock(block_hash)
if block["confirmations"] > 0 and block["chainlock"]:
return
except:
# block might not be on the node yet
pass
time.sleep(0.1)
raise AssertionError("wait_for_chainlock timed out")
self.wait_for_chainlocked_block(self.nodes[0], self.nodes[0].getbestblockhash(), 30)

def create_chained_txs(self, node, amount):
txid = node.sendtoaddress(node.getnewaddress(), amount)
Expand Down
37 changes: 2 additions & 35 deletions test/functional/llmq-is-cl-conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def run_test(self):

# mine single block, wait for chainlock
self.nodes[0].generate(1)
self.wait_for_chainlock_tip_all_nodes()
self.wait_for_chainlocked_tip_all_nodes()

self.test_chainlock_overrides_islock(False)
self.test_chainlock_overrides_islock(True)
Expand Down Expand Up @@ -133,7 +133,7 @@ def test_chainlock_overrides_islock(self, test_block_conflict):
assert(submit_result is None)

for node in self.nodes:
self.wait_for_chainlock(node, "%064x" % block.sha256)
self.wait_for_chainlocked_block(node, "%064x" % block.sha256)

# Create a chained TX on top of tx2
inputs = []
Expand Down Expand Up @@ -212,39 +212,6 @@ def test_islock_overrides_nonchainlock(self):
assert(self.nodes[0].getbestblockhash() != good_tip)
assert(self.nodes[1].getbestblockhash() != good_tip)

def wait_for_chainlock_tip_all_nodes(self):
for node in self.nodes:
tip = node.getbestblockhash()
self.wait_for_chainlock(node, tip)

def wait_for_chainlock_tip(self, node):
tip = node.getbestblockhash()
self.wait_for_chainlock(node, tip)

def wait_for_chainlock(self, node, block_hash):
t = time.time()
while time.time() - t < 15:
try:
block = node.getblockheader(block_hash)
if block["confirmations"] > 0 and block["chainlock"]:
return
except:
# block might not be on the node yet
pass
time.sleep(0.1)
raise AssertionError("wait_for_chainlock timed out")

def wait_for_best_chainlock(self, node, block_hash):
t = time.time()
while time.time() - t < 15:
try:
if node.getbestchainlock()["blockhash"] == block_hash:
return
except:
pass
time.sleep(0.1)
raise AssertionError("wait_for_best_chainlock timed out")

def create_block(self, node, vtx=[]):
bt = node.getblocktemplate()
height = bt['height']
Expand Down
56 changes: 30 additions & 26 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,25 +696,34 @@ def check_instantlock():
return False
wait_until(check_instantlock, timeout=10, sleep=0.5)

def wait_for_sporks_same(self, timeout=30):
st = time.time()
while time.time() < st + timeout:
if self.check_sporks_same():
return
time.sleep(0.5)
raise AssertionError("wait_for_sporks_same timed out")

def check_sporks_same(self):
sporks = self.nodes[0].spork('show')
for node in self.nodes[1:]:
sporks2 = node.spork('show')
if sporks != sporks2:
def wait_for_chainlocked_block(self, node, block_hash, timeout=15):
def check_chainlocked_block():
try:
block = node.getblock(block_hash)
return block["confirmations"] > 0 and block["chainlock"]
except:
return False
return True
wait_until(check_chainlocked_block, timeout=timeout, sleep=0.1)

def wait_for_chainlocked_tip(self, node):
tip = node.getbestblockhash()
self.wait_for_chainlocked_block(node, tip)

def wait_for_chainlocked_tip_all_nodes(self):
for node in self.nodes:
self.wait_for_chainlocked_tip(node)
Comment thread
UdjinM6 marked this conversation as resolved.
Outdated

def wait_for_best_chainlock(self, node, block_hash):
wait_until(lambda: node.getbestchainlock()["blockhash"] == block_hash, timeout=15, sleep=0.1)

def wait_for_sporks_same(self, timeout=30):
def check_sporks_same():
sporks = self.nodes[0].spork('show')
return all(node.spork('show') == sporks for node in self.nodes[1:])
wait_until(check_sporks_same, timeout=timeout, sleep=0.5)

def wait_for_quorum_phase(self, phase, check_received_messages, check_received_messages_count, timeout=30):
t = time.time()
while time.time() - t < timeout:
def check_dkg_session():
all_ok = True
for mn in self.mninfo:
s = mn.node.quorum("dkgstatus")["session"]
Expand All @@ -732,14 +741,11 @@ def wait_for_quorum_phase(self, phase, check_received_messages, check_received_m
if s[check_received_messages] < check_received_messages_count:
all_ok = False
break
if all_ok:
return
time.sleep(0.1)
raise AssertionError("wait_for_quorum_phase timed out")
return all_ok
wait_until(check_dkg_session, timeout=timeout, sleep=0.1)

def wait_for_quorum_commitment(self, timeout = 15):
t = time.time()
while time.time() - t < timeout:
def check_dkg_comitments():
all_ok = True
for node in self.nodes:
s = node.quorum("dkgstatus")
Expand All @@ -750,10 +756,8 @@ def wait_for_quorum_commitment(self, timeout = 15):
if "llmq_5_60" not in s:
all_ok = False
break
if all_ok:
return
time.sleep(0.1)
raise AssertionError("wait_for_quorum_commitment timed out")
return all_ok
wait_until(check_dkg_comitments, timeout=timeout, sleep=0.1)

def mine_quorum(self, expected_contributions=5, expected_complaints=0, expected_justifications=0, expected_commitments=5):
quorums = self.nodes[0].quorum("list")
Expand Down