Skip to content

Commit 107ffae

Browse files
committed
pset: add support for elip-101 global genesis blockhash
1 parent 7d2b2cd commit 107ffae

File tree

10 files changed

+130
-2
lines changed

10 files changed

+130
-2
lines changed

include/wally.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,18 @@ inline int psbt_find_global_scalar(const PSBT& psbt, const SCALAR& scalar, size_
24392439
return detail::check_ret(__FUNCTION__, ret);
24402440
}
24412441

2442+
template <class PSBT, class BYTES_OUT>
2443+
inline int psbt_get_global_genesis_blockhash(const PSBT& psbt, BYTES_OUT& bytes_out, size_t* written) {
2444+
int ret = ::wally_psbt_get_global_genesis_blockhash(detail::get_p(psbt), bytes_out.data(), bytes_out.size(), written);
2445+
return detail::check_ret(__FUNCTION__, ret);
2446+
}
2447+
2448+
template <class PSBT>
2449+
inline int psbt_has_global_genesis_blockhash(const PSBT& psbt, size_t* written) {
2450+
int ret = ::wally_psbt_has_global_genesis_blockhash(detail::get_p(psbt), written);
2451+
return detail::check_ret(__FUNCTION__, ret);
2452+
}
2453+
24422454
inline int psbt_input_clear_amount_rangeproof(struct wally_psbt_input* input) {
24432455
int ret = ::wally_psbt_input_clear_amount_rangeproof(input);
24442456
return detail::check_ret(__FUNCTION__, ret);
@@ -3050,6 +3062,12 @@ inline int psbt_output_set_value_rangeproof(const OUTPUT& output, const RANGEPRO
30503062
return detail::check_ret(__FUNCTION__, ret);
30513063
}
30523064

3065+
template <class PSBT, class GENESIS_BLOCKHASH>
3066+
inline int psbt_set_global_genesis_blockhash(const PSBT& psbt, const GENESIS_BLOCKHASH& genesis_blockhash) {
3067+
int ret = ::wally_psbt_set_global_genesis_blockhash(detail::get_p(psbt), genesis_blockhash.data(), genesis_blockhash.size());
3068+
return detail::check_ret(__FUNCTION__, ret);
3069+
}
3070+
30533071
template <class PSBT>
30543072
inline int psbt_set_global_scalars(const PSBT& psbt, const struct wally_map* map_in) {
30553073
int ret = ::wally_psbt_set_global_scalars(detail::get_p(psbt), map_in);

include/wally_psbt.h

+40
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct wally_psbt {
139139
#ifndef WALLY_ABI_NO_ELEMENTS
140140
struct wally_map global_scalars;
141141
uint32_t pset_modifiable_flags;
142+
unsigned char genesis_blockhash[SHA256_LEN]; /* All zeros if not present */
142143
#endif /* WALLY_ABI_NO_ELEMENTS */
143144
};
144145
#endif /* SWIG */
@@ -2114,6 +2115,45 @@ WALLY_CORE_API int wally_psbt_find_global_scalar(
21142115
WALLY_CORE_API int wally_psbt_set_pset_modifiable_flags(
21152116
struct wally_psbt *psbt,
21162117
uint32_t flags);
2118+
2119+
/**
2120+
* Set the global genesis blockhash in a PSBT.
2121+
*
2122+
* :param psbt: The psbt to update. Must be a PSET.
2123+
* :param genesis_blockhash: The genesis blockhash.
2124+
* :param genesis_blockhash_len: Size of ``genesis_blockhash`` in bytes. Must be `SHA256_LEN`.
2125+
*/
2126+
WALLY_CORE_API int wally_psbt_set_global_genesis_blockhash(
2127+
struct wally_psbt *psbt,
2128+
const unsigned char *genesis_blockhash,
2129+
size_t genesis_blockhash_len);
2130+
2131+
/**
2132+
* Determine if a PSBT contains a global genesis blockhash.
2133+
*
2134+
* :param psbt: The psbt to check. Must be a PSET.
2135+
* :param written: On success, set to zero if no genesis blockhash is present,
2136+
*| otherwise set to one.
2137+
*/
2138+
WALLY_CORE_API int wally_psbt_has_global_genesis_blockhash(
2139+
struct wally_psbt *psbt,
2140+
size_t *written);
2141+
2142+
/**
2143+
* Get the global genesis blockhash from a PSBT.
2144+
*
2145+
* :param psbt: The psbt to get the genesis blockhash from.
2146+
* :param bytes_out: Destination for the genesis blockhash.
2147+
* MAX_SIZED_OUTPUT(len, bytes_out, SHA256_LEN)
2148+
* :param written: Destination for the number of bytes written to ``bytes_out``.
2149+
*| Will be zero if the value is not present.
2150+
*/
2151+
WALLY_CORE_API int wally_psbt_get_global_genesis_blockhash(
2152+
struct wally_psbt *psbt,
2153+
unsigned char *bytes_out,
2154+
size_t len,
2155+
size_t *written);
2156+
21172157
#endif /* WALLY_ABI_NO_ELEMENTS */
21182158

21192159
/**

src/psbt.c

+52
Original file line numberDiff line numberDiff line change
@@ -1348,6 +1348,47 @@ PSBT_GET(num_outputs, PSBT_0)
13481348
PSBT_GET(fallback_locktime, PSBT_2)
13491349
PSBT_GET(tx_version, PSBT_2)
13501350
PSBT_GET(tx_modifiable_flags, PSBT_2)
1351+
#ifndef WALLY_ABI_NO_ELEMENTS
1352+
int wally_psbt_set_global_genesis_blockhash(
1353+
struct wally_psbt *psbt,
1354+
const unsigned char* genesis_blockhash, size_t genesis_blockhash_len)
1355+
{
1356+
size_t is_pset;
1357+
if ((wally_psbt_is_elements(psbt, &is_pset)) != WALLY_OK || !is_pset ||
1358+
!genesis_blockhash || genesis_blockhash_len != SHA256_LEN)
1359+
return WALLY_EINVAL;
1360+
memcpy(psbt->genesis_blockhash, genesis_blockhash, genesis_blockhash_len);
1361+
return WALLY_OK;
1362+
}
1363+
1364+
int wally_psbt_has_global_genesis_blockhash(struct wally_psbt *psbt, size_t *written)
1365+
{
1366+
size_t is_pset;
1367+
if (written)
1368+
*written = 0;
1369+
if ((wally_psbt_is_elements(psbt, &is_pset)) != WALLY_OK || !is_pset || !written)
1370+
return WALLY_EINVAL;
1371+
*written = !mem_is_zero(psbt->genesis_blockhash, sizeof(psbt->genesis_blockhash));
1372+
return WALLY_OK;
1373+
}
1374+
1375+
int wally_psbt_get_global_genesis_blockhash(struct wally_psbt *psbt,
1376+
unsigned char* bytes_out, size_t len,
1377+
size_t *written)
1378+
{
1379+
size_t has_blockhash;
1380+
if (written)
1381+
*written = 0;
1382+
if ((wally_psbt_has_global_genesis_blockhash(psbt, &has_blockhash)) != WALLY_OK ||
1383+
!bytes_out || len < SHA256_LEN || !written)
1384+
return WALLY_EINVAL;
1385+
if (has_blockhash) {
1386+
memcpy(bytes_out, psbt->genesis_blockhash, sizeof(psbt->genesis_blockhash));
1387+
*written = sizeof(psbt->genesis_blockhash);
1388+
}
1389+
return WALLY_OK;
1390+
}
1391+
#endif /* WALLY_ABI_NO_ELEMENTS */
13511392

13521393
int wally_psbt_has_fallback_locktime(const struct wally_psbt *psbt, size_t *written)
13531394
{
@@ -2717,6 +2758,13 @@ int wally_psbt_from_bytes(const unsigned char *bytes, size_t len,
27172758
if ((*output)->pset_modifiable_flags & ~PSET_TXMOD_ALL_FLAGS)
27182759
ret = WALLY_EINVAL; /* Invalid flags */
27192760
break;
2761+
case PSET_FT(PSET_GLOBAL_GENESIS_HASH): {
2762+
size_t val_len;
2763+
const unsigned char *val_p;
2764+
pull_varlength_buff(cursor, max, &val_p, &val_len);
2765+
ret = wally_psbt_set_global_genesis_blockhash(*output, val_p, val_len);
2766+
break;
2767+
}
27202768
#endif /* BUILD_ELEMENTS */
27212769
default:
27222770
goto unknown;
@@ -3357,6 +3405,10 @@ int wally_psbt_to_bytes(const struct wally_psbt *psbt, uint32_t flags,
33573405
push_varint(&cursor, &max, sizeof(uint8_t));
33583406
push_u8(&cursor, &max, psbt->pset_modifiable_flags);
33593407
}
3408+
if (!mem_is_zero(psbt->genesis_blockhash, sizeof(psbt->genesis_blockhash))) {
3409+
push_key(&cursor, &max, PSET_GLOBAL_GENESIS_HASH, true, NULL, 0);
3410+
push_varbuff(&cursor, &max, psbt->genesis_blockhash, sizeof(psbt->genesis_blockhash));
3411+
}
33603412
#endif /* BUILD_ELEMENTS */
33613413
}
33623414

src/psbt_io.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@
5151
/* Globals: PSET */
5252
#define PSET_GLOBAL_SCALAR 0x00
5353
#define PSET_GLOBAL_TX_MODIFIABLE 0x01
54-
#define PSET_GLOBAL_MAX PSET_GLOBAL_TX_MODIFIABLE
54+
#define PSET_GLOBAL_GENESIS_HASH 0x02
55+
#define PSET_GLOBAL_MAX PSET_GLOBAL_GENESIS_HASH
5556

5657
/* Global PSBT/PSET fields that can be repeated */
5758
#define PSBT_GLOBAL_REPEATABLE (PSBT_FT(PSBT_GLOBAL_XPUB) | \
@@ -76,7 +77,8 @@
7677
PSBT_FT(PSBT_GLOBAL_OUTPUT_COUNT) | \
7778
PSBT_FT(PSBT_GLOBAL_TX_MODIFIABLE) | \
7879
PSET_FT(PSET_GLOBAL_SCALAR) | \
79-
PSET_FT(PSET_GLOBAL_TX_MODIFIABLE))
80+
PSET_FT(PSET_GLOBAL_TX_MODIFIABLE) | \
81+
PSET_FT(PSET_GLOBAL_GENESIS_HASH))
8082

8183
/* Global PSBT/PSET fields that must *not* be present in v2 */
8284
#define PSBT_GLOBAL_DISALLOWED_V2 PSBT_FT(PSBT_GLOBAL_UNSIGNED_TX)

src/swig_java/swig.i

+3
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
740740
%returns_struct(wally_psbt_from_tx, wally_psbt);
741741
%returns_void__(wally_psbt_generate_input_explicit_proofs);
742742
%returns_size_t(wally_psbt_get_pset_modifiable_flags);
743+
%returns_size_t(wally_psbt_get_global_genesis_blockhash);
743744
%returns_struct(wally_psbt_get_global_tx_alloc, wally_tx);
744745
%rename("psbt_get_global_tx") wally_psbt_get_global_tx_alloc;
745746
%returns_array_(wally_psbt_get_global_scalar, 3, 4, WALLY_SCALAR_OFFSET_LEN);
@@ -866,6 +867,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
866867
%returns_size_t(wally_psbt_get_tx_version);
867868
%returns_size_t(wally_psbt_get_version);
868869
%returns_size_t(wally_psbt_has_fallback_locktime);
870+
%returns_size_t(wally_psbt_has_global_genesis_blockhash);
869871
%returns_size_t(wally_psbt_has_input_required_lockheight);
870872
%returns_size_t(wally_psbt_has_input_required_locktime);
871873
%returns_size_t(wally_psbt_has_input_value);
@@ -889,6 +891,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
889891
%returns_void__(wally_psbt_remove_output);
890892
%returns_void__(wally_psbt_set_pset_modifiable_flags);
891893
%returns_void__(wally_psbt_set_fallback_locktime);
894+
%returns_void__(wally_psbt_set_global_genesis_blockhash);
892895
%returns_void__(wally_psbt_set_global_tx);
893896
%returns_void__(wally_psbt_set_global_scalars);
894897
%returns_void__(wally_psbt_set_input_amount);

src/swig_python/python_extra.py_in

+1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ if is_elements_build():
285285
explicit_rangeproof = _wrap_bin(explicit_rangeproof, ASSET_EXPLICIT_RANGEPROOF_MAX_LEN, resize=True)
286286
explicit_surjectionproof = _wrap_bin(explicit_surjectionproof, ASSET_EXPLICIT_SURJECTIONPROOF_LEN)
287287
psbt_blind = psbt_blind_alloc
288+
psbt_get_global_genesis_blockhash = _wrap_bin(psbt_get_global_genesis_blockhash, SHA256_LEN, resize=True)
288289
psbt_get_global_scalar = _wrap_bin(psbt_get_global_scalar, WALLY_SCALAR_OFFSET_LEN)
289290
psbt_get_input_amount_rangeproof = _wrap_bin(psbt_get_input_amount_rangeproof, psbt_get_input_amount_rangeproof_len)
290291
psbt_get_input_asset = _wrap_bin(psbt_get_input_asset, psbt_get_input_asset_len)

src/test/util.py

+3
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ class wally_psbt(Structure):
454454
('wally_psbt_from_base64_n', c_int, [c_char_p, c_size_t, c_uint32, POINTER(POINTER(wally_psbt))]),
455455
('wally_psbt_from_bytes', c_int, [c_void_p, c_size_t, c_uint32, POINTER(POINTER(wally_psbt))]),
456456
('wally_psbt_from_tx', c_int, [POINTER(wally_tx), c_uint32, c_uint32, POINTER(POINTER(wally_psbt))]),
457+
('wally_psbt_get_global_genesis_blockhash', c_int, [POINTER(wally_psbt), c_void_p, c_size_t, c_size_t_p]),
457458
('wally_psbt_get_id', c_int, [POINTER(wally_psbt), c_uint32, c_void_p, c_size_t]),
458459
('wally_psbt_get_input_bip32_key_from_alloc', c_int, [POINTER(wally_psbt), c_size_t, c_size_t, c_uint32, POINTER(ext_key), POINTER(POINTER(ext_key))]),
459460
('wally_psbt_get_input_scriptcode', c_int, [POINTER(wally_psbt), c_size_t, c_void_p, c_size_t, c_void_p, c_size_t, c_size_t_p]),
@@ -464,6 +465,7 @@ class wally_psbt(Structure):
464465
('wally_psbt_get_length', c_int, [POINTER(wally_psbt), c_uint32, c_size_t_p]),
465466
('wally_psbt_get_locktime', c_int, [POINTER(wally_psbt), c_size_t_p]),
466467
('wally_psbt_get_tx_version', c_int, [POINTER(wally_psbt), c_size_t_p]),
468+
('wally_psbt_has_global_genesis_blockhash', c_int, [POINTER(wally_psbt), c_size_t_p]),
467469
('wally_psbt_init_alloc', c_int, [c_uint32, c_size_t, c_size_t, c_size_t, c_uint32, POINTER(POINTER(wally_psbt))]),
468470
('wally_psbt_input_add_signature', c_int, [POINTER(wally_psbt_input), c_void_p, c_size_t, c_void_p, c_size_t]),
469471
('wally_psbt_input_clear_amount_rangeproof', c_int, [POINTER(wally_psbt_input)]),
@@ -617,6 +619,7 @@ class wally_psbt(Structure):
617619
('wally_psbt_remove_input', c_int, [POINTER(wally_psbt), c_uint32]),
618620
('wally_psbt_remove_output', c_int, [POINTER(wally_psbt), c_uint32]),
619621
('wally_psbt_set_fallback_locktime', c_int, [POINTER(wally_psbt), c_uint32]),
622+
('wally_psbt_set_global_genesis_blockhash', c_int, [POINTER(wally_psbt), c_void_p, c_size_t]),
620623
('wally_psbt_set_global_scalars', c_int, [POINTER(wally_psbt), POINTER(wally_map)]),
621624
('wally_psbt_set_global_tx', c_int, [POINTER(wally_psbt), POINTER(wally_tx)]),
622625
('wally_psbt_set_pset_modifiable_flags', c_int, [POINTER(wally_psbt), c_uint32]),

src/wasm_package/src/functions.js

+3
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

+3
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ export function psbt_from_bytes(bytes: Buffer|Uint8Array, flags: number): Ref_wa
285285
export function psbt_from_tx(tx: Ref_wally_tx, version: number, flags: number): Ref_wally_psbt;
286286
export function psbt_generate_input_explicit_proofs(psbt: Ref_wally_psbt, index: number, satoshi: bigint, asset: Buffer|Uint8Array, abf: Buffer|Uint8Array, vbf: Buffer|Uint8Array, entropy: Buffer|Uint8Array): void;
287287
export function psbt_get_fallback_locktime(psbt: Ref_wally_psbt): number;
288+
export function psbt_get_global_genesis_blockhash(psbt: Ref_wally_psbt): Buffer;
288289
export function psbt_get_global_scalar(psbt: Ref_wally_psbt, index: number): Buffer;
289290
export function psbt_get_global_scalars_size(psbt: Ref_wally_psbt): number;
290291
export function psbt_get_global_tx(psbt: Ref_wally_psbt): Ref_wally_tx;
@@ -363,6 +364,7 @@ export function psbt_get_tx_modifiable_flags(psbt: Ref_wally_psbt): number;
363364
export function psbt_get_tx_version(psbt: Ref_wally_psbt): number;
364365
export function psbt_get_version(psbt: Ref_wally_psbt): number;
365366
export function psbt_has_fallback_locktime(psbt: Ref_wally_psbt): number;
367+
export function psbt_has_global_genesis_blockhash(psbt: Ref_wally_psbt): number;
366368
export function psbt_has_input_required_lockheight(psbt: Ref_wally_psbt, index: number): number;
367369
export function psbt_has_input_required_locktime(psbt: Ref_wally_psbt, index: number): number;
368370
export function psbt_has_output_amount(psbt: Ref_wally_psbt, index: number): number;
@@ -496,6 +498,7 @@ export function psbt_output_taproot_keypath_add(output: Ref_wally_psbt_output, p
496498
export function psbt_remove_input(psbt: Ref_wally_psbt, index: number): void;
497499
export function psbt_remove_output(psbt: Ref_wally_psbt, index: number): void;
498500
export function psbt_set_fallback_locktime(psbt: Ref_wally_psbt, locktime: number): void;
501+
export function psbt_set_global_genesis_blockhash(psbt: Ref_wally_psbt, genesis_blockhash: Buffer|Uint8Array): void;
499502
export function psbt_set_global_scalars(psbt: Ref_wally_psbt, map_in: Ref_wally_map): void;
500503
export function psbt_set_global_tx(psbt: Ref_wally_psbt, tx: Ref_wally_tx): void;
501504
export function psbt_set_input_amount(psbt: Ref_wally_psbt, index: number, amount: bigint): void;

tools/wasm_exports.sh

+3
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ if [ -z "$DISABLE_ELEMENTS" ]; then
565565
,'_wally_psbt_clear_output_value_rangeproof' \
566566
,'_wally_psbt_find_global_scalar' \
567567
,'_wally_psbt_generate_input_explicit_proofs' \
568+
,'_wally_psbt_get_global_genesis_blockhash' \
568569
,'_wally_psbt_get_global_scalar' \
569570
,'_wally_psbt_get_global_scalars_size' \
570571
,'_wally_psbt_get_input_amount' \
@@ -622,6 +623,7 @@ if [ -z "$DISABLE_ELEMENTS" ]; then
622623
,'_wally_psbt_get_output_value_rangeproof' \
623624
,'_wally_psbt_get_output_value_rangeproof_len' \
624625
,'_wally_psbt_get_pset_modifiable_flags' \
626+
,'_wally_psbt_has_global_genesis_blockhash' \
625627
,'_wally_psbt_has_output_blinder_index' \
626628
,'_wally_psbt_input_clear_amount_rangeproof' \
627629
,'_wally_psbt_input_clear_asset' \
@@ -729,6 +731,7 @@ if [ -z "$DISABLE_ELEMENTS" ]; then
729731
,'_wally_psbt_output_set_value_blinding_rangeproof' \
730732
,'_wally_psbt_output_set_value_commitment' \
731733
,'_wally_psbt_output_set_value_rangeproof' \
734+
,'_wally_psbt_set_global_genesis_blockhash' \
732735
,'_wally_psbt_set_global_scalars' \
733736
,'_wally_psbt_set_input_amount' \
734737
,'_wally_psbt_set_input_amount_rangeproof' \

0 commit comments

Comments
 (0)