From 19f200a210ced3ea4fa3eb0f7b34adcbda2deac9 Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Fri, 30 Jan 2026 22:54:03 +0100 Subject: [PATCH] allow resetting block_h in CCC menu --- releases/Next-ChangeLog.md | 1 + shared/ccc.py | 24 ++++++++++++++++++------ testing/test_ccc.py | 26 ++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/releases/Next-ChangeLog.md b/releases/Next-ChangeLog.md index ad26563d..9367453a 100644 --- a/releases/Next-ChangeLog.md +++ b/releases/Next-ChangeLog.md @@ -8,6 +8,7 @@ This lists the new changes that have not yet been published in a normal release. Navigate to `Advanced/Tools -> Export Wallet -> Key Expression` - New Feature: Support for v3 transactions - New Feature: Send keystrokes with all derived BIP-85 secrets +- Enhancement: CCC allow to reset block height # Mk4 Specific Changes diff --git a/shared/ccc.py b/shared/ccc.py index 644edaff..ab635180 100644 --- a/shared/ccc.py +++ b/shared/ccc.py @@ -285,7 +285,7 @@ class CCCFeature: # a very basic and permissive policy, but non-zero too. # - 1BTC per day chain = chains.current_chain() - return SpendingPolicy('ccc', dict(mag=1, vel=144, + return SpendingPolicy('ccc', dict(mag=1, vel=144, block_h=chain.ccc_min_block, web2fa='', addrs=[])) @classmethod @@ -402,20 +402,32 @@ class CCCConfigMenu(MenuSystem): async def debug_last_fail(self, *a): # debug for customers: why did we reject that last txn? + c = chains.current_chain() + def_bh = c.ccc_min_block pol = CCCFeature.get_policy() bh = pol.get('block_h', None) + bh_clear = '' msg = '' - if bh: - msg += "CCC height:\n\n%s\n\n" % bh + escape = "4" + if bh is not None: + msg += 'CCC height:\n\n%s\n\n' % bh + if bh != def_bh: + bh_clear = 'Press (1) to clear block height. ' + escape += "1" lfr = LastFailReason.get() - msg += 'The most recent policy check failed because of:\n\n%s\n\nPress (4) to clear.' \ - % lfr - ch = await ux_show_story(msg, escape='4') + msg += ('The most recent policy check failed because of:\n\n%s\n\n' + '%sPress (4) to clear last fail reason.' % (lfr, bh_clear)) + ch = await ux_show_story(msg, escape=escape) if ch == '4': LastFailReason.clear() self.update_contents() + elif ch == '1': + if await ux_confirm("Reset block height to default value %d for %s?" % (def_bh, c.name)): + pol.update_policy_key(_quiet=True, _master_only=False, block_h=def_bh) + + async def remove_ccc(self, *a): # disable and remove feature diff --git a/testing/test_ccc.py b/testing/test_ccc.py index d882a245..7eadacc6 100644 --- a/testing/test_ccc.py +++ b/testing/test_ccc.py @@ -705,7 +705,9 @@ def test_ccc_whitelist(whitelist_ok, setup_ccc, ccc_ms_setup, @pytest.mark.bitcoind @pytest.mark.parametrize("velocity_mi", ['6 blocks (hour)', '48 blocks (8h)']) def test_ccc_velocity(velocity_mi, setup_ccc, ccc_ms_setup, bitcoind, settings_set, - policy_sign, settings_get, bitcoind_create_watch_only_wallet): + policy_sign, settings_get, bitcoind_create_watch_only_wallet, + enter_enabled_ccc, pick_menu_item, cap_story, need_keypress, + press_select, press_cancel): settings_set("ccc", None) settings_set("chain", "XRT") @@ -713,7 +715,7 @@ def test_ccc_velocity(velocity_mi, setup_ccc, ccc_ms_setup, bitcoind, settings_s blocks = int(velocity_mi.split()[0]) - setup_ccc(vel=velocity_mi) + c_words = setup_ccc(vel=velocity_mi) _, target_mi = ccc_ms_setup() assert settings_get("ccc")["pol"]["block_h"] == 0 @@ -786,6 +788,26 @@ def test_ccc_velocity(velocity_mi, setup_ccc, ccc_ms_setup, bitcoind, settings_s violation="nLockTime not height" ) + enter_enabled_ccc(c_words) + pick_menu_item("Last Violation") + time.sleep(.1) + title, story = cap_story() + assert 'Press (1) to clear block height' in story + assert int(story.split("\n\n")[1]) == block_height + need_keypress("1") + time.sleep(.1) + title, story = cap_story() + assert "Reset block height to default value 0 for Bitcoin Regtest?" in story + press_select() + time.sleep(.1) + pick_menu_item("Last Violation") + time.sleep(.1) + title, story = cap_story() + assert 'Press (1) to clear block height' not in story # not in story when default + assert int(story.split("\n\n")[1]) == 0 + press_cancel() # go back to CCC menu + press_cancel() # got home + @pytest.mark.bitcoind def test_ccc_warnings(setup_ccc, ccc_ms_setup, bitcoind, settings_set, policy_sign,