feat: ability to disable clsig creation while retaining clsig enforcement (#5398)

## Issue being fixed or feature implemented
Currently, Chainlocks are either enabled or disabled. This PR adds a
third state: enabled but we will not sign new ones.

Should probably backport this to v19.x

## What was done?
Spork state != 0 but active will now result in chain locks being
enforced but not created.

## How Has This Been Tested?

## Breaking Changes
None

## Checklist:
_Go over all the following points, and put an `x` in all the boxes that
apply._
- [ ] 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)_

---------

Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
PastaPastaPasta 2023-05-31 15:34:14 -05:00 committed by GitHub
parent 2c0cb13f09
commit 3bf7d2a38c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 2 deletions

View File

@ -249,6 +249,10 @@ void CChainLocksHandler::TrySignChainTip()
return;
}
if (!ChainLocksSigningEnabled(spork_manager)) {
return;
}
const CBlockIndex* pindex = WITH_LOCK(cs_main, return ::ChainActive().Tip());
if (pindex->pprev == nullptr) {
@ -687,4 +691,9 @@ bool AreChainLocksEnabled(const CSporkManager& sporkManager)
return sporkManager.IsSporkActive(SPORK_19_CHAINLOCKS_ENABLED);
}
bool ChainLocksSigningEnabled(const CSporkManager& sporkManager)
{
return sporkManager.GetSporkValue(SPORK_19_CHAINLOCKS_ENABLED) == 0;
}
} // namespace llmq

View File

@ -128,6 +128,7 @@ private:
extern std::unique_ptr<CChainLocksHandler> chainLocksHandler;
bool AreChainLocksEnabled(const CSporkManager& sporkManager);
bool ChainLocksSigningEnabled(const CSporkManager& sporkManager);
} // namespace llmq

View File

@ -66,6 +66,20 @@ class LLMQChainLocksTest(DashTestFramework):
block = self.nodes[0].getblock(self.nodes[0].getblockhash(h))
assert block['chainlock']
# Update spork to SPORK_19_CHAINLOCKS_ENABLED and test its behaviour
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 1)
self.wait_for_sporks_same()
# Generate new blocks and verify that they are not chainlocked
previous_block_hash = self.nodes[0].getbestblockhash()
for _ in range(2):
block_hash = self.nodes[0].generate(1)[0]
self.wait_for_chainlocked_block_all_nodes(block_hash, expected=False)
assert self.nodes[0].getblock(previous_block_hash)["chainlock"]
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 0)
self.wait_for_sporks_same()
self.log.info("Isolate node, mine on another, and reconnect")
self.isolate_node(0)
node0_mining_addr = self.nodes[0].getnewaddress()

View File

@ -1513,9 +1513,9 @@ class DashTestFramework(BitcoinTestFramework):
if wait_until(check_chainlocked_block, timeout=timeout, sleep=0.1, do_assert=expected) and not expected:
raise AssertionError("waiting unexpectedly succeeded")
def wait_for_chainlocked_block_all_nodes(self, block_hash, timeout=15):
def wait_for_chainlocked_block_all_nodes(self, block_hash, timeout=15, expected=True):
for node in self.nodes:
self.wait_for_chainlocked_block(node, block_hash, timeout=timeout)
self.wait_for_chainlocked_block(node, block_hash, expected=expected, timeout=timeout)
def wait_for_best_chainlock(self, node, block_hash, timeout=15):
wait_until(lambda: node.getbestchainlock()["blockhash"] == block_hash, timeout=timeout, sleep=0.1)