diff --git a/config.go b/config.go index b52bdd11..0efb7512 100644 --- a/config.go +++ b/config.go @@ -121,10 +121,11 @@ type bitcoindConfig struct { } type autoPilotConfig struct { - // TODO(roasbeef): add - Active bool `long:"active" description:"If the autopilot agent should be active or not."` - MaxChannels int `long:"maxchannels" description:"The maximum number of channels that should be created"` - Allocation float64 `long:"allocation" description:"The percentage of total funds that should be committed to automatic channel establishment"` + Active bool `long:"active" description:"If the autopilot agent should be active or not."` + MaxChannels int `long:"maxchannels" description:"The maximum number of channels that should be created"` + Allocation float64 `long:"allocation" description:"The percentage of total funds that should be committed to automatic channel establishment"` + MinChannelSize int64 `long:"minchansize" description:"The smallest channel that the autopilot agent should create"` + MaxChannelSize int64 `long:"maxchansize" description:"The larget channel taht the autopilot agent should create"` } type torConfig struct { @@ -249,8 +250,10 @@ func loadConfig() (*config, error) { MaxPendingChannels: defaultMaxPendingChannels, NoEncryptWallet: defaultNoEncryptWallet, Autopilot: &autoPilotConfig{ - MaxChannels: 5, - Allocation: 0.6, + MaxChannels: 5, + Allocation: 0.6, + MinChannelSize: int64(minChanFundingSize), + MaxChannelSize: int64(maxFundingAmount), }, TrickleDelay: defaultTrickleDelay, Alias: defaultAlias, @@ -333,6 +336,42 @@ func loadConfig() (*config, error) { cfg.BitcoindMode.Dir = cleanAndExpandPath(cfg.BitcoindMode.Dir) cfg.LitecoindMode.Dir = cleanAndExpandPath(cfg.LitecoindMode.Dir) + // Ensure that the user didn't attempt to specify negative values for + // any of the autopilot params. + if cfg.Autopilot.MaxChannelSize < 0 { + str := "%s: autopilot.maxchansize must be greater than zero" + err := fmt.Errorf(str) + fmt.Fprintln(os.Stderr, err) + return nil, err + } + if cfg.Autopilot.Allocation < 0 { + str := "%s: autopilot.allocation must be greater than zero" + err := fmt.Errorf(str) + fmt.Fprintln(os.Stderr, err) + return nil, err + } + if cfg.Autopilot.MinChannelSize < 0 { + str := "%s: autopilot.minchansize must be greater than zero" + err := fmt.Errorf(str) + fmt.Fprintln(os.Stderr, err) + return nil, err + } + if cfg.Autopilot.MaxChannelSize < 0 { + str := "%s: autopilot.maxchansize must be greater than zero" + err := fmt.Errorf(str) + fmt.Fprintln(os.Stderr, err) + return nil, err + } + + // Ensure that the specified values for the min and max channel size + // don't are within the bounds of the normal chan size constraints. + if cfg.Autopilot.MinChannelSize < int64(minChanFundingSize) { + cfg.Autopilot.MinChannelSize = int64(minChanFundingSize) + } + if cfg.Autopilot.MaxChannelSize > int64(maxFundingAmount) { + cfg.Autopilot.MaxChannelSize = int64(maxFundingAmount) + } + // Setup dial and DNS resolution functions depending on the specified // options. The default is to use the standard golang "net" package // functions. When Tor's proxy is specified, the dial function is set to diff --git a/fundingmanager.go b/fundingmanager.go index 607a91e7..87db5a95 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -60,6 +60,10 @@ const ( // for the funding transaction to be confirmed before forgetting about // the channel. 288 blocks is ~48 hrs maxWaitNumBlocksFundingConf = 288 + + // minChanFundingSize is the smallest channel that we'll allow to be + // created over the RPC interface. + minChanFundingSize = btcutil.Amount(20000) ) // reservationWithCtx encapsulates a pending channel reservation. This wrapper diff --git a/pilot.go b/pilot.go index dd0b6ab6..e29cc485 100644 --- a/pilot.go +++ b/pilot.go @@ -142,11 +142,9 @@ func initAutoPilot(svr *server, cfg *autoPilotConfig) (*autopilot.Agent, error) // First, we'll create the preferential attachment heuristic, // initialized with the passed auto pilot configuration parameters. - // - // TODO(roasbeef): switch here to dispatch specified heuristic - minChanSize := svr.cc.wallet.Cfg.DefaultConstraints.DustLimit * 5 prefAttachment := autopilot.NewConstrainedPrefAttachment( - minChanSize, maxFundingAmount, + btcutil.Amount(cfg.MinChannelSize), + btcutil.Amount(cfg.MaxChannelSize), uint16(cfg.MaxChannels), cfg.Allocation, ) diff --git a/rpcserver.go b/rpcserver.go index 282af192..d2a64a9f 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -701,17 +701,12 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest, "channel size is: %v", maxFundingAmount) } - const minChannelSize = btcutil.Amount(6000) - - // Restrict the size of the channel we'll actually open. Atm, we - // require the amount to be above 6k satoshis we currently hard-coded - // a 5k satoshi fee in several areas. As a result 6k sat is the min - // channel size that allows us to safely sit above the dust threshold - // after fees are applied - // TODO(roasbeef): remove after dynamic fees are in - if localFundingAmt < minChannelSize { + // Restrict the size of the channel we'll actually open. At a later + // level, we'll ensure that the output we create after accounting for + // fees that a dust output isn't created. + if localFundingAmt < minChanFundingSize { return fmt.Errorf("channel is too small, the minimum channel "+ - "size is: %v (6k sat)", minChannelSize) + "size is: %v SAT", int64(minChanFundingSize)) } var ( @@ -864,6 +859,14 @@ func (r *rpcServer) OpenChannelSync(ctx context.Context, "initial state must be below the local funding amount") } + // Restrict the size of the channel we'll actually open. At a later + // level, we'll ensure that the output we create after accounting for + // fees that a dust output isn't created. + if localFundingAmt < minChanFundingSize { + return nil, fmt.Errorf("channel is too small, the minimum channel "+ + "size is: %v SAT", int64(minChanFundingSize)) + } + // Based on the passed fee related parameters, we'll determine an // appropriate fee rate for the funding transaction. feeRate, err := determineFeePerVSize(