Skip to content

Commit bb53f4f

Browse files
jgriffithsJamie C. Driver
authored andcommitted
map: add a non-allocating keypath search which also returns the index of the match
1 parent 6afa250 commit bb53f4f

File tree

9 files changed

+72
-11
lines changed

9 files changed

+72
-11
lines changed

include/wally.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,12 @@ inline int map_keypath_bip32_init_alloc(size_t allocation_len, struct wally_map*
10441044
return detail::check_ret(__FUNCTION__, ret);
10451045
}
10461046

1047+
template <class MAP_IN, class HDKEY, class OUTPUT>
1048+
inline int map_keypath_get_bip32_key_from(const MAP_IN& map_in, size_t index, const HDKEY& hdkey, const OUTPUT& output, size_t* written) {
1049+
int ret = ::wally_map_keypath_get_bip32_key_from(detail::get_p(map_in), index, detail::get_p(hdkey), detail::get_p(output), written);
1050+
return detail::check_ret(__FUNCTION__, ret);
1051+
}
1052+
10471053
template <class MAP_IN, class HDKEY>
10481054
inline int map_keypath_get_bip32_key_from_alloc(const MAP_IN& map_in, size_t index, const HDKEY& hdkey, struct ext_key** output) {
10491055
int ret = ::wally_map_keypath_get_bip32_key_from_alloc(detail::get_p(map_in), index, detail::get_p(hdkey), output);

include/wally_map.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,33 @@ WALLY_CORE_API int wally_map_find_bip32_public_key_from(
361361
const struct ext_key *hdkey,
362362
size_t *written);
363363

364+
#ifndef SWIG
365+
/**
366+
* Return a BIP32 derived key matching the keypath of a parent in a map.
367+
*
368+
* :param map_in: The map to search for derived keys of ``hdkey`` in.
369+
* :param index: The zero-based index of the item to start searching from.
370+
* :param hdkey: The BIP32 parent key to derive matches from.
371+
* :param output: Destination for the resulting derived key. If a matching
372+
*| key is not found, ``output`` is zeroed.
373+
* :param written: On success, set to zero if a matching derived key is
374+
*| not found, otherwise the index of the matching key plus one.
375+
*
376+
* .. note:: This function searches for keys in the map that are children
377+
*| of ``hdkey``. If one is found, the corresponding private extended key
378+
*| is derived from ``hdey`` into ``output`` and ``written`` is set
379+
*| to the index of the matching key plus one.
380+
*| If no key is found, ``*output`` is set to ``NULL`` and
381+
*| `WALLY_OK` is returned.
382+
*/
383+
WALLY_CORE_API int wally_map_keypath_get_bip32_key_from(
384+
const struct wally_map *map_in,
385+
size_t index,
386+
const struct ext_key *hdkey,
387+
struct ext_key *output,
388+
size_t *written);
389+
#endif /* SWIG */
390+
364391
/**
365392
* Return a BIP32 derived key matching the keypath of a parent in a map.
366393
*
@@ -370,7 +397,7 @@ WALLY_CORE_API int wally_map_find_bip32_public_key_from(
370397
* :param output: Destination for the resulting derived key, if any.
371398
*
372399
* .. note:: This function searches for keys in the map that are children
373-
*| of ``hdkey``. If one is found, the resulting privately derived key
400+
*| of ``hdkey``. If one is found, the corresponding privately derived key
374401
*| is returned. If no key is found, ``*output`` is set to ``NULL`` and
375402
*| `WALLY_OK` is returned.
376403
*/

src/map.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -463,17 +463,20 @@ int wally_map_find_bip32_public_key_from(const struct wally_map *map_in, size_t
463463
return ret;
464464
}
465465

466-
int wally_map_keypath_get_bip32_key_from_alloc(const struct wally_map *map_in,
467-
size_t index, const struct ext_key *hdkey,
468-
struct ext_key **output)
466+
int wally_map_keypath_get_bip32_key_from(const struct wally_map *map_in,
467+
size_t index, const struct ext_key *hdkey,
468+
struct ext_key *output, size_t *written)
469469
{
470470
uint32_t path[BIP32_PATH_MAX_LEN];
471471
struct ext_key derived;
472472
size_t i, path_len, idx = 0;
473473
int ret = WALLY_OK;
474474

475-
OUTPUT_CHECK;
476-
if (!map_in || !hdkey)
475+
if (written)
476+
*written = 0;
477+
if (output)
478+
memset(output, 0, sizeof(*output));
479+
if (!map_in || !hdkey || !written || !output)
477480
return WALLY_EINVAL;
478481

479482
if (mem_is_zero(hdkey->chain_code, sizeof(hdkey->chain_code))) {
@@ -516,14 +519,33 @@ int wally_map_keypath_get_bip32_key_from_alloc(const struct wally_map *map_in,
516519
}
517520
}
518521
if (ret == WALLY_OK && idx) {
519-
/* Found, return the matching key */
520-
*output = wally_calloc(sizeof(struct ext_key));
521-
if (!*output)
522+
/* Found, return the matching key and its 1-based index */
523+
*written = idx;
524+
memcpy(output, hdkey, sizeof(*hdkey));
525+
}
526+
wally_clear(&derived, sizeof(derived));
527+
return ret;
528+
}
529+
530+
531+
int wally_map_keypath_get_bip32_key_from_alloc(const struct wally_map *map_in,
532+
size_t index, const struct ext_key *hdkey,
533+
struct ext_key **output)
534+
{
535+
struct ext_key found;
536+
size_t found_index;
537+
int ret;
538+
539+
OUTPUT_CHECK;
540+
ret = wally_map_keypath_get_bip32_key_from(map_in, index, hdkey,
541+
&found, &found_index);
542+
if (ret == WALLY_OK && found_index) {
543+
if (!(*output = wally_calloc(sizeof(struct ext_key))))
522544
ret = WALLY_ENOMEM;
523545
else
524-
memcpy(*output, hdkey, sizeof(*hdkey));
546+
memcpy(*output, &found, sizeof(found));
525547
}
526-
wally_clear(&derived, sizeof(derived));
548+
wally_clear(&found, sizeof(found));
527549
return ret;
528550
}
529551

src/swig_java/swig.i

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
340340
%ignore bip32_key_unserialize;
341341
%ignore bip32_key_with_tweak_from_parent_path;
342342
%ignore wally_map_init;
343+
%ignore wally_map_keypath_get_bip32_key_from;
343344
%ignore wally_psbt_blind;
344345
%ignore wally_tx_elements_output_init;
345346
%ignore wally_tx_input_clone;

src/swig_python/swig.i

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ static void destroy_words(PyObject *obj) { (void)obj; }
413413
%ignore bip32_key_unserialize;
414414
%ignore bip32_key_with_tweak_from_parent_path;
415415
%ignore wally_map_init;
416+
%ignore wally_map_keypath_get_bip32_key_from;
416417
%ignore wally_psbt_blind;
417418
%ignore wally_psbt_get_input_best_utxo;
418419
%ignore wally_tx_elements_output_init;

src/test/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ class wally_psbt(Structure):
415415
('wally_map_init_alloc', c_int, [c_size_t, c_void_p, POINTER(POINTER(wally_map))]),
416416
('wally_map_keypath_add', c_int, [POINTER(wally_map), c_void_p, c_size_t, c_void_p, c_size_t, POINTER(c_uint32), c_size_t]),
417417
('wally_map_keypath_bip32_init_alloc', c_int, [c_size_t, POINTER(POINTER(wally_map))]),
418+
('wally_map_keypath_get_bip32_key_from', c_int, [POINTER(wally_map), c_size_t, POINTER(ext_key), POINTER(ext_key), c_size_t_p]),
418419
('wally_map_keypath_get_bip32_key_from_alloc', c_int, [POINTER(wally_map), c_size_t, POINTER(ext_key), POINTER(POINTER(ext_key))]),
419420
('wally_map_keypath_get_item_fingerprint', c_int, [POINTER(wally_map), c_size_t, c_void_p, c_size_t]),
420421
('wally_map_keypath_get_item_path', c_int, [POINTER(wally_map), c_size_t, POINTER(c_uint32), c_size_t, c_size_t_p]),

src/wasm_package/src/functions.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/wasm_package/src/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export function map_init_noalloc(allocation_len: number, verify_fn: Ref, output:
208208
export function map_keypath_add(map_in: Ref_wally_map, pub_key: Buffer|Uint8Array, fingerprint: Buffer|Uint8Array, child_path: Uint32Array|number[]): void;
209209
export function map_keypath_bip32_init(allocation_len: number): Ref_wally_map;
210210
export function map_keypath_get_bip32_key_from(map_in: Ref_wally_map, index: number, hdkey: Ref_ext_key): Ref_ext_key;
211+
export function map_keypath_get_bip32_key_from_noalloc(map_in: Ref_wally_map, index: number, hdkey: Ref_ext_key, output: Ref_ext_key): number;
211212
export function map_keypath_get_item_fingerprint(map_in: Ref_wally_map, index: number): Buffer;
212213
export function map_keypath_get_item_path_len(map_in: Ref_wally_map, index: number): number;
213214
export function map_keypath_public_key_init(allocation_len: number): Ref_wally_map;

tools/wasm_exports.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ EXPORTED_FUNCTIONS="['_malloc','_free','_bip32_key_free' \
171171
,'_wally_map_init_alloc' \
172172
,'_wally_map_keypath_add' \
173173
,'_wally_map_keypath_bip32_init_alloc' \
174+
,'_wally_map_keypath_get_bip32_key_from' \
174175
,'_wally_map_keypath_get_bip32_key_from_alloc' \
175176
,'_wally_map_keypath_get_item_fingerprint' \
176177
,'_wally_map_keypath_get_item_path' \

0 commit comments

Comments
 (0)