# We can now use RBF, but the feerate must be higher than that of the first transaction.
with pytest.raises(RpcError, match=f"Feerate 1 too low for minimum feerate 2."):
lianad.rpc.rbfpsbt(first_txid, False, 1)
# Using a higher feerate works.
lianad.rpc.rbfpsbt(first_txid, False, 2)
# Let's use an even higher feerate.
rbf_1_res = lianad.rpc.rbfpsbt(first_txid, False, 10)
rbf_1_psbt = PSBT.from_base64(rbf_1_res["psbt"])
# Check the locktime is being set.
tip_height = bitcoind.rpc.getblockcount()
locktime = rbf_1_psbt.tx.nLockTime
assert tip_height - 100 <= locktime <= tip_height
# The inputs are the same in both (no new inputs needed in the replacement).
assert sorted(i.prevout.serialize() for i in first_psbt.tx.vin) == sorted(
i.prevout.serialize() for i in rbf_1_psbt.tx.vin
)
# Check non-change output is the same in both.
assert first_psbt.tx.vout[0].nValue == rbf_1_psbt.tx.vout[0].nValue
assert first_psbt.tx.vout[0].scriptPubKey == rbf_1_psbt.tx.vout[0].scriptPubKey
# Change address is the same but change amount will be lower in the replacement to pay higher fee.
assert first_psbt.tx.vout[1].nValue > rbf_1_psbt.tx.vout[1].nValue
assert first_psbt.tx.vout[1].scriptPubKey == rbf_1_psbt.tx.vout[1].scriptPubKey
# Broadcast the replacement and wait for it to be detected.
rbf_1_txid = sign_and_broadcast_psbt(lianad, rbf_1_psbt)
wait_for(
lambda: all(
c["spend_info"] is not None and c["spend_info"]["txid"] == rbf_1_txid
for c in lianad.rpc.listcoins([], first_outpoints)["coins"]
)
)
mempool_rbf_1 = bitcoind.rpc.getmempoolentry(rbf_1_txid)
# Note that in the mempool entry, "ancestor" includes rbf_1_txid itself.
rbf_1_feerate = (
mempool_rbf_1["fees"]["ancestor"] * COIN / mempool_rbf_1["ancestorsize"]
)
assert 9.75 < rbf_1_feerate < 10.25
# If we try to RBF the first transaction again, it will use the first RBF's
# feerate to set the min feerate, instead of 1 sat/vb of first
# transaction:
> with pytest.raises(
RpcError, match=f"Feerate {int(rbf_1_feerate)} too low for minimum feerate 10."
):
E AssertionError: Regex pattern did not match.
E Regex: 'Feerate 10 too low for minimum feerate 10.'
E Input: 'RPC call failed: method: rbfpsbt, params: (\'4514e9f78ebd6746b5de6a3baeb661ff65002035ae8ec3cefbc99f3941f2c549\', False, 10), error: {\'code\': -32602, \'message\': "RBF error: \'Feerate 10 too low for minimum feerate 11.\'."}'
tests/test_rpc.py:1147: AssertionError
--------------------------- Captured stdout teardown ---------------------------
Test failed, leaving directory '/tmp/lianad-tests-lxeecnda/test_rbfpsbt_bump_fee_1' intact
=========================== short test summary info ============================
FAILED tests/test_rpc.py::test_rbfpsbt_bump_fee - AssertionError: Regex pattern did not match.
Regex: 'Feerate 10 too low for minimum feerate 10.'
Input: 'RPC call failed: method: rbfpsbt, params: (\'4514e9f78ebd6746b5de6a3baeb661ff65002035ae8ec3cefbc99f3941f2c549\', False, 10), error: {\'code\': -32602, \'message\': "RBF error: \'Feerate 10 too low for minimum feerate 11.\'."}'
=================== 1 failed, 15 passed in 70.18s (0:01:10) ====================
I open this issue to track the flaky test we have in the CI quite often:
https://github.com/wizardsardine/liana/pull/1265/checks?check_run_id=29705927967