tx: Use the context chainparams to determine the fee asset

This is the main reason we started weaving the chainparams everywhere: being
able to compare the asset type with the fee paying asset tag, thus determining
the value of the asset correctly (we still treat any non-fee-paying assets as
having value 0).

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-07-30 21:09:47 +02:00 committed by Rusty Russell
parent 9f3922344b
commit fad9a74662
3 changed files with 22 additions and 21 deletions

View File

@ -14,13 +14,6 @@
#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)
{
@ -28,9 +21,11 @@ int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script,
struct wally_tx_output *output;
int ret;
u64 satoshis = amount.satoshis; /* Raw: low-level helper */
const struct chainparams *chainparams = tx->chainparams;
assert(i < tx->wtx->outputs_allocation_len);
assert(tx->wtx != NULL);
assert(chainparams);
if (is_elements) {
u8 value[9];
@ -38,9 +33,8 @@ int bitcoin_tx_add_output(struct bitcoin_tx *tx, const u8 *script,
sizeof(value));
assert(ret == WALLY_OK);
ret = wally_tx_elements_output_init_alloc(
script, tal_bytelen(script), bitcoin_asset,
sizeof(bitcoin_asset), value, sizeof(value), NULL, 0, NULL,
0, NULL, 0, &output);
script, tal_bytelen(script), chainparams->fee_asset_tag, 33,
value, sizeof(value), NULL, 0, NULL, 0, NULL, 0, &output);
assert(ret == WALLY_OK);
/* Cheat a bit by also setting the numeric satoshi value,
* otherwise we end up converting a number of times */
@ -212,19 +206,24 @@ struct amount_sat bitcoin_tx_output_get_amount(const struct bitcoin_tx *tx,
struct amount_sat amount;
struct wally_tx_output *output;
u64 satoshis;
const u8 *fee_asset_tag;
assert(tx->chainparams);
assert(outnum < tx->wtx->num_outputs);
output = &tx->wtx->outputs[outnum];
fee_asset_tag = tx->chainparams->fee_asset_tag;
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 {
if (fee_asset_tag) {
if (memeq(fee_asset_tag, 33, output->asset, output->asset_len)) {
be64 raw;
memcpy(&raw, output->value + 1, sizeof(raw));
satoshis = be64_to_cpu(raw);
} else {
/* 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 {
satoshis = tx->wtx->outputs[outnum].satoshi;
}

View File

@ -207,7 +207,7 @@ static void signature_from_hex(const char *hex, struct bitcoin_signature *sig)
/* We don't have enough info to make this from first principles, but we have
* an example tx, so just mangle that. */
struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
const struct chainparams *chainparams UNNEEDED,
const struct chainparams *chainparams,
const struct bitcoin_txid *commit_txid UNNEEDED,
unsigned int commit_output_number UNNEEDED,
struct amount_msat htlc_msatoshi,
@ -225,6 +225,7 @@ struct bitcoin_tx *htlc_timeout_tx(const tal_t *ctx,
in_amount = amount_msat_to_sat_round_down(htlc_msatoshi);
tx->input_amounts[0] = tal_dup(tx, struct amount_sat, &in_amount);
tx->chainparams = chainparams;
tx->wtx->locktime = cltv_expiry;
return tx;

View File

@ -203,6 +203,7 @@ int main(int argc, char *argv[])
setup_tmpctx();
tx = bitcoin_tx_from_hex(tmpctx, "0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000",
strlen("0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000"));
tx->chainparams = chainparams_for_network("regtest");
tx->input_amounts[0] = tal(tx, struct amount_sat);
*tx->input_amounts[0] = AMOUNT_SAT(700000);
tx->chainparams = chainparams_for_network("bitcoin");