Add test to make sure that extreme valid values of n are accepted in older(n)
What changed, and why it matters
This commit only adds a new automated test and slightly modifies existing test helper functions. It does not change the actual Ledger Bitcoin app code that users run. The new test checks that the app accepts certain extreme but valid relative timelock values when registering a wallet policy. There is no fix or behavior change to the secure firmware itself.
No security action required. Treat as routine test coverage improvement. If reviewing a broader patch series, verify whether a preceding commit changed the actual parsing/validation logic that this test exercises.
Security signals we found
No changes to firmware or application source code
Only test code and test helpers modified
New test exercises relative timelock boundary values in Miniscript policy registration
Evidence from the diff
The diff adds test_register_wallet_minmax_relative_timelocks in tests/test_register_wallet.py, which registers a taproot wallet policy containing older(1), older(65535), older(4194305), and older(4259839) to verify boundary values are accepted. It also parameterizes save_screenshot in register_wallet_instruction_approve and register_wallet_instruction_approve_long in tests/instructions.py so the new test can suppress screenshots. No C or app logic is modified.
Changed components
tests/test_register_wallet.pytests/instructions.pyInspect captured patch +28 / −11
diff --git a/tests/instructions.py b/tests/instructions.py
index 3d425a8..6ddfc8c 100644
--- a/tests/instructions.py
+++ b/tests/instructions.py
@@ -109,15 +109,15 @@ def wallet_instruction_approve(model: Firmware) -> Instructions:
return instructions
-def register_wallet_instruction_approve(model: Firmware) -> Instructions:
+def register_wallet_instruction_approve(model: Firmware, save_screenshot=True) -> Instructions:
instructions = Instructions(model)
if model.name.startswith("nano"):
- instructions.new_request("Register account")
+ instructions.new_request("Register account", save_screenshot=save_screenshot)
else:
- instructions.choice_confirm()
- instructions.choice_confirm()
- instructions.choice_confirm()
+ instructions.choice_confirm(save_screenshot=save_screenshot)
+ instructions.choice_confirm(save_screenshot=save_screenshot)
+ instructions.choice_confirm(save_screenshot=save_screenshot)
return instructions
@@ -133,16 +133,16 @@ def register_wallet_instruction_approve_no_save(model: Firmware) -> Instructions
return instructions
-def register_wallet_instruction_approve_long(model: Firmware) -> Instructions:
+def register_wallet_instruction_approve_long(model: Firmware, save_screenshot=True) -> Instructions:
instructions = Instructions(model)
if model.name.startswith("nano"):
- instructions.new_request("Register account")
+ instructions.new_request("Register account", save_screenshot=save_screenshot)
else:
- instructions.choice_confirm()
- instructions.choice_confirm()
- instructions.choice_confirm()
- instructions.choice_confirm()
+ instructions.choice_confirm(save_screenshot=save_screenshot)
+ instructions.choice_confirm(save_screenshot=save_screenshot)
+ instructions.choice_confirm(save_screenshot=save_screenshot)
+ instructions.choice_confirm(save_screenshot=save_screenshot)
return instructions
diff --git a/tests/test_register_wallet.py b/tests/test_register_wallet.py
index 3880b87..aa02527 100644
--- a/tests/test_register_wallet.py
+++ b/tests/test_register_wallet.py
@@ -235,6 +235,23 @@ def test_register_miniscript_long_policy(navigator: Navigator, firmware: Firmwar
wallet_hmac,
)
+def test_register_wallet_minmax_relative_timelocks(navigator: Navigator, firmware: Firmware, client:
+ RaggerClient, test_name: str):
+ # This test makes sure that the minimum and maximum values in the sane range for relative timelocks are accepted.
+ # Since mixing height-based and time-based is not allowed, we separate them in different leaves of a taptree.
+ wallet = WalletPolicy(
+ name="Relative timelocks",
+ descriptor_template="tr(@0/<0;1>/*,{thresh(3,pk(@0/<2;3>/*),s:pk(@1/<2;3>/*),s:pk(@2/<2;3>/*),sln:older(1),sln:older(65535)),thresh(3,pk(@0/<4;5>/*),s:pk(@1/<4;5>/*),s:pk(@2/<4;5>/*),sln:older(4194305),sln:older(4259839))})",
+ keys_info=[
+ "[f5acc2fd/48'/1'/0'/2']tpubDFAqEGNyad35aBCKUAXbQGDjdVhNueno5ZZVEn3sQbW5ci457gLR7HyTmHBg93oourBssgUxuWz1jX5uhc1qaqFo9VsybY1J5FuedLfm4dK",
+ "tpubDE7NQymr4AFtewpAsWtnreyq9ghkzQBXpCZjWLFVRAvnbf7vya2eMTvT2fPapNqL8SuVvLQdbUbMfWLVDCZKnsEBqp6UK93QEzL8Ck23AwF",
+ "tpubDDV6FDLcCieWUeN7R3vZK2Qs3KuQed3ScTY9EiwMXvyCkLjDbCb8RXaAgWDbkG4tW1BMKVF1zERHnyt78QKd4ZaAYGMJMpvHPwgSSU1AxZ3",
+ ])
+ wallet_id, _ = client.register_wallet(wallet, navigator,
+ instructions=register_wallet_instruction_approve_long(
+ firmware, save_screenshot=False),
+ testname=test_name)
+ assert wallet_id == wallet.id
def test_register_wallet_not_sane_policy(navigator: Navigator, firmware: Firmware, client:
RaggerClient, test_name: str):
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.