mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
onchaind: use lowball fee instead of donating to miners.
As of bitcoind 0.16.1, you can't send a single-input OP_RETURN output, as you get 'tx-too-small'. sendrawtx exit 26, gave error code: -26?error message:?tx-size-small (code 64)?' So instead we use the minimum fee we can, but otherwise ignore it and don't wait for it to be mined. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
0e6c0dbba2
commit
c78afa9201
@@ -1,3 +1,4 @@
|
|||||||
|
#include <bitcoin/feerate.h>
|
||||||
#include <bitcoin/script.h>
|
#include <bitcoin/script.h>
|
||||||
#include <ccan/crypto/shachain/shachain.h>
|
#include <ccan/crypto/shachain/shachain.h>
|
||||||
#include <ccan/mem/mem.h>
|
#include <ccan/mem/mem.h>
|
||||||
@@ -274,12 +275,30 @@ static struct bitcoin_tx *tx_to_us(const tal_t *ctx,
|
|||||||
+ 1 + 3 + 73 + 0 + tal_len(wscript))
|
+ 1 + 3 + 73 + 0 + tal_len(wscript))
|
||||||
/ 1000;
|
/ 1000;
|
||||||
|
|
||||||
/* Result is trivial? Spent to OP_RETURN to avoid leaving dust. */
|
/* Result is trivial? Spend with small feerate, but don't wait
|
||||||
|
* around for it as it might not confirm. */
|
||||||
if (tx->output[0].amount < dust_limit_satoshis + fee) {
|
if (tx->output[0].amount < dust_limit_satoshis + fee) {
|
||||||
tx->output[0].amount = 0;
|
/* FIXME: We should use SIGHASH_NONE so others can take it */
|
||||||
tx->output[0].script = scriptpubkey_opreturn(tx->output);
|
fee = feerate_floor() * (measure_tx_weight(tx)
|
||||||
*tx_type = DONATING_TO_MINERS;
|
+ 1 + 3 + 73 + 0 + tal_len(wscript))
|
||||||
|
/ 1000;
|
||||||
|
/* This shouldn't happen (we don't set feerate below floor!),
|
||||||
|
* but just in case. */
|
||||||
|
if (tx->output[0].amount < dust_limit_satoshis + fee) {
|
||||||
|
fee = tx->output[0].amount - dust_limit_satoshis;
|
||||||
|
status_broken("TX %s can't afford minimal feerate"
|
||||||
|
"; setting fee to %"PRIu64,
|
||||||
|
tx_type_name(*tx_type),
|
||||||
|
fee);
|
||||||
} else
|
} else
|
||||||
|
status_unusual("TX %s amount %"PRIu64" too small to"
|
||||||
|
" pay reasonable fee, using minimal fee"
|
||||||
|
" and ignoring",
|
||||||
|
tx_type_name(*tx_type),
|
||||||
|
out->satoshi);
|
||||||
|
|
||||||
|
*tx_type = IGNORING_TINY_PAYMENT;
|
||||||
|
}
|
||||||
tx->output[0].amount -= fee;
|
tx->output[0].amount -= fee;
|
||||||
|
|
||||||
sign_tx_input(tx, 0, NULL, wscript, privkey, pubkey, &sig);
|
sign_tx_input(tx, 0, NULL, wscript, privkey, pubkey, &sig);
|
||||||
@@ -361,6 +380,13 @@ static void proposal_meets_depth(struct tracked_output *out)
|
|||||||
wire_sync_write(REQ_FD,
|
wire_sync_write(REQ_FD,
|
||||||
take(towire_onchain_broadcast_tx(NULL,
|
take(towire_onchain_broadcast_tx(NULL,
|
||||||
out->proposal->tx)));
|
out->proposal->tx)));
|
||||||
|
|
||||||
|
/* Don't wait for this if we're ignoring the tiny payment. */
|
||||||
|
if (out->proposal->tx_type == IGNORING_TINY_PAYMENT) {
|
||||||
|
ignore_output(out);
|
||||||
|
out->proposal = tal_free(out->proposal);
|
||||||
|
}
|
||||||
|
|
||||||
/* We will get a callback when it's in a block. */
|
/* We will get a callback when it's in a block. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ enum tx_type {
|
|||||||
OUR_PENALTY_TX,
|
OUR_PENALTY_TX,
|
||||||
|
|
||||||
/* Amount too small, we're just spending it to close UTXO */
|
/* Amount too small, we're just spending it to close UTXO */
|
||||||
DONATING_TO_MINERS,
|
IGNORING_TINY_PAYMENT,
|
||||||
|
|
||||||
/* Special type for marking outputs as resolved by self. */
|
/* Special type for marking outputs as resolved by self. */
|
||||||
SELF,
|
SELF,
|
||||||
|
|||||||
@@ -108,6 +108,10 @@ bool per_commit_point(const struct sha256 *shaseed UNNEEDED,
|
|||||||
void status_failed(enum status_failreason code UNNEEDED,
|
void status_failed(enum status_failreason code UNNEEDED,
|
||||||
const char *fmt UNNEEDED, ...)
|
const char *fmt UNNEEDED, ...)
|
||||||
{ fprintf(stderr, "status_failed called!\n"); abort(); }
|
{ fprintf(stderr, "status_failed called!\n"); abort(); }
|
||||||
|
/* Generated stub for status_fmt */
|
||||||
|
void status_fmt(enum log_level level UNNEEDED, const char *fmt UNNEEDED, ...)
|
||||||
|
|
||||||
|
{ fprintf(stderr, "status_fmt called!\n"); abort(); }
|
||||||
/* Generated stub for status_setup_sync */
|
/* Generated stub for status_setup_sync */
|
||||||
void status_setup_sync(int fd UNNEEDED)
|
void status_setup_sync(int fd UNNEEDED)
|
||||||
{ fprintf(stderr, "status_setup_sync called!\n"); abort(); }
|
{ fprintf(stderr, "status_setup_sync called!\n"); abort(); }
|
||||||
|
|||||||
@@ -2206,26 +2206,22 @@ class LightningDTests(BaseLightningDTests):
|
|||||||
l2.daemon.wait_for_log(' to ONCHAIN')
|
l2.daemon.wait_for_log(' to ONCHAIN')
|
||||||
|
|
||||||
# Wait for timeout.
|
# Wait for timeout.
|
||||||
l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/OUR_HTLC by DONATING_TO_MINERS .* after 6 blocks')
|
l1.daemon.wait_for_log('Propose handling THEIR_UNILATERAL/OUR_HTLC by IGNORING_TINY_PAYMENT .* after 6 blocks')
|
||||||
bitcoind.generate_block(6)
|
bitcoind.generate_block(5)
|
||||||
|
|
||||||
l1.daemon.wait_for_log('sendrawtx exit 0')
|
l1.daemon.wait_for_logs(['Broadcasting IGNORING_TINY_PAYMENT .* to resolve THEIR_UNILATERAL/OUR_HTLC',
|
||||||
bitcoind.generate_block(1)
|
'sendrawtx exit 0',
|
||||||
|
'Ignoring output 0 of .*: THEIR_UNILATERAL/OUR_HTLC'])
|
||||||
l1.daemon.wait_for_log('Resolved THEIR_UNILATERAL/OUR_HTLC by our proposal DONATING_TO_MINERS')
|
|
||||||
|
|
||||||
# 100 deep and l2 forgets.
|
# 100 deep and l2 forgets.
|
||||||
bitcoind.generate_block(91)
|
bitcoind.generate_block(93)
|
||||||
sync_blockheight([l2])
|
sync_blockheight([l1, l2])
|
||||||
assert not l2.daemon.is_in_log('onchaind complete, forgetting peer')
|
assert not l2.daemon.is_in_log('onchaind complete, forgetting peer')
|
||||||
|
assert not l1.daemon.is_in_log('onchaind complete, forgetting peer')
|
||||||
bitcoind.generate_block(1)
|
bitcoind.generate_block(1)
|
||||||
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
|
l2.daemon.wait_for_log('onchaind complete, forgetting peer')
|
||||||
|
|
||||||
# l1 forgets 100 blocks after DONATING_TO_MINERS.
|
# l1 does not wait for ignored payment.
|
||||||
bitcoind.generate_block(6)
|
|
||||||
sync_blockheight([l1])
|
|
||||||
assert not l1.daemon.is_in_log('onchaind complete, forgetting peer')
|
|
||||||
bitcoind.generate_block(1)
|
|
||||||
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
|
l1.daemon.wait_for_log('onchaind complete, forgetting peer')
|
||||||
|
|
||||||
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_fail")
|
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_fail")
|
||||||
|
|||||||
Reference in New Issue
Block a user