@@ -18,7 +18,7 @@ package fr.acinq.eclair.blockchain.fee
1818
1919import fr .acinq .bitcoin .scalacompat .SatoshiLong
2020import fr .acinq .eclair .randomKey
21- import fr .acinq .eclair .transactions .Transactions .{UnsafeLegacyAnchorOutputsCommitmentFormat , ZeroFeeHtlcTxAnchorOutputsCommitmentFormat }
21+ import fr .acinq .eclair .transactions .Transactions .{PhoenixSimpleTaprootChannelCommitmentFormat , UnsafeLegacyAnchorOutputsCommitmentFormat , ZeroFeeHtlcTxAnchorOutputsCommitmentFormat , ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat }
2222import org .scalatest .funsuite .AnyFunSuite
2323
2424class OnChainFeeConfSpec extends AnyFunSuite {
@@ -29,56 +29,59 @@ class OnChainFeeConfSpec extends AnyFunSuite {
2929
3030 test(" should update fee when diff ratio exceeded" ) {
3131 val feeConf = OnChainFeeConf (defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0 , spendAnchorWithoutHtlcs = true , anchorWithoutHtlcsMaxFee = 10_000 .sat, closeOnOfflineMismatch = true , updateFeeMinDiffRatio = 0.1 , defaultFeerateTolerance, Map .empty)
32- assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1000 sat)))
33- assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (900 sat)))
34- assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1100 sat)))
35- assert(feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (899 sat)))
36- assert(feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1101 sat)))
32+ assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1000 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ))
33+ assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (900 sat), ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ))
34+ assert(! feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1100 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ))
35+ assert(feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (899 sat), ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ))
36+ assert(feeConf.shouldUpdateFee(FeeratePerKw (1000 sat), FeeratePerKw (1101 sat), ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ))
3737 }
3838
39- test(" get commitment feerate " ) {
39+ test(" should update fee to set to 1 sat/byte " ) {
4040 val feeConf = OnChainFeeConf (defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0 , spendAnchorWithoutHtlcs = true , anchorWithoutHtlcsMaxFee = 10_000 .sat, closeOnOfflineMismatch = true , updateFeeMinDiffRatio = 0.1 , defaultFeerateTolerance, Map .empty)
41- val feerates1 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = FeeratePerKw (5000 sat))
42- assert(feeConf.getCommitmentFeerate(feerates1, randomKey().publicKey, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (2500 sat))
43- val feerates2 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = FeeratePerKw (2000 sat))
44- assert(feeConf.getCommitmentFeerate(feerates2, randomKey().publicKey, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (2000 sat))
41+ // We always use 1 sat/byte for mobile wallet commitment formats, regardless of the current feerate.
42+ val feerates = FeeratesPerKw .single(FeeratePerKw (FeeratePerByte (20 sat)))
43+ assert(feeConf.getCommitmentFeerate(feerates, randomKey().publicKey, UnsafeLegacyAnchorOutputsCommitmentFormat ) == FeeratePerKw (FeeratePerByte (1 sat)))
44+ assert(feeConf.getCommitmentFeerate(feerates, randomKey().publicKey, PhoenixSimpleTaprootChannelCommitmentFormat ) == FeeratePerKw (FeeratePerByte (1 sat)))
45+ // If we're not already using 1 sat/byte, we update the feerate.
46+ assert(feeConf.shouldUpdateFee(FeeratePerKw (300 sat), FeeratePerKw (FeeratePerByte (1 sat)), UnsafeLegacyAnchorOutputsCommitmentFormat ))
47+ assert(feeConf.shouldUpdateFee(FeeratePerKw (300 sat), FeeratePerKw (FeeratePerByte (1 sat)), PhoenixSimpleTaprootChannelCommitmentFormat ))
4548 }
4649
47- test(" get commitment feerate (anchor outputs) " ) {
50+ test(" get commitment feerate" ) {
4851 val defaultNodeId = randomKey().publicKey
4952 val defaultMaxCommitFeerate = defaultFeerateTolerance.anchorOutputMaxCommitFeerate
5053 val overrideNodeId = randomKey().publicKey
5154 val overrideMaxCommitFeerate = defaultMaxCommitFeerate * 2
5255 val feeConf = OnChainFeeConf (defaultFeeTargets, defaultMaxClosingFeerate, safeUtxosThreshold = 0 , spendAnchorWithoutHtlcs = true , anchorWithoutHtlcsMaxFee = 10_000 .sat, closeOnOfflineMismatch = true , updateFeeMinDiffRatio = 0.1 , defaultFeerateTolerance, Map (overrideNodeId -> defaultFeerateTolerance.copy(anchorOutputMaxCommitFeerate = overrideMaxCommitFeerate)))
5356
5457 val feerates1 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = defaultMaxCommitFeerate / 2 , minimum = FeeratePerKw (250 sat))
55- assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
58+ assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
5659 assert(feeConf.getCommitmentFeerate(feerates1, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
5760
5861 val feerates2 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = defaultMaxCommitFeerate * 2 , minimum = FeeratePerKw (250 sat))
59- assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate)
62+ assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == defaultMaxCommitFeerate)
6063 assert(feeConf.getCommitmentFeerate(feerates2, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate)
61- assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == overrideMaxCommitFeerate)
64+ assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == overrideMaxCommitFeerate)
6265 assert(feeConf.getCommitmentFeerate(feerates2, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == overrideMaxCommitFeerate)
6366
6467 val feerates3 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = defaultMaxCommitFeerate / 2 , minimum = FeeratePerKw (250 sat))
65- assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
68+ assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
6669 assert(feeConf.getCommitmentFeerate(feerates3, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate / 2 )
6770
6871 val feerates4 = FeeratesPerKw .single(FeeratePerKw (10000 sat)).copy(fast = defaultMaxCommitFeerate * 1.5 , minimum = FeeratePerKw (250 sat))
69- assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate)
72+ assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == defaultMaxCommitFeerate)
7073 assert(feeConf.getCommitmentFeerate(feerates4, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == defaultMaxCommitFeerate)
7174
7275 val feerates5 = FeeratesPerKw .single(FeeratePerKw (25000 sat)).copy(minimum = FeeratePerKw (10000 sat))
73- assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
76+ assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
7477 assert(feeConf.getCommitmentFeerate(feerates5, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
75- assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
78+ assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
7679 assert(feeConf.getCommitmentFeerate(feerates5, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
7780
7881 val feerates6 = FeeratesPerKw .single(FeeratePerKw (25000 sat)).copy(minimum = FeeratePerKw (10000 sat))
79- assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
82+ assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
8083 assert(feeConf.getCommitmentFeerate(feerates6, defaultNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
81- assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, UnsafeLegacyAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
84+ assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, ZeroFeeHtlcTxSimpleTaprootChannelCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
8285 assert(feeConf.getCommitmentFeerate(feerates6, overrideNodeId, ZeroFeeHtlcTxAnchorOutputsCommitmentFormat ) == FeeratePerKw (10000 sat) * 1.25 )
8386 }
8487
0 commit comments