lnwallet+funding+lnd: add new config option for min accepted channel size

In this commit we add a new command line option (and a sane default) to
allow users to specify the *smallest* inbound channel that they'll
accept. Having a higher-ish limit lets users limit their channels, and
also avoid a series of very low value "spam" channels.

The new option is --minchansize, and expressed in satoshis. If we
receive an inbound channel request for a value smaller than this, then
we'll immediately reject it.
This commit is contained in:
Olaoluwa Osuntokun 2018-04-02 16:17:50 -07:00
parent de0a2ee49b
commit b422e4ec1e
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
4 changed files with 45 additions and 15 deletions

@ -195,8 +195,9 @@ type config struct {
TrickleDelay int `long:"trickledelay" description:"Time in milliseconds between each release of announcements to the network"` TrickleDelay int `long:"trickledelay" description:"Time in milliseconds between each release of announcements to the network"`
Alias string `long:"alias" description:"The node alias. Used as a moniker by peers and intelligence services"` Alias string `long:"alias" description:"The node alias. Used as a moniker by peers and intelligence services"`
Color string `long:"color" description:"The color of the node in hex format (i.e. '#3399FF'). Used to customize node appearance in intelligence services"` Color string `long:"color" description:"The color of the node in hex format (i.e. '#3399FF'). Used to customize node appearance in intelligence services"`
MinChanSize int64 `long:"minchansize" description:"The smallest channel size (in satoshis) that we should accept. Incoming channels smaller than this will be rejected"`
net torsvc.Net net torsvc.Net
} }
@ -264,6 +265,7 @@ func loadConfig() (*config, error) {
TrickleDelay: defaultTrickleDelay, TrickleDelay: defaultTrickleDelay,
Alias: defaultAlias, Alias: defaultAlias,
Color: defaultColor, Color: defaultColor,
MinChanSize: int64(minChanFundingSize),
} }
// Pre-parse the command line options to pick up an alternative config // Pre-parse the command line options to pick up an alternative config

@ -286,14 +286,14 @@ type fundingConfig struct {
// times. // times.
RequiredRemoteChanReserve func(btcutil.Amount) btcutil.Amount RequiredRemoteChanReserve func(btcutil.Amount) btcutil.Amount
// RequiredRemoteMaxValue is a function closure that, given the // RequiredRemoteMaxValue is a function closure that, given the channel
// channel capacity, returns the amount of MilliSatoshis that our // capacity, returns the amount of MilliSatoshis that our remote peer
// remote peer can have in total outstanding HTLCs with us. // can have in total outstanding HTLCs with us.
RequiredRemoteMaxValue func(btcutil.Amount) lnwire.MilliSatoshi RequiredRemoteMaxValue func(btcutil.Amount) lnwire.MilliSatoshi
// RequiredRemoteMaxHTLCs is a function closure that, given the // RequiredRemoteMaxHTLCs is a function closure that, given the channel
// channel capacity, returns the number of maximum HTLCs the remote // capacity, returns the number of maximum HTLCs the remote peer can
// peer can offer us. // offer us.
RequiredRemoteMaxHTLCs func(btcutil.Amount) uint16 RequiredRemoteMaxHTLCs func(btcutil.Amount) uint16
// WatchNewChannel is to be called once a new channel enters the final // WatchNewChannel is to be called once a new channel enters the final
@ -308,13 +308,19 @@ type fundingConfig struct {
// sub-systems. // sub-systems.
ReportShortChanID func(wire.OutPoint, lnwire.ShortChannelID) error ReportShortChanID func(wire.OutPoint, lnwire.ShortChannelID) error
// ZombieSweeperInterval is the periodic time interval in which the zombie // ZombieSweeperInterval is the periodic time interval in which the
// sweeper is run. // zombie sweeper is run.
ZombieSweeperInterval time.Duration ZombieSweeperInterval time.Duration
// ReservationTimeout is the length of idle time that must pass before a // ReservationTimeout is the length of idle time that must pass before
// reservation is considered a zombie. // a reservation is considered a zombie.
ReservationTimeout time.Duration ReservationTimeout time.Duration
// MinChanSize is the smallest channel size that we'll accept as an
// inbound channel. We have such a parameter, as otherwise, nodes could
// flood us with very small channels that would never really be usable
// due to fees.
MinChanSize btcutil.Amount
} }
// fundingManager acts as an orchestrator/bridge between the wallet's // fundingManager acts as an orchestrator/bridge between the wallet's
@ -331,8 +337,8 @@ type fundingManager struct {
started int32 started int32
stopped int32 stopped int32
// cfg is a copy of the configuration struct that the FundingManager was // cfg is a copy of the configuration struct that the FundingManager
// initialized with. // was initialized with.
cfg *fundingConfig cfg *fundingConfig
// chanIDKey is a cryptographically random key that's used to generate // chanIDKey is a cryptographically random key that's used to generate
@ -939,7 +945,18 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
if msg.FundingAmount > maxFundingAmount { if msg.FundingAmount > maxFundingAmount {
f.failFundingFlow( f.failFundingFlow(
fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID, fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID,
lnwire.ErrChanTooLarge) lnwire.ErrChanTooLarge,
)
return
}
// We'll, also ensure that the remote party isn't attempting to propose
// a channel that's below our current min channel size.
if amt < f.cfg.MinChanSize {
f.failFundingFlow(
fmsg.peerAddress.IdentityKey, fmsg.msg.PendingChannelID,
lnwallet.ErrChanTooSmall(amt, btcutil.Amount(f.cfg.MinChanSize)),
)
return return
} }

1
lnd.go

@ -470,6 +470,7 @@ func lndMain() error {
}, },
ZombieSweeperInterval: 1 * time.Minute, ZombieSweeperInterval: 1 * time.Minute,
ReservationTimeout: 10 * time.Minute, ReservationTimeout: 10 * time.Minute,
MinChanSize: btcutil.Amount(cfg.MinChanSize),
}) })
if err != nil { if err != nil {
return err return err

@ -106,3 +106,13 @@ func ErrMaxValueInFlightTooSmall(maxValInFlight,
maxValInFlight, minMaxValInFlight), maxValInFlight, minMaxValInFlight),
} }
} }
// ErrChanTooSmall returns an error indicating that an incoming channel request
// was too small. We'll reject any incoming channels if they're below our
// configured value for the min channel size we'll accept.
func ErrChanTooSmall(chanSize, minChanSize btcutil.Amount) ReservationError {
return ReservationError{
fmt.Errorf("chan size of %v is below min chan size of %v",
chanSize, minChanSize),
}
}