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 <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-04-16 22:30:25 +02:00 committed by Rusty Russell
parent 357322d721
commit 6b7c3c7a78
2 changed files with 42 additions and 2 deletions

View File

@ -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;
}

View File

@ -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();