Browse Source

txprepare: elements requires inclusion of an accurate fee output

so we add an accurate one
bump-pyln-proto
niftynei 4 years ago
committed by Rusty Russell
parent
commit
4c28e7b362
  1. 45
      bitcoin/psbt.c
  2. 8
      bitcoin/psbt.h
  3. 4
      plugins/txprepare.c

45
bitcoin/psbt.c

@ -308,6 +308,51 @@ void psbt_elements_input_set_asset(struct wally_psbt *psbt, size_t in,
abort(); abort();
} }
void psbt_elements_normalize_fees(struct wally_psbt *psbt)
{
struct amount_asset asset;
size_t fee_output_idx = psbt->num_outputs;
if (!is_elements(chainparams))
return;
/* Elements requires that every input value is accounted for,
* including the fees */
struct amount_sat total_in = AMOUNT_SAT(0), val;
for (size_t i = 0; i < psbt->num_inputs; i++) {
val = psbt_input_get_amount(psbt, i);
if (!amount_sat_add(&total_in, total_in, val))
return;
}
for (size_t i = 0; i < psbt->num_outputs; i++) {
asset = wally_tx_output_get_amount(&psbt->tx->outputs[i]);
if (elements_wtx_output_is_fee(psbt->tx, i)) {
fee_output_idx = i;
continue;
}
if (!amount_asset_is_main(&asset))
continue;
if (!amount_sat_sub(&total_in, total_in,
amount_asset_to_sat(&asset)))
return;
}
if (amount_sat_eq(total_in, AMOUNT_SAT(0)))
return;
/* We need to add a fee output */
if (fee_output_idx == psbt->num_outputs) {
psbt_append_output(psbt, NULL, total_in);
} else {
u64 sats = total_in.satoshis; /* Raw: wally API */
struct wally_tx_output *out = &psbt->tx->outputs[fee_output_idx];
if (wally_tx_confidential_value_from_satoshi(
sats, out->value, out->value_len) != WALLY_OK)
return;
}
}
bool psbt_has_input(struct wally_psbt *psbt, bool psbt_has_input(struct wally_psbt *psbt,
struct bitcoin_txid *txid, struct bitcoin_txid *txid,
u32 outnum) u32 outnum)

8
bitcoin/psbt.h

@ -69,6 +69,14 @@ bool psbt_is_finalized(const struct wally_psbt *psbt);
void psbt_txid(const struct wally_psbt *psbt, struct bitcoin_txid *txid, void psbt_txid(const struct wally_psbt *psbt, struct bitcoin_txid *txid,
struct wally_tx **wtx); struct wally_tx **wtx);
/* psbt_elements_normalize_fees - Figure out the fee output for a PSET
*
* Adds a fee output if not present, or updates it to include the diff
* between inputs - outputs. Unlike bitcoin, elements requires every
* satoshi to be accounted for in an output.
*/
void psbt_elements_normalize_fees(struct wally_psbt *psbt);
struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place); struct wally_tx *psbt_finalize(struct wally_psbt *psbt, bool finalize_in_place);
/* psbt_make_key - Create a new, proprietary c-lightning key /* psbt_make_key - Create a new, proprietary c-lightning key

4
plugins/txprepare.c

@ -191,6 +191,10 @@ static struct command_result *finish_txprepare(struct command *cmd,
psbt_add_output(txp->psbt, out, i); psbt_add_output(txp->psbt, out, i);
} }
/* If this is elements, we should normalize
* the PSBT fee output */
psbt_elements_normalize_fees(txp->psbt);
utx = tal(NULL, struct unreleased_tx); utx = tal(NULL, struct unreleased_tx);
utx->psbt = tal_steal(utx, txp->psbt); utx->psbt = tal_steal(utx, txp->psbt);
psbt_txid(txp->psbt, &utx->txid, &utx->tx); psbt_txid(txp->psbt, &utx->txid, &utx->tx);

Loading…
Cancel
Save