Skip to content

Commit

Permalink
Increase maximum depth of the supported taptrees on non-NanoS devices…
Browse files Browse the repository at this point in the history
…; generalize corresponding test so that it adapts to the different limits
  • Loading branch information
bigspider committed Nov 2, 2023
1 parent edcd935 commit 84bd8da
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/common/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@
MAX(MAX_WALLET_POLICY_SERIALIZED_LENGTH_V1, MAX_WALLET_POLICY_SERIALIZED_LENGTH_V2)

// maximum depth of a taproot tree that we support
#define MAX_TAPTREE_POLICY_DEPTH 4
// (here depth 1 means only the root of the taptree)
#ifdef TARGET_NANOS
#define MAX_TAPTREE_POLICY_DEPTH 5
#else
#define MAX_TAPTREE_POLICY_DEPTH 9
#endif

typedef struct {
uint32_t master_key_derivation[MAX_BIP32_PATH_STEPS];
Expand Down
5 changes: 3 additions & 2 deletions src/handler/lib/check_merkle_tree_sorted.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

#include "../../boilerplate/dispatcher.h"
#include "../../common/merkle.h"
#include "../../common/wallet.h"

// this flow aborts if any element is larger than this size
// This is enough for a PSBT with the control block of a taptree of depth 5 tapbranches
// TODO: we might remove this limitation altogether with a more careful implementation.
#define MAX_CHECK_MERKLE_TREE_SORTED_PREIMAGE_SIZE 162
// Here we make sure that we have enough space for control block of a taptree of the maximum supported depth
#define MAX_CHECK_MERKLE_TREE_SORTED_PREIMAGE_SIZE (34 + 32*(MAX_TAPTREE_POLICY_DEPTH - 1))

typedef void (*merkle_tree_elements_callback_t)(struct dispatcher_context_s *,
void *,
Expand Down
13 changes: 10 additions & 3 deletions tests/test_e2e_tapscripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,21 +236,28 @@ def test_e2e_tapscript_multi_a_2of2(rpc, rpc_test_wallet, client: Client, specul
rpc, rpc_test_wallet, client, speculos_globals, comm)


def test_e2e_tapscript_depth4(rpc, rpc_test_wallet, client: Client, speculos_globals: SpeculosGlobals, comm: Union[TransportClient, SpeculosClient]):
def test_e2e_tapscript_maxdepth(rpc, rpc_test_wallet, client: Client, speculos_globals: SpeculosGlobals, comm: Union[TransportClient, SpeculosClient], model: str):
# A taproot tree with maximum supported depth, where the internal key is in the deepest script

MAX_TAPTREE_POLICY_DEPTH = 4 if model == "nanos" else 9

# Make the most unbalanced tree where each script is a simple pk()
parts = [f"pk(@{i}/**)" for i in range(1, MAX_TAPTREE_POLICY_DEPTH)]
descriptor_template = "tr(@0/**,{" + ',{'.join(parts) + f",pk(@{MAX_TAPTREE_POLICY_DEPTH}/**)" + "}" * (MAX_TAPTREE_POLICY_DEPTH - 1) + ")"

keys_info = []
for _ in range(4):
for _ in range(MAX_TAPTREE_POLICY_DEPTH):
_, core_xpub_orig = create_new_wallet()
keys_info.append(core_xpub_orig)

# the last (deepest) script is the only one we sign with the ledger key
path = "499'/1'/0'"
internal_xpub = get_internal_xpub(speculos_globals.seed, path)
keys_info.append(f"[{speculos_globals.master_key_fingerprint.hex()}/{path}]{internal_xpub}")

wallet_policy = WalletPolicy(
name="Tapscriptception",
descriptor_template="tr(@0/**,{pk(@1/**),{pk(@2/**),{pk(@3/**),pk(@4/**)}}})",
descriptor_template=descriptor_template,
keys_info=keys_info)

run_test_e2e(wallet_policy, [], rpc, rpc_test_wallet, client, speculos_globals, comm)
Expand Down

0 comments on commit 84bd8da

Please sign in to comment.