psbt: utilities for adding unknown info / proprietary c-lightning keydata

This commit is contained in:
niftynei 2020-07-22 21:08:12 -05:00 committed by Rusty Russell
parent 251cde3514
commit 3923e0f0fd
2 changed files with 156 additions and 0 deletions

View File

@ -6,6 +6,7 @@
#include <bitcoin/signature.h>
#include <ccan/cast/cast.h>
#include <ccan/ccan/array_size/array_size.h>
#include <ccan/ccan/mem/mem.h>
#include <ccan/tal/str/str.h>
#include <common/amount.h>
#include <common/type_to_string.h>
@ -420,6 +421,105 @@ struct amount_sat psbt_output_get_amount(struct wally_psbt *psbt,
assert(amount_asset_is_main(&asset));
return amount_asset_to_sat(&asset);
}
static void add(u8 **key, const void *mem, size_t len)
{
size_t oldlen = tal_count(*key);
tal_resize(key, oldlen + len);
memcpy(*key + oldlen, memcheck(mem, len), len);
}
static void add_type(u8 **key, const u8 num)
{
add(key, &num, 1);
}
static void add_varint(u8 **key, size_t val)
{
u8 vt[VARINT_MAX_LEN];
size_t vtlen;
vtlen = varint_put(vt, val);
add(key, vt, vtlen);
}
#define LIGHTNING_PROPRIETARY_PREFIX "lightning"
u8 *psbt_make_key(const tal_t *ctx, u8 key_subtype, const u8 *key_data)
{
/**
* BIP174:
* Type: Proprietary Use Type <tt>PSBT_GLOBAL_PROPRIETARY = 0xFC</tt>
** Key: Variable length identifier prefix, followed
* by a subtype, followed by the key data itself.
*** <tt>{0xFC}|<prefix>|{subtype}|{key data}</tt>
** Value: Any value data as defined by the proprietary type user.
*** <tt><data></tt>
*/
u8 *key = tal_arr(ctx, u8, 0);
add_type(&key, PSBT_PROPRIETARY_TYPE);
add_varint(&key, strlen(LIGHTNING_PROPRIETARY_PREFIX));
add(&key, LIGHTNING_PROPRIETARY_PREFIX,
strlen(LIGHTNING_PROPRIETARY_PREFIX));
add_type(&key, key_subtype);
if (key_data)
add(&key, key_data, tal_bytelen(key_data));
return key;
}
void psbt_input_add_unknown(struct wally_psbt_input *in,
const u8 *key,
const void *value,
size_t value_len)
{
if (wally_map_add(&in->unknowns,
cast_const(unsigned char *, key), tal_bytelen(key),
(unsigned char *) memcheck(value, value_len), value_len)
!= WALLY_OK)
abort();
}
void *psbt_get_unknown(const struct wally_map *map,
const u8 *key,
size_t *val_len)
{
size_t index;
if (wally_map_find(map, key, tal_bytelen(key), &index) != WALLY_OK)
return NULL;
/* Zero: item not found. */
if (index == 0)
return NULL;
/* ++: item is at this index minus 1 */
*val_len = map->items[index - 1].value_len;
return map->items[index - 1].value;
}
void *psbt_get_lightning(const struct wally_map *map,
const u8 proprietary_type,
size_t *val_len)
{
void *res;
u8 *key = psbt_make_key(NULL, proprietary_type, NULL);
res = psbt_get_unknown(map, key, val_len);
tal_free(key);
return res;
}
void psbt_output_add_unknown(struct wally_psbt_output *out,
const u8 *key,
const void *value,
size_t value_len)
{
if (wally_map_add(&out->unknowns,
cast_const(unsigned char *, key), tal_bytelen(key),
(unsigned char *) memcheck(value, value_len), value_len)
!= WALLY_OK)
abort();
}
struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place)
{
struct wally_psbt *tmppsbt;
@ -518,6 +618,8 @@ char *psbt_to_b64(const tal_t *ctx, const struct wally_psbt *psbt)
wally_free_string(serialized_psbt);
return ret_val;
}
/* Do not remove this line, it is magic */
REGISTER_TYPE_TO_STRING(wally_psbt, psbt_to_b64);
const u8 *psbt_get_bytes(const tal_t *ctx, const struct wally_psbt *psbt,

View File

@ -10,6 +10,7 @@ struct wally_psbt_input;
struct wally_tx;
struct wally_tx_input;
struct wally_tx_output;
struct wally_map;
struct amount_asset;
struct amount_sat;
struct bitcoin_signature;
@ -59,6 +60,16 @@ void psbt_txid(const struct wally_psbt *psbt, struct bitcoin_txid *txid,
struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place);
/* psbt_make_key - Create a new, proprietary c-lightning key
*
* @ctx - allocation context
* @key_subtype - type for this key
* @key_data - any extra data to append to the key
*
* Returns a proprietary-prefixed key.
*/
u8 *psbt_make_key(const tal_t *ctx, u8 key_subtype, const u8 *key_data);
struct wally_psbt_input *psbt_add_input(struct wally_psbt *psbt,
struct wally_tx_input *input,
size_t insert_at);
@ -112,6 +123,49 @@ void psbt_elements_input_init_witness(struct wally_psbt *psbt, size_t in,
const u8 *nonce);
bool psbt_input_set_redeemscript(struct wally_psbt *psbt, size_t in,
const u8 *redeemscript);
/* psbt_input_add_unknown - Add the given Key-Value to the psbt's input keymap
* @in - psbt input to add key-value to
* @key - key for key-value pair
* @value - value to add
* @value_len - length of {@value}
*/
void psbt_input_add_unknown(struct wally_psbt_input *in,
const u8 *key,
const void *value,
size_t value_len);
/* psbt_get_unknown - Fetch the value from the given map at key
*
* @map - map of unknowns to search for key
* @key - key of key-value pair to return value for
* @value_len - (out) length of value (if found)
*
* Returns: value at @key, or NULL if not found */
void *psbt_get_unknown(const struct wally_map *map,
const u8 *key,
size_t *val_len);
/* psbt_get_lightning - Fetch a proprietary lightning value from the given map
*
* @map - map of unknowns to search for key
* @proprietary_type - type no. to look for
* @val_len - (out) length of value (if found)
*
* Returns: value of type {proprietary_type}, or NULL if not found */
void *psbt_get_lightning(const struct wally_map *map,
const u8 proprietary_type,
size_t *val_len);
/* psbt_output_add_unknown - Add the given Key-Value to the psbt's output keymap
*
* @out - psbt output to add key-value to
* @key - key for key-value pair
* @value - value to add
* @value_len - length of {@value}
*/
void psbt_output_add_unknown(struct wally_psbt_output *out,
const u8 *key, const void *value,
size_t value_len);
/* psbt_input_get_amount - Returns the value of this input
*
* @psbt - psbt