mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-19 18:10:42 +01:00
Reject unreasonable remote dust limit (#1694)
It makes no sense to use a dust limit that's much higher than what bitcoin mandates, so we should not allow our peer to use invalid values.
This commit is contained in:
parent
82e5b5968d
commit
3a94a80447
@ -64,6 +64,7 @@ eclair {
|
||||
channel-flags = 1 // announce channels
|
||||
|
||||
dust-limit-satoshis = 546
|
||||
max-remote-dust-limit-satoshis = 600
|
||||
max-htlc-value-in-flight-msat = 5000000000 // 50 mBTC
|
||||
htlc-minimum-msat = 1
|
||||
max-accepted-htlcs = 30
|
||||
|
@ -58,6 +58,7 @@ case class NodeParams(nodeKeyManager: NodeKeyManager,
|
||||
syncWhitelist: Set[PublicKey],
|
||||
pluginParams: Seq[PluginParams],
|
||||
dustLimit: Satoshi,
|
||||
maxRemoteDustLimit: Satoshi,
|
||||
onChainFeeConf: OnChainFeeConf,
|
||||
maxHtlcValueInFlightMsat: UInt64,
|
||||
maxAcceptedHtlcs: Int,
|
||||
@ -323,6 +324,7 @@ object NodeParams extends Logging {
|
||||
overrideFeatures = overrideFeatures,
|
||||
syncWhitelist = syncWhitelist,
|
||||
dustLimit = dustLimitSatoshis,
|
||||
maxRemoteDustLimit = Satoshi(config.getLong("max-remote-dust-limit-satoshis")),
|
||||
onChainFeeConf = OnChainFeeConf(
|
||||
feeTargets = feeTargets,
|
||||
feeEstimator = feeEstimator,
|
||||
|
@ -103,6 +103,8 @@ object Helpers {
|
||||
// BOLT #2: The receiving node MUST fail the channel if: it considers feerate_per_kw too small for timely processing.
|
||||
if (isFeeTooSmall(open.feeratePerKw)) return Left(FeerateTooSmall(open.temporaryChannelId, open.feeratePerKw))
|
||||
|
||||
if (open.dustLimitSatoshis > nodeParams.maxRemoteDustLimit) return Left(DustLimitTooLarge(open.temporaryChannelId, open.dustLimitSatoshis, nodeParams.maxRemoteDustLimit))
|
||||
|
||||
// BOLT #2: The receiving node MUST fail the channel if: dust_limit_satoshis is greater than channel_reserve_satoshis.
|
||||
if (open.dustLimitSatoshis > open.channelReserveSatoshis) return Left(DustLimitTooLarge(open.temporaryChannelId, open.dustLimitSatoshis, open.channelReserveSatoshis))
|
||||
|
||||
@ -140,6 +142,8 @@ object Helpers {
|
||||
if (accept.dustLimitSatoshis < Channel.MIN_DUSTLIMIT) return Left(DustLimitTooSmall(accept.temporaryChannelId, accept.dustLimitSatoshis, Channel.MIN_DUSTLIMIT))
|
||||
}
|
||||
|
||||
if (accept.dustLimitSatoshis > nodeParams.maxRemoteDustLimit) return Left(DustLimitTooLarge(open.temporaryChannelId, accept.dustLimitSatoshis, nodeParams.maxRemoteDustLimit))
|
||||
|
||||
// BOLT #2: The receiving node MUST fail the channel if: dust_limit_satoshis is greater than channel_reserve_satoshis.
|
||||
if (accept.dustLimitSatoshis > accept.channelReserveSatoshis) return Left(DustLimitTooLarge(accept.temporaryChannelId, accept.dustLimitSatoshis, accept.channelReserveSatoshis))
|
||||
|
||||
|
@ -167,6 +167,7 @@ object TestConstants {
|
||||
overrideFeatures = Map.empty,
|
||||
syncWhitelist = Set.empty,
|
||||
dustLimit = 1100 sat,
|
||||
maxRemoteDustLimit = 1500 sat,
|
||||
onChainFeeConf = OnChainFeeConf(
|
||||
feeTargets = FeeTargets(6, 2, 2, 6),
|
||||
feeEstimator = new TestFeeEstimator,
|
||||
@ -271,6 +272,7 @@ object TestConstants {
|
||||
overrideFeatures = Map.empty,
|
||||
syncWhitelist = Set.empty,
|
||||
dustLimit = 1000 sat,
|
||||
maxRemoteDustLimit = 1500 sat,
|
||||
onChainFeeConf = OnChainFeeConf(
|
||||
feeTargets = FeeTargets(6, 2, 2, 6),
|
||||
feeEstimator = new TestFeeEstimator,
|
||||
|
@ -52,6 +52,7 @@ class WaitForAcceptChannelStateSpec extends TestKitBaseClass with FixtureAnyFunS
|
||||
val aliceNodeParams = Alice.nodeParams
|
||||
.modify(_.chainHash).setToIf(test.tags.contains("mainnet"))(Block.LivenetGenesisBlock.hash)
|
||||
.modify(_.maxFundingSatoshis).setToIf(test.tags.contains("high-max-funding-size"))(Btc(100))
|
||||
.modify(_.maxRemoteDustLimit).setToIf(test.tags.contains("high-remote-dust-limit"))(15000 sat)
|
||||
val aliceParams = Alice.channelParams
|
||||
.modify(_.features).setToIf(test.tags.contains("wumbo"))(Features(Set(ActivatedFeature(Wumbo, Optional))))
|
||||
|
||||
@ -98,7 +99,7 @@ class WaitForAcceptChannelStateSpec extends TestKitBaseClass with FixtureAnyFunS
|
||||
awaitCond(alice.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv AcceptChannel (invalid dust limit)", Tag("mainnet")) { f =>
|
||||
test("recv AcceptChannel (dust limit too low)", Tag("mainnet")) { f =>
|
||||
import f._
|
||||
val accept = bob2alice.expectMsgType[AcceptChannel]
|
||||
// we don't want their dust limit to be below 546
|
||||
@ -109,6 +110,16 @@ class WaitForAcceptChannelStateSpec extends TestKitBaseClass with FixtureAnyFunS
|
||||
awaitCond(alice.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv AcceptChannel (dust limit too high)") { f =>
|
||||
import f._
|
||||
val accept = bob2alice.expectMsgType[AcceptChannel]
|
||||
val highDustLimitSatoshis = 2000.sat
|
||||
alice ! accept.copy(dustLimitSatoshis = highDustLimitSatoshis)
|
||||
val error = alice2bob.expectMsgType[Error]
|
||||
assert(error === Error(accept.temporaryChannelId, DustLimitTooLarge(accept.temporaryChannelId, highDustLimitSatoshis, Alice.nodeParams.maxRemoteDustLimit).getMessage))
|
||||
awaitCond(alice.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv AcceptChannel (to_self_delay too high)") { f =>
|
||||
import f._
|
||||
val accept = bob2alice.expectMsgType[AcceptChannel]
|
||||
@ -151,7 +162,7 @@ class WaitForAcceptChannelStateSpec extends TestKitBaseClass with FixtureAnyFunS
|
||||
awaitCond(alice.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv AcceptChannel (dust limit above our reserve)") { f =>
|
||||
test("recv AcceptChannel (dust limit above our reserve)", Tag("high-remote-dust-limit")) { f =>
|
||||
import f._
|
||||
val accept = bob2alice.expectMsgType[AcceptChannel]
|
||||
val open = alice.stateData.asInstanceOf[DATA_WAIT_FOR_ACCEPT_CHANNEL].lastSent
|
||||
|
@ -188,6 +188,16 @@ class WaitForOpenChannelStateSpec extends TestKitBaseClass with FixtureAnyFunSui
|
||||
awaitCond(bob.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv OpenChannel (dust limit too high)") { f =>
|
||||
import f._
|
||||
val open = alice2bob.expectMsgType[OpenChannel]
|
||||
val dustLimitTooHigh = 2000.sat
|
||||
bob ! open.copy(dustLimitSatoshis = dustLimitTooHigh)
|
||||
val error = bob2alice.expectMsgType[Error]
|
||||
assert(error === Error(open.temporaryChannelId, DustLimitTooLarge(open.temporaryChannelId, dustLimitTooHigh, Bob.nodeParams.maxRemoteDustLimit).getMessage))
|
||||
awaitCond(bob.stateName == CLOSED)
|
||||
}
|
||||
|
||||
test("recv OpenChannel (toLocal + toRemote below reserve)") { f =>
|
||||
import f._
|
||||
val open = alice2bob.expectMsgType[OpenChannel]
|
||||
|
Loading…
Reference in New Issue
Block a user