Skip to content

Commit 55008b0

Browse files
authored
fix: do not check chainlock state in IsTxSafeForMining (#5444)
## Issue being fixed or feature implemented Disabled or non-enforced Chainlocks does not mean you can safely mine non-locked txes, you could end up mining a block that is going to be rejected by everyone else if a conflicting tx (missing on your node) would be IS-locked. I can't find any reason why we have this besides "if Chainlocks are disabled then smth is wrong so let them all be mined" but we have spork_2 and spork_3 to control IS behaviour and we check them in `IsTxSafeForMining` already, that would be a much more straightforward way to deal with a potential issue. Noticed this while reviewing #5150 and also while testing v19.2 during recent testnet v19 re-fork. ## What was done? Drop this check, adjust tests ## How Has This Been Tested? Run tests locally ## Breaking Changes Not quote breaking changes but a change in behaviour: with CLs disabled it will now take 10 minutes for non-locked txes to be mined, same as when CLs are enabled. ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_
1 parent 33d5161 commit 55008b0

File tree

3 files changed

+21
-24
lines changed

3 files changed

+21
-24
lines changed

src/llmq/chainlocks.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -449,17 +449,7 @@ CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const
449449

450450
bool CChainLocksHandler::IsTxSafeForMining(const CInstantSendManager& isman, const uint256& txid) const
451451
{
452-
if (!isman.RejectConflictingBlocks()) {
453-
return true;
454-
}
455-
if (!isEnabled || !isEnforced) {
456-
return true;
457-
}
458-
459-
if (!isman.IsInstantSendEnabled()) {
460-
return true;
461-
}
462-
if (isman.IsLocked(txid)) {
452+
if (!isman.RejectConflictingBlocks() || !isman.IsInstantSendEnabled() || isman.IsLocked(txid)) {
463453
return true;
464454
}
465455

test/functional/feature_dip4_coinbasemerkleroots.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ def set_test_params(self):
4444
self.set_dash_test_params(4, 3, fast_dip3_enforcement=True)
4545

4646
def run_test(self):
47+
# No IS or Chainlocks in this test
48+
self.bump_mocktime(1)
49+
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 4070908800)
50+
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 4070908800)
51+
self.wait_for_sporks_same()
52+
4753
self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn())
4854

4955
self.confirm_mns()
@@ -85,21 +91,14 @@ def run_test(self):
8591

8692
self.nodes[0].generate(1)
8793
oldhash = self.nodes[0].getbestblockhash()
88-
# Have to disable ChainLocks here because they won't let you to invalidate already locked blocks
89-
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 4070908800)
90-
self.wait_for_sporks_same()
94+
9195
# Test DIP8 activation once with a pre-existing quorum and once without (we don't know in which order it will activate on mainnet)
9296
self.test_dip8_quorum_merkle_root_activation(True)
9397
for n in self.nodes:
9498
n.invalidateblock(oldhash)
9599
self.sync_all()
96100
first_quorum = self.test_dip8_quorum_merkle_root_activation(False, True)
97101

98-
# Re-enable ChainLocks again
99-
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 0)
100-
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
101-
self.wait_for_sporks_same()
102-
103102
# Verify that the first quorum appears in MNLISTDIFF
104103
expectedDeleted = []
105104
expectedNew = [QuorumId(100, int(first_quorum, 16)), QuorumId(104, int(first_quorum, 16)), QuorumId(106, int(first_quorum, 16))]

test/functional/p2p_instantsend.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ def test_block_doublespend(self):
3535

3636
# feed the sender with some balance
3737
sender_addr = sender.getnewaddress()
38-
self.nodes[0].sendtoaddress(sender_addr, 1)
38+
is_id = self.nodes[0].sendtoaddress(sender_addr, 1)
39+
for node in self.nodes:
40+
self.wait_for_instantlock(is_id, node)
3941
self.bump_mocktime(1)
4042
self.nodes[0].generate(2)
4143
self.sync_all()
@@ -54,11 +56,15 @@ def test_block_doublespend(self):
5456
for node in connected_nodes:
5557
self.wait_for_instantlock(is_id, node)
5658
# send doublespend transaction to isolated node
57-
isolated.sendrawtransaction(dblspnd_tx['hex'])
59+
dblspnd_txid = isolated.sendrawtransaction(dblspnd_tx['hex'])
5860
# generate block on isolated node with doublespend transaction
61+
self.bump_mocktime(599)
62+
wrong_early_block = isolated.generate(1)[0]
63+
assert not "confirmation" in isolated.getrawtransaction(dblspnd_txid, 1)
64+
isolated.invalidateblock(wrong_early_block)
5965
self.bump_mocktime(1)
60-
isolated.generate(1)
61-
wrong_block = isolated.getbestblockhash()
66+
wrong_block = isolated.generate(1)[0]
67+
assert_equal(isolated.getrawtransaction(dblspnd_txid, 1)["confirmations"], 1)
6268
# connect isolated block to network
6369
self.reconnect_isolated_node(self.isolated_idx, 0)
6470
# check doublespend block is rejected by other nodes
@@ -90,7 +96,9 @@ def test_mempool_doublespend(self):
9096

9197
# feed the sender with some balance
9298
sender_addr = sender.getnewaddress()
93-
self.nodes[0].sendtoaddress(sender_addr, 1)
99+
is_id = self.nodes[0].sendtoaddress(sender_addr, 1)
100+
for node in self.nodes:
101+
self.wait_for_instantlock(is_id, node)
94102
self.bump_mocktime(1)
95103
self.nodes[0].generate(2)
96104
self.sync_all()

0 commit comments

Comments
 (0)