mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
elements: Fix up existing fee output instead of adding a new one
Especially when we grind fees we may end up setting the fees several times, so instead of always adding a new fee output look for an existing one and set its value. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
b356dda0ba
commit
99988cb0e1
29
bitcoin/tx.c
29
bitcoin/tx.c
@ -68,6 +68,12 @@ int bitcoin_tx_add_multi_outputs(struct bitcoin_tx *tx,
|
||||
return tx->wtx->num_outputs;
|
||||
}
|
||||
|
||||
static bool bitcoin_tx_output_is_fee(const struct bitcoin_tx *tx, int outnum)
|
||||
{
|
||||
assert(outnum < tx->wtx->num_outputs);
|
||||
return is_elements && tx->wtx->outputs[outnum].script_len == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute how much fee we are actually sending with this transaction.
|
||||
*/
|
||||
@ -79,6 +85,9 @@ static u64 bitcoin_tx_compute_fee(const struct bitcoin_tx *tx)
|
||||
fee += tx->input_amounts[i]->satoshis; /* Raw: fee computation */
|
||||
|
||||
for (size_t i=0; i<tx->wtx->num_outputs; i++) {
|
||||
if (bitcoin_tx_output_is_fee(tx, i))
|
||||
continue;
|
||||
|
||||
if (!is_elements) {
|
||||
fee -= tx->wtx->outputs[i].satoshi; /* Raw: low-level helper */
|
||||
} else {
|
||||
@ -95,13 +104,28 @@ static u64 bitcoin_tx_compute_fee(const struct bitcoin_tx *tx)
|
||||
int bitcoin_tx_add_fee_output(struct bitcoin_tx *tx)
|
||||
{
|
||||
struct amount_sat fee;
|
||||
int pos = -1;
|
||||
u64 rawsats = bitcoin_tx_compute_fee(tx); /* Raw: pedantic much? */
|
||||
fee.satoshis = rawsats; /* Raw: need amounts later */
|
||||
|
||||
/* If we aren't using elements, we don't add explicit fee outputs */
|
||||
if (!is_elements || rawsats == 0)
|
||||
return -1;
|
||||
return bitcoin_tx_add_output(tx, NULL, fee);
|
||||
|
||||
/* Try to find any existing fee output */
|
||||
for (int i=0; i<tx->wtx->num_outputs; i++) {
|
||||
if (bitcoin_tx_output_is_fee(tx, i)) {
|
||||
assert(pos == -1);
|
||||
pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == -1) {
|
||||
return bitcoin_tx_add_output(tx, NULL, fee);
|
||||
} else {
|
||||
bitcoin_tx_output_set_amount(tx, pos, fee);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid,
|
||||
@ -139,9 +163,6 @@ bool bitcoin_tx_check(const struct bitcoin_tx *tx)
|
||||
|
||||
if (is_elements) {
|
||||
flags |= WALLY_TX_FLAG_USE_ELEMENTS;
|
||||
/* Elements transactions must have an explicit fee */
|
||||
if (bitcoin_tx_compute_fee(tx) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
newtx = tal_arr(tmpctx, u8, written);
|
||||
|
@ -153,8 +153,7 @@ bool bitcoin_tx_check(const struct bitcoin_tx *tx);
|
||||
*
|
||||
* An explicit fee output is only necessary if we are using an elements
|
||||
* transaction, and we have a non-zero fee. This method may be called multiple
|
||||
* times if input and output values do not change, however it may result in
|
||||
* multiple change outputs if the fee is changed.
|
||||
* times.
|
||||
*
|
||||
* Returns the position of the fee output, or -1 in the case of non-elements
|
||||
* transactions.
|
||||
|
Loading…
Reference in New Issue
Block a user