Skip to content

Commit

Permalink
transaction: expose wally_tx_input_clone
Browse files Browse the repository at this point in the history
Note output cloning is already exposed.
  • Loading branch information
jgriffiths committed Feb 5, 2024
1 parent b772203 commit f48dc58
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 15 deletions.
12 changes: 12 additions & 0 deletions include/wally.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1872,6 +1872,18 @@ inline int tx_init_alloc(uint32_t version, uint32_t locktime, size_t inputs_allo
return detail::check_ret(__FUNCTION__, ret);
}

template <class TX_INPUT_IN>
inline int tx_input_clone(const TX_INPUT_IN& tx_input_in, struct wally_tx_input* input) {
int ret = ::wally_tx_input_clone(detail::get_p(tx_input_in), input);
return detail::check_ret(__FUNCTION__, ret);
}

template <class TX_INPUT_IN>
inline int tx_input_clone_alloc(const TX_INPUT_IN& tx_input_in, struct wally_tx_input** input) {
int ret = ::wally_tx_input_clone_alloc(detail::get_p(tx_input_in), input);
return detail::check_ret(__FUNCTION__, ret);
}

inline int tx_input_free(struct wally_tx_input* input) {
int ret = ::wally_tx_input_free(input);
return detail::check_ret(__FUNCTION__, ret);
Expand Down
22 changes: 22 additions & 0 deletions include/wally_transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,28 @@ WALLY_CORE_API int wally_tx_input_init_alloc(
const struct wally_tx_witness_stack *witness,
struct wally_tx_input **output);

/**
* Create a new copy of a transaction input.
*
* :param tx_input_in: The transaction input to clone.
* :param input: Destination for the resulting transaction input copy.
*/
WALLY_CORE_API int wally_tx_input_clone_alloc(
const struct wally_tx_input *tx_input_in,
struct wally_tx_input **input);

/**
* Create a new copy of a transaction input in place.
*
* :param tx_input_in: The transaction input to clone.
* :param input: Destination for the resulting transaction input copy.
*
* .. note:: ``input`` is overwritten in place, and not cleared first.
*/
WALLY_CORE_API int wally_tx_input_clone(
const struct wally_tx_input *tx_input_in,
struct wally_tx_input *input);

/**
* Free a transaction input allocated by `wally_tx_input_init_alloc`.
*
Expand Down
3 changes: 3 additions & 0 deletions src/swig_java/swig.i
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
%ignore wally_map_init;
%ignore wally_psbt_blind;
%ignore wally_tx_elements_output_init;
%ignore wally_tx_input_clone;
%ignore wally_tx_output_clone;
%ignore wally_tx_output_init;
/* END AUTOGENERATED */
Expand Down Expand Up @@ -1051,6 +1052,8 @@ static jobjectArray create_jstringArray(JNIEnv *jenv, char **p, size_t len) {
%rename("tx_init") wally_tx_init_alloc;
%returns_struct(wally_tx_clone_alloc, wally_tx);
%rename("tx_clone") wally_tx_clone_alloc;
%returns_struct(wally_tx_input_clone_alloc, wally_tx_input_clone);
%rename("tx_input_clone") wally_tx_input_clone_alloc;
%returns_void__(wally_tx_input_free);
%returns_array_(wally_tx_input_get_blinding_nonce, 2, 3, SHA256_LEN);
%returns_array_(wally_tx_input_get_entropy, 2, 3, SHA256_LEN);
Expand Down
1 change: 1 addition & 0 deletions src/swig_python/python_extra.py_in
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ tx_get_output_script = _wrap_bin(tx_get_output_script, tx_get_output_script_len)
tx_get_signature_hash = _wrap_bin(tx_get_signature_hash, SHA256_LEN)
tx_get_txid = _wrap_bin(tx_get_txid, WALLY_TXHASH_LEN)
tx_init = tx_init_alloc
tx_input_clone = tx_input_clone_alloc
tx_input_get_script = _wrap_bin(tx_input_get_script, tx_input_get_script_len)
tx_input_get_txhash = _wrap_bin(tx_input_get_txhash, WALLY_TXHASH_LEN)
tx_input_get_witness = _wrap_bin(tx_input_get_witness, tx_input_get_witness_len)
Expand Down
1 change: 1 addition & 0 deletions src/swig_python/swig.i
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ static void destroy_words(PyObject *obj) { (void)obj; }
%ignore wally_psbt_blind;
%ignore wally_psbt_get_input_best_utxo;
%ignore wally_tx_elements_output_init;
%ignore wally_tx_input_clone;
%ignore wally_tx_output_clone;
%ignore wally_tx_output_init;
/* END AUTOGENERATED */
Expand Down
2 changes: 2 additions & 0 deletions src/test/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,8 @@ class wally_psbt(Structure):
('wally_tx_get_weight', c_int, [POINTER(wally_tx), c_size_t_p]),
('wally_tx_get_witness_count', c_int, [POINTER(wally_tx), c_size_t_p]),
('wally_tx_init_alloc', c_int, [c_uint32, c_uint32, c_size_t, c_size_t, POINTER(POINTER(wally_tx))]),
('wally_tx_input_clone', c_int, [POINTER(wally_tx_input), POINTER(wally_tx_input)]),
('wally_tx_input_clone_alloc', c_int, [POINTER(wally_tx_input), POINTER(POINTER(wally_tx_input))]),
('wally_tx_input_free', c_int, [POINTER(wally_tx_input)]),
('wally_tx_input_init_alloc', c_int, [c_void_p, c_size_t, c_uint32, c_uint32, c_void_p, c_size_t, POINTER(wally_tx_witness_stack), POINTER(POINTER(wally_tx_input))]),
('wally_tx_is_coinbase', c_int, [POINTER(wally_tx), c_size_t_p]),
Expand Down
50 changes: 35 additions & 15 deletions src/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,8 @@ int wally_tx_witness_stack_set_dummy(struct wally_tx_witness_stack *stack,
return wally_tx_witness_stack_set(stack, index, p, len);
}

static bool clone_input_to(
struct wally_tx_input *dst,
const struct wally_tx_input *src)
int wally_tx_input_clone(const struct wally_tx_input *src,
struct wally_tx_input *output)
{
unsigned char *new_script = NULL;
#ifdef BUILD_ELEMENTS
Expand All @@ -369,6 +368,9 @@ static bool clone_input_to(
#endif
struct wally_tx_witness_stack *new_witness = NULL;

if (!src || !output)
return WALLY_EINVAL;

if (src->witness)
wally_tx_witness_stack_clone_alloc(src->witness, &new_witness);

Expand All @@ -394,20 +396,36 @@ static bool clone_input_to(
wally_tx_witness_stack_free(new_pegin_witness);
#endif
wally_tx_witness_stack_free(new_witness);
return false;
return WALLY_ENOMEM;
}

memcpy(dst, src, sizeof(*src));
dst->script = new_script;
memcpy(output, src, sizeof(*src));
output->script = new_script;
#ifdef BUILD_ELEMENTS
dst->issuance_amount = new_issuance_amount;
dst->inflation_keys = new_inflation_keys;
dst->issuance_amount_rangeproof = new_issuance_amount_rangeproof;
dst->inflation_keys_rangeproof = new_inflation_keys_rangeproof;
dst->pegin_witness = new_pegin_witness;
output->issuance_amount = new_issuance_amount;
output->inflation_keys = new_inflation_keys;
output->issuance_amount_rangeproof = new_issuance_amount_rangeproof;
output->inflation_keys_rangeproof = new_inflation_keys_rangeproof;
output->pegin_witness = new_pegin_witness;
#endif
dst->witness = new_witness;
return true;
output->witness = new_witness;
return WALLY_OK;
}

int wally_tx_input_clone_alloc(const struct wally_tx_input *src,
struct wally_tx_input **output)
{
int ret;

OUTPUT_CHECK;
OUTPUT_ALLOC(struct wally_tx_input);

ret = wally_tx_input_clone(src, *output);
if (ret != WALLY_OK) {
wally_free(*output);
*output = NULL;
}
return ret;
}

static int tx_elements_input_issuance_proof_init(
Expand Down Expand Up @@ -1214,6 +1232,8 @@ int wally_tx_free(struct wally_tx *tx)
int wally_tx_add_input_at(struct wally_tx *tx, uint32_t index,
const struct wally_tx_input *input)
{
int ret;

if (!is_valid_tx(tx) || index > tx->num_inputs || !is_valid_tx_input(input))
return WALLY_EINVAL;

Expand All @@ -1233,10 +1253,10 @@ int wally_tx_add_input_at(struct wally_tx *tx, uint32_t index,
memmove(tx->inputs + index + 1, tx->inputs + index,
(tx->num_inputs - index) * sizeof(*input));

if (!clone_input_to(tx->inputs + index, input)) {
if ((ret = wally_tx_input_clone(input, tx->inputs + index)) != WALLY_OK) {
memmove(tx->inputs + index, tx->inputs + index + 1,
(tx->num_inputs - index) * sizeof(*input)); /* Undo */
return WALLY_ENOMEM;
return ret;
}

tx->num_inputs += 1;
Expand Down
2 changes: 2 additions & 0 deletions src/wasm_package/src/functions.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/wasm_package/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,8 @@ export function tx_get_vsize(tx: Ref_wally_tx): number;
export function tx_get_weight(tx: Ref_wally_tx): number;
export function tx_get_witness_count(tx: Ref_wally_tx): number;
export function tx_init(version: number, locktime: number, inputs_allocation_len: number, outputs_allocation_len: number): Ref_wally_tx;
export function tx_input_clone(tx_input_in: Ref_wally_tx_input): Ref_wally_tx_input;
export function tx_input_clone_noalloc(tx_input_in: Ref_wally_tx_input, input: Ref_wally_tx_input): void;
export function tx_input_free(input: Ref_wally_tx_input): void;
export function tx_input_get_blinding_nonce(tx_input_in: Ref_wally_tx_input): Buffer;
export function tx_input_get_entropy(tx_input_in: Ref_wally_tx_input): Buffer;
Expand Down
2 changes: 2 additions & 0 deletions tools/wasm_exports.sh
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ EXPORTED_FUNCTIONS="['_malloc','_free','_bip32_key_free' \
,'_wally_tx_get_weight' \
,'_wally_tx_get_witness_count' \
,'_wally_tx_init_alloc' \
,'_wally_tx_input_clone' \
,'_wally_tx_input_clone_alloc' \
,'_wally_tx_input_free' \
,'_wally_tx_input_get_index' \
,'_wally_tx_input_get_script' \
Expand Down

0 comments on commit f48dc58

Please sign in to comment.