From 6b7c3c7a78d4cf545d7f5ada9896e156f98cdcb8 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Tue, 16 Apr 2019 22:30:25 +0200 Subject: [PATCH] elements: Extract the real value from the transactions If we are handling an elements transaction the value is not stored in the satoshi field, rather it is stored in the `value` field which is prefixed with a version (0x01) and is counted in `asset` units. Signed-off-by: Christian Decker --- bitcoin/tx.c | 42 ++++++++++++++++++++++++++++++++++++++++-- hsmd/hsmd.c | 2 ++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/bitcoin/tx.c b/bitcoin/tx.c index 10eff9fb3..de09f7d3b 100644 --- a/bitcoin/tx.c +++ b/bitcoin/tx.c @@ -14,6 +14,13 @@ #define SEGREGATED_WITNESS_FLAG 0x1 +static u8 bitcoin_asset[] = + { + 0x01, 0x5c, 0xe7, 0xb9, 0x63, 0xd3, 0x7f, 0x8f, 0x2d, 0x51, 0xca, + 0xfb, 0xba, 0x92, 0x8a, 0xaa, 0x9e, 0x22, 0x0b, 0x8b, 0xbc, 0x66, + 0x05, 0x71, 0x49, 0x9c, 0x03, 0x62, 0x8a, 0x38, 0x51, 0xb8, 0xce, + }; + int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script, struct amount_sat amount) { @@ -86,8 +93,22 @@ bool bitcoin_tx_check(const struct bitcoin_tx *tx) void bitcoin_tx_output_set_amount(struct bitcoin_tx *tx, int outnum, struct amount_sat amount) { + u64 satoshis = amount.satoshis; /* Raw: low-level helper */ + struct wally_tx_output *output = &tx->wtx->outputs[outnum]; assert(outnum < tx->wtx->num_outputs); - tx->wtx->outputs[outnum].satoshi = amount.satoshis; /* Raw: low-level helper */ + if (is_elements) { + u8 raw[9]; + be64 rawu64; + output->asset = bitcoin_asset; + output->asset_len = sizeof(bitcoin_asset); + output->value_len = 9; + raw[0] = 0x01; /* Value version 01 */ + rawu64 = cpu_to_be64(satoshis); + memcpy(raw+1, &rawu64, 8); + output->satoshi = UINT64_MAX; + } else { + output->satoshi = satoshis; + } } const u8 *bitcoin_tx_output_get_script(const tal_t *ctx, @@ -109,8 +130,25 @@ struct amount_sat bitcoin_tx_output_get_amount(const struct bitcoin_tx *tx, int outnum) { struct amount_sat amount; + struct wally_tx_output *output; + u64 satoshis; assert(outnum < tx->wtx->num_outputs); - amount.satoshis = tx->wtx->outputs[outnum].satoshi; /* Raw: helper */ + output = &tx->wtx->outputs[outnum]; + + if (is_elements && !memeq(output->asset, output->asset_len, + bitcoin_asset, sizeof(bitcoin_asset))) { + /* If this is an asset based tx, and we don't know the asset + * type, i.e., it's not bitcoin, return a 0 amount */ + satoshis = 0; + } else if (is_elements) { + be64 raw; + memcpy(&raw, output->value + 1, sizeof(raw)); + satoshis = be64_to_cpu(raw); + }else { + satoshis = tx->wtx->outputs[outnum].satoshi; + } + + amount.satoshis = satoshis; /* Raw: helper */ return amount; } diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index b7e9bc9c2..c90f2788c 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -603,6 +603,8 @@ static struct io_plan *init_hsm(struct io_conn *conn, /* Once we have read the init message we know which params the master * will use */ c->chainparams = chainparams_by_chainhash(&chain_hash); + is_elements = c->chainparams->is_elements; + maybe_create_new_hsm(); load_hsm();