Merge pull request #4487 from Crypt-iQ/cc_pkg_0723

chainreg: new chainreg package
This commit is contained in:
Eugene 2020-10-30 06:07:26 -04:00 committed by GitHub
commit 225390ab5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 712 additions and 560 deletions

25
chainreg/chaincode.go Normal file

@ -0,0 +1,25 @@
package chainreg
// ChainCode is an enum-like structure for keeping track of the chains
// currently supported within lnd.
type ChainCode uint32
const (
// BitcoinChain is Bitcoin's chain.
BitcoinChain ChainCode = iota
// LitecoinChain is Litecoin's chain.
LitecoinChain
)
// String returns a string representation of the target ChainCode.
func (c ChainCode) String() string {
switch c {
case BitcoinChain:
return "bitcoin"
case LitecoinChain:
return "litecoin"
default:
return "kekcoin"
}
}

@ -1,4 +1,4 @@
package lnd package chainreg
import ( import (
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
@ -10,91 +10,93 @@ import (
litecoinWire "github.com/ltcsuite/ltcd/wire" litecoinWire "github.com/ltcsuite/ltcd/wire"
) )
// bitcoinNetParams couples the p2p parameters of a network with the // BitcoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network. // corresponding RPC port of a daemon running on the particular network.
type bitcoinNetParams struct { type BitcoinNetParams struct {
*bitcoinCfg.Params *bitcoinCfg.Params
rpcPort string RPCPort string
CoinType uint32 CoinType uint32
} }
// litecoinNetParams couples the p2p parameters of a network with the // LitecoinNetParams couples the p2p parameters of a network with the
// corresponding RPC port of a daemon running on the particular network. // corresponding RPC port of a daemon running on the particular network.
type litecoinNetParams struct { type LitecoinNetParams struct {
*litecoinCfg.Params *litecoinCfg.Params
rpcPort string RPCPort string
CoinType uint32 CoinType uint32
} }
// bitcoinTestNetParams contains parameters specific to the 3rd version of the // BitcoinTestNetParams contains parameters specific to the 3rd version of the
// test network. // test network.
var bitcoinTestNetParams = bitcoinNetParams{ var BitcoinTestNetParams = BitcoinNetParams{
Params: &bitcoinCfg.TestNet3Params, Params: &bitcoinCfg.TestNet3Params,
rpcPort: "18334", RPCPort: "18334",
CoinType: keychain.CoinTypeTestnet, CoinType: keychain.CoinTypeTestnet,
} }
// bitcoinMainNetParams contains parameters specific to the current Bitcoin // BitcoinMainNetParams contains parameters specific to the current Bitcoin
// mainnet. // mainnet.
var bitcoinMainNetParams = bitcoinNetParams{ var BitcoinMainNetParams = BitcoinNetParams{
Params: &bitcoinCfg.MainNetParams, Params: &bitcoinCfg.MainNetParams,
rpcPort: "8334", RPCPort: "8334",
CoinType: keychain.CoinTypeBitcoin, CoinType: keychain.CoinTypeBitcoin,
} }
// bitcoinSimNetParams contains parameters specific to the simulation test // BitcoinSimNetParams contains parameters specific to the simulation test
// network. // network.
var bitcoinSimNetParams = bitcoinNetParams{ var BitcoinSimNetParams = BitcoinNetParams{
Params: &bitcoinCfg.SimNetParams, Params: &bitcoinCfg.SimNetParams,
rpcPort: "18556", RPCPort: "18556",
CoinType: keychain.CoinTypeTestnet, CoinType: keychain.CoinTypeTestnet,
} }
// litecoinSimNetParams contains parameters specific to the simulation test // LitecoinSimNetParams contains parameters specific to the simulation test
// network. // network.
var litecoinSimNetParams = litecoinNetParams{ var LitecoinSimNetParams = LitecoinNetParams{
Params: &litecoinCfg.SimNetParams,
rpcPort: "18556",
CoinType: keychain.CoinTypeTestnet,
}
// litecoinTestNetParams contains parameters specific to the 4th version of the
// test network.
var litecoinTestNetParams = litecoinNetParams{
Params: &litecoinCfg.TestNet4Params, Params: &litecoinCfg.TestNet4Params,
rpcPort: "19334", RPCPort: "18556",
CoinType: keychain.CoinTypeTestnet, CoinType: keychain.CoinTypeTestnet,
} }
// litecoinMainNetParams contains the parameters specific to the current // LitecoinTestNetParams contains parameters specific to the 4th version of the
// test network.
var LitecoinTestNetParams = LitecoinNetParams{
Params: &litecoinCfg.TestNet4Params,
RPCPort: "19334",
CoinType: keychain.CoinTypeTestnet,
}
// LitecoinMainNetParams contains the parameters specific to the current
// Litecoin mainnet. // Litecoin mainnet.
var litecoinMainNetParams = litecoinNetParams{ var LitecoinMainNetParams = LitecoinNetParams{
Params: &litecoinCfg.MainNetParams, Params: &litecoinCfg.MainNetParams,
rpcPort: "9334", RPCPort: "9334",
CoinType: keychain.CoinTypeLitecoin, CoinType: keychain.CoinTypeLitecoin,
} }
// litecoinRegTestNetParams contains parameters specific to a local litecoin // LitecoinRegTestNetParams contains parameters specific to a local litecoin
// regtest network. // regtest network.
var litecoinRegTestNetParams = litecoinNetParams{ var LitecoinRegTestNetParams = LitecoinNetParams{
Params: &litecoinCfg.RegressionNetParams, Params: &litecoinCfg.RegressionNetParams,
rpcPort: "18334", RPCPort: "18334",
CoinType: keychain.CoinTypeTestnet, CoinType: keychain.CoinTypeTestnet,
} }
// bitcoinRegTestNetParams contains parameters specific to a local bitcoin // BitcoinRegTestNetParams contains parameters specific to a local bitcoin
// regtest network. // regtest network.
var bitcoinRegTestNetParams = bitcoinNetParams{ var BitcoinRegTestNetParams = BitcoinNetParams{
Params: &bitcoinCfg.RegressionNetParams, Params: &bitcoinCfg.RegressionNetParams,
rpcPort: "18334", RPCPort: "18334",
CoinType: keychain.CoinTypeTestnet, CoinType: keychain.CoinTypeTestnet,
} }
// applyLitecoinParams applies the relevant chain configuration parameters that // ApplyLitecoinParams applies the relevant chain configuration parameters that
// differ for litecoin to the chain parameters typed for btcsuite derivation. // differ for litecoin to the chain parameters typed for btcsuite derivation.
// This function is used in place of using something like interface{} to // This function is used in place of using something like interface{} to
// abstract over _which_ chain (or fork) the parameters are for. // abstract over _which_ chain (or fork) the parameters are for.
func applyLitecoinParams(params *bitcoinNetParams, litecoinParams *litecoinNetParams) { func ApplyLitecoinParams(params *BitcoinNetParams,
litecoinParams *LitecoinNetParams) {
params.Name = litecoinParams.Name params.Name = litecoinParams.Name
params.Net = bitcoinWire.BitcoinNet(litecoinParams.Net) params.Net = bitcoinWire.BitcoinNet(litecoinParams.Net)
params.DefaultPort = litecoinParams.DefaultPort params.DefaultPort = litecoinParams.DefaultPort
@ -127,13 +129,13 @@ func applyLitecoinParams(params *bitcoinNetParams, litecoinParams *litecoinNetPa
} }
params.Checkpoints = checkPoints params.Checkpoints = checkPoints
params.rpcPort = litecoinParams.rpcPort params.RPCPort = litecoinParams.RPCPort
params.CoinType = litecoinParams.CoinType params.CoinType = litecoinParams.CoinType
} }
// isTestnet tests if the given params correspond to a testnet // IsTestnet tests if the givern params correspond to a testnet
// parameter configuration. // parameter configuration.
func isTestnet(params *bitcoinNetParams) bool { func IsTestnet(params *BitcoinNetParams) bool {
switch params.Params.Net { switch params.Params.Net {
case bitcoinWire.TestNet3, bitcoinWire.BitcoinNet(litecoinWire.TestNet4): case bitcoinWire.TestNet3, bitcoinWire.BitcoinNet(litecoinWire.TestNet4):
return true return true

@ -1,4 +1,4 @@
package lnd package chainreg
import ( import (
"encoding/hex" "encoding/hex"
@ -7,7 +7,6 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"os" "os"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -18,9 +17,7 @@ import (
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
"github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wallet"
"github.com/btcsuite/btcwallet/walletdb"
"github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino"
"github.com/lightninglabs/neutrino/headerfs"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/chainntnfs/bitcoindnotify" "github.com/lightningnetwork/lnd/chainntnfs/bitcoindnotify"
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify" "github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
@ -37,8 +34,76 @@ import (
"github.com/lightningnetwork/lnd/routing/chainview" "github.com/lightningnetwork/lnd/routing/chainview"
) )
// Config houses necessary fields that a chainControl instance needs to
// function.
type Config struct {
// Bitcoin defines settings for the Bitcoin chain.
Bitcoin *lncfg.Chain
// Litecoin defines settings for the Litecoin chain.
Litecoin *lncfg.Chain
// PrimaryChain is a function that returns our primary chain via its
// ChainCode.
PrimaryChain func() ChainCode
// HeightHintCacheQueryDisable is a boolean that disables height hint
// queries if true.
HeightHintCacheQueryDisable bool
// NeutrinoMode defines settings for connecting to a neutrino light-client.
NeutrinoMode *lncfg.Neutrino
// BitcoindMode defines settings for connecting to a bitcoind node.
BitcoindMode *lncfg.Bitcoind
// LitecoindMode defines settings for connecting to a litecoind node.
LitecoindMode *lncfg.Bitcoind
// BtcdMode defines settings for connecting to a btcd node.
BtcdMode *lncfg.Btcd
// LtcdMode defines settings for connecting to an ltcd node.
LtcdMode *lncfg.Btcd
// LocalChanDB is a pointer to the local backing channel database.
LocalChanDB *channeldb.DB
// RemoteChanDB is a pointer to the remote backing channel database.
RemoteChanDB *channeldb.DB
// PrivateWalletPw is the private wallet password to the underlying
// btcwallet instance.
PrivateWalletPw []byte
// PublicWalletPw is the public wallet password to the underlying btcwallet
// instance.
PublicWalletPw []byte
// Birthday specifies the time the wallet was initially created.
Birthday time.Time
// RecoveryWindow specifies the address look-ahead for which to scan when
// restoring a wallet.
RecoveryWindow uint32
// Wallet is a pointer to the backing wallet instance.
Wallet *wallet.Wallet
// NeutrinoCS is a pointer to a neutrino ChainService. Must be non-nil if
// using neutrino.
NeutrinoCS *neutrino.ChainService
// ActiveNetParams details the current chain we are on.
ActiveNetParams BitcoinNetParams
// FeeURL defines the URL for fee estimation we will use. This field is
// optional.
FeeURL string
}
const ( const (
// defaultBitcoinMinHTLCMSat is the default smallest value htlc this // DefaultBitcoinMinHTLCInMSat is the default smallest value htlc this
// node will accept. This value is proposed in the channel open sequence // node will accept. This value is proposed in the channel open sequence
// and cannot be changed during the life of the channel. It is 1 msat by // and cannot be changed during the life of the channel. It is 1 msat by
// default to allow maximum flexibility in deciding what size payments // default to allow maximum flexibility in deciding what size payments
@ -47,13 +112,13 @@ const (
// All forwarded payments are subjected to the min htlc constraint of // All forwarded payments are subjected to the min htlc constraint of
// the routing policy of the outgoing channel. This implicitly controls // the routing policy of the outgoing channel. This implicitly controls
// the minimum htlc value on the incoming channel too. // the minimum htlc value on the incoming channel too.
defaultBitcoinMinHTLCInMSat = lnwire.MilliSatoshi(1) DefaultBitcoinMinHTLCInMSat = lnwire.MilliSatoshi(1)
// defaultBitcoinMinHTLCOutMSat is the default minimum htlc value that // DefaultBitcoinMinHTLCOutMSat is the default minimum htlc value that
// we require for sending out htlcs. Our channel peer may have a lower // we require for sending out htlcs. Our channel peer may have a lower
// min htlc channel parameter, but we - by default - don't forward // min htlc channel parameter, but we - by default - don't forward
// anything under the value defined here. // anything under the value defined here.
defaultBitcoinMinHTLCOutMSat = lnwire.MilliSatoshi(1000) DefaultBitcoinMinHTLCOutMSat = lnwire.MilliSatoshi(1000)
// DefaultBitcoinBaseFeeMSat is the default forwarding base fee. // DefaultBitcoinBaseFeeMSat is the default forwarding base fee.
DefaultBitcoinBaseFeeMSat = lnwire.MilliSatoshi(1000) DefaultBitcoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
@ -65,157 +130,143 @@ const (
// delta. // delta.
DefaultBitcoinTimeLockDelta = 40 DefaultBitcoinTimeLockDelta = 40
defaultLitecoinMinHTLCInMSat = lnwire.MilliSatoshi(1) DefaultLitecoinMinHTLCInMSat = lnwire.MilliSatoshi(1)
defaultLitecoinMinHTLCOutMSat = lnwire.MilliSatoshi(1000) DefaultLitecoinMinHTLCOutMSat = lnwire.MilliSatoshi(1000)
defaultLitecoinBaseFeeMSat = lnwire.MilliSatoshi(1000) DefaultLitecoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
defaultLitecoinFeeRate = lnwire.MilliSatoshi(1) DefaultLitecoinFeeRate = lnwire.MilliSatoshi(1)
defaultLitecoinTimeLockDelta = 576 DefaultLitecoinTimeLockDelta = 576
defaultLitecoinDustLimit = btcutil.Amount(54600) DefaultLitecoinDustLimit = btcutil.Amount(54600)
// defaultBitcoinStaticFeePerKW is the fee rate of 50 sat/vbyte // DefaultBitcoinStaticFeePerKW is the fee rate of 50 sat/vbyte
// expressed in sat/kw. // expressed in sat/kw.
defaultBitcoinStaticFeePerKW = chainfee.SatPerKWeight(12500) DefaultBitcoinStaticFeePerKW = chainfee.SatPerKWeight(12500)
// defaultBitcoinStaticMinRelayFeeRate is the min relay fee used for // DefaultBitcoinStaticMinRelayFeeRate is the min relay fee used for
// static estimators. // static estimators.
defaultBitcoinStaticMinRelayFeeRate = chainfee.FeePerKwFloor DefaultBitcoinStaticMinRelayFeeRate = chainfee.FeePerKwFloor
// defaultLitecoinStaticFeePerKW is the fee rate of 200 sat/vbyte // DefaultLitecoinStaticFeePerKW is the fee rate of 200 sat/vbyte
// expressed in sat/kw. // expressed in sat/kw.
defaultLitecoinStaticFeePerKW = chainfee.SatPerKWeight(50000) DefaultLitecoinStaticFeePerKW = chainfee.SatPerKWeight(50000)
// btcToLtcConversionRate is a fixed ratio used in order to scale up // BtcToLtcConversionRate is a fixed ratio used in order to scale up
// payments when running on the Litecoin chain. // payments when running on the Litecoin chain.
btcToLtcConversionRate = 60 BtcToLtcConversionRate = 60
) )
// defaultBtcChannelConstraints is the default set of channel constraints that are // DefaultBtcChannelConstraints is the default set of channel constraints that are
// meant to be used when initially funding a Bitcoin channel. // meant to be used when initially funding a Bitcoin channel.
// //
// TODO(halseth): make configurable at startup? // TODO(halseth): make configurable at startup?
var defaultBtcChannelConstraints = channeldb.ChannelConstraints{ var DefaultBtcChannelConstraints = channeldb.ChannelConstraints{
DustLimit: lnwallet.DefaultDustLimit(), DustLimit: lnwallet.DefaultDustLimit(),
MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
} }
// defaultLtcChannelConstraints is the default set of channel constraints that are // DefaultLtcChannelConstraints is the default set of channel constraints that are
// meant to be used when initially funding a Litecoin channel. // meant to be used when initially funding a Litecoin channel.
var defaultLtcChannelConstraints = channeldb.ChannelConstraints{ var DefaultLtcChannelConstraints = channeldb.ChannelConstraints{
DustLimit: defaultLitecoinDustLimit, DustLimit: DefaultLitecoinDustLimit,
MaxAcceptedHtlcs: input.MaxHTLCNumber / 2, MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
} }
// chainCode is an enum-like structure for keeping track of the chains // ChainControl couples the three primary interfaces lnd utilizes for a
// currently supported within lnd. // particular chain together. A single ChainControl instance will exist for all
type chainCode uint32
const (
// bitcoinChain is Bitcoin's testnet chain.
bitcoinChain chainCode = iota
// litecoinChain is Litecoin's testnet chain.
litecoinChain
)
// String returns a string representation of the target chainCode.
func (c chainCode) String() string {
switch c {
case bitcoinChain:
return "bitcoin"
case litecoinChain:
return "litecoin"
default:
return "kekcoin"
}
}
// chainControl couples the three primary interfaces lnd utilizes for a
// particular chain together. A single chainControl instance will exist for all
// the chains lnd is currently active on. // the chains lnd is currently active on.
type chainControl struct { type ChainControl struct {
chainIO lnwallet.BlockChainIO // ChainIO represents an abstraction over a source that can query the blockchain.
ChainIO lnwallet.BlockChainIO
feeEstimator chainfee.Estimator // FeeEstimator is used to estimate an optimal fee for transactions important to us.
FeeEstimator chainfee.Estimator
signer input.Signer // Signer is used to provide signatures over things like transactions.
Signer input.Signer
keyRing keychain.SecretKeyRing // KeyRing represents a set of keys that we have the private keys to.
KeyRing keychain.SecretKeyRing
wc lnwallet.WalletController // Wc is an abstraction over some basic wallet commands. This base set of commands
// will be provided to the Wallet *LightningWallet raw pointer below.
Wc lnwallet.WalletController
msgSigner lnwallet.MessageSigner // MsgSigner is used to sign arbitrary messages.
MsgSigner lnwallet.MessageSigner
chainNotifier chainntnfs.ChainNotifier // ChainNotifier is used to receive blockchain events that we are interested in.
ChainNotifier chainntnfs.ChainNotifier
chainView chainview.FilteredChainView // ChainView is used in the router for maintaining an up-to-date graph.
ChainView chainview.FilteredChainView
wallet *lnwallet.LightningWallet // Wallet is our LightningWallet that also contains the abstract Wc above. This wallet
// handles all of the lightning operations.
Wallet *lnwallet.LightningWallet
routingPolicy htlcswitch.ForwardingPolicy // RoutingPolicy is the routing policy we have decided to use.
RoutingPolicy htlcswitch.ForwardingPolicy
minHtlcIn lnwire.MilliSatoshi // MinHtlcIn is the minimum HTLC we will accept.
MinHtlcIn lnwire.MilliSatoshi
} }
// newChainControlFromConfig attempts to create a chainControl instance // NewChainControl attempts to create a ChainControl instance according
// according to the parameters in the passed lnd configuration. Currently three // to the parameters in the passed configuration. Currently three
// branches of chainControl instances exist: one backed by a running btcd // branches of ChainControl instances exist: one backed by a running btcd
// full-node, another backed by a running bitcoind full-node, and the other // full-node, another backed by a running bitcoind full-node, and the other
// backed by a running neutrino light client instance. When running with a // backed by a running neutrino light client instance. When running with a
// neutrino light client instance, `neutrinoCS` must be non-nil. // neutrino light client instance, `neutrinoCS` must be non-nil.
func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB, func NewChainControl(cfg *Config) (*ChainControl, error) {
privateWalletPw, publicWalletPw []byte, birthday time.Time,
recoveryWindow uint32, wallet *wallet.Wallet,
neutrinoCS *neutrino.ChainService) (*chainControl, error) {
// Set the RPC config from the "home" chain. Multi-chain isn't yet // Set the RPC config from the "home" chain. Multi-chain isn't yet
// active, so we'll restrict usage to a particular chain for now. // active, so we'll restrict usage to a particular chain for now.
homeChainConfig := cfg.Bitcoin homeChainConfig := cfg.Bitcoin
if cfg.registeredChains.PrimaryChain() == litecoinChain { if cfg.PrimaryChain() == LitecoinChain {
homeChainConfig = cfg.Litecoin homeChainConfig = cfg.Litecoin
} }
ltndLog.Infof("Primary chain is set to: %v", log.Infof("Primary chain is set to: %v",
cfg.registeredChains.PrimaryChain()) cfg.PrimaryChain())
cc := &chainControl{} cc := &ChainControl{}
switch cfg.registeredChains.PrimaryChain() { switch cfg.PrimaryChain() {
case bitcoinChain: case BitcoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{ cc.RoutingPolicy = htlcswitch.ForwardingPolicy{
MinHTLCOut: cfg.Bitcoin.MinHTLCOut, MinHTLCOut: cfg.Bitcoin.MinHTLCOut,
BaseFee: cfg.Bitcoin.BaseFee, BaseFee: cfg.Bitcoin.BaseFee,
FeeRate: cfg.Bitcoin.FeeRate, FeeRate: cfg.Bitcoin.FeeRate,
TimeLockDelta: cfg.Bitcoin.TimeLockDelta, TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
} }
cc.minHtlcIn = cfg.Bitcoin.MinHTLCIn cc.MinHtlcIn = cfg.Bitcoin.MinHTLCIn
cc.feeEstimator = chainfee.NewStaticEstimator( cc.FeeEstimator = chainfee.NewStaticEstimator(
defaultBitcoinStaticFeePerKW, DefaultBitcoinStaticFeePerKW,
defaultBitcoinStaticMinRelayFeeRate, DefaultBitcoinStaticMinRelayFeeRate,
) )
case litecoinChain: case LitecoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{ cc.RoutingPolicy = htlcswitch.ForwardingPolicy{
MinHTLCOut: cfg.Litecoin.MinHTLCOut, MinHTLCOut: cfg.Litecoin.MinHTLCOut,
BaseFee: cfg.Litecoin.BaseFee, BaseFee: cfg.Litecoin.BaseFee,
FeeRate: cfg.Litecoin.FeeRate, FeeRate: cfg.Litecoin.FeeRate,
TimeLockDelta: cfg.Litecoin.TimeLockDelta, TimeLockDelta: cfg.Litecoin.TimeLockDelta,
} }
cc.minHtlcIn = cfg.Litecoin.MinHTLCIn cc.MinHtlcIn = cfg.Litecoin.MinHTLCIn
cc.feeEstimator = chainfee.NewStaticEstimator( cc.FeeEstimator = chainfee.NewStaticEstimator(
defaultLitecoinStaticFeePerKW, 0, DefaultLitecoinStaticFeePerKW, 0,
) )
default: default:
return nil, fmt.Errorf("default routing policy for chain %v is "+ return nil, fmt.Errorf("default routing policy for chain %v is "+
"unknown", cfg.registeredChains.PrimaryChain()) "unknown", cfg.PrimaryChain())
} }
walletConfig := &btcwallet.Config{ walletConfig := &btcwallet.Config{
PrivatePass: privateWalletPw, PrivatePass: cfg.PrivateWalletPw,
PublicPass: publicWalletPw, PublicPass: cfg.PublicWalletPw,
Birthday: birthday, Birthday: cfg.Birthday,
RecoveryWindow: recoveryWindow, RecoveryWindow: cfg.RecoveryWindow,
DataDir: homeChainConfig.ChainDir, DataDir: homeChainConfig.ChainDir,
NetParams: cfg.ActiveNetParams.Params, NetParams: cfg.ActiveNetParams.Params,
CoinType: cfg.ActiveNetParams.CoinType, CoinType: cfg.ActiveNetParams.CoinType,
Wallet: wallet, Wallet: cfg.Wallet,
} }
var err error var err error
@ -224,11 +275,13 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
QueryDisable: cfg.HeightHintCacheQueryDisable, QueryDisable: cfg.HeightHintCacheQueryDisable,
} }
if cfg.HeightHintCacheQueryDisable { if cfg.HeightHintCacheQueryDisable {
ltndLog.Infof("Height Hint Cache Queries disabled") log.Infof("Height Hint Cache Queries disabled")
} }
// Initialize the height hint cache within the chain directory. // Initialize the height hint cache within the chain directory.
hintCache, err := chainntnfs.NewHeightHintCache(heightHintCacheConfig, localDB) hintCache, err := chainntnfs.NewHeightHintCache(
heightHintCacheConfig, cfg.LocalChanDB,
)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialize height hint "+ return nil, fmt.Errorf("unable to initialize height hint "+
"cache: %v", err) "cache: %v", err)
@ -242,10 +295,10 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// We'll create ChainNotifier and FilteredChainView instances, // We'll create ChainNotifier and FilteredChainView instances,
// along with the wallet's ChainSource, which are all backed by // along with the wallet's ChainSource, which are all backed by
// the neutrino light client. // the neutrino light client.
cc.chainNotifier = neutrinonotify.New( cc.ChainNotifier = neutrinonotify.New(
neutrinoCS, hintCache, hintCache, cfg.NeutrinoCS, hintCache, hintCache,
) )
cc.chainView, err = chainview.NewCfFilteredChainView(neutrinoCS) cc.ChainView, err = chainview.NewCfFilteredChainView(cfg.NeutrinoCS)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -262,7 +315,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
} }
walletConfig.ChainSource = chain.NewNeutrinoClient( walletConfig.ChainSource = chain.NewNeutrinoClient(
cfg.ActiveNetParams.Params, neutrinoCS, cfg.ActiveNetParams.Params, cfg.NeutrinoCS,
) )
case "bitcoind", "litecoind": case "bitcoind", "litecoind":
@ -286,7 +339,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// btcd, which picks a different port so that btcwallet // btcd, which picks a different port so that btcwallet
// can use the same RPC port as bitcoind. We convert // can use the same RPC port as bitcoind. We convert
// this back to the btcwallet/bitcoind port. // this back to the btcwallet/bitcoind port.
rpcPort, err := strconv.Atoi(cfg.ActiveNetParams.rpcPort) rpcPort, err := strconv.Atoi(cfg.ActiveNetParams.RPCPort)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -328,10 +381,10 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
"%v", err) "%v", err)
} }
cc.chainNotifier = bitcoindnotify.New( cc.ChainNotifier = bitcoindnotify.New(
bitcoindConn, cfg.ActiveNetParams.Params, hintCache, hintCache, bitcoindConn, cfg.ActiveNetParams.Params, hintCache, hintCache,
) )
cc.chainView = chainview.NewBitcoindFilteredChainView(bitcoindConn) cc.ChainView = chainview.NewBitcoindFilteredChainView(bitcoindConn)
walletConfig.ChainSource = bitcoindConn.NewBitcoindClient() walletConfig.ChainSource = bitcoindConn.NewBitcoindClient()
// If we're not in regtest mode, then we'll attempt to use a // If we're not in regtest mode, then we'll attempt to use a
@ -346,7 +399,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
HTTPPostMode: true, HTTPPostMode: true,
} }
if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest { if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest {
ltndLog.Infof("Initializing bitcoind backed fee estimator in "+ log.Infof("Initializing bitcoind backed fee estimator in "+
"%s mode", bitcoindMode.EstimateMode) "%s mode", bitcoindMode.EstimateMode)
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
@ -354,7 +407,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// use live fee estimates, rather than a statically // use live fee estimates, rather than a statically
// coded value. // coded value.
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000) fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
cc.feeEstimator, err = chainfee.NewBitcoindEstimator( cc.FeeEstimator, err = chainfee.NewBitcoindEstimator(
*rpcConfig, bitcoindMode.EstimateMode, *rpcConfig, bitcoindMode.EstimateMode,
fallBackFeeRate.FeePerKWeight(), fallBackFeeRate.FeePerKWeight(),
) )
@ -362,7 +415,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
return nil, err return nil, err
} }
} else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest { } else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest {
ltndLog.Infof("Initializing litecoind backed fee estimator in "+ log.Infof("Initializing litecoind backed fee estimator in "+
"%s mode", bitcoindMode.EstimateMode) "%s mode", bitcoindMode.EstimateMode)
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
@ -370,7 +423,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// use live fee estimates, rather than a statically // use live fee estimates, rather than a statically
// coded value. // coded value.
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000) fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
cc.feeEstimator, err = chainfee.NewBitcoindEstimator( cc.FeeEstimator, err = chainfee.NewBitcoindEstimator(
*rpcConfig, bitcoindMode.EstimateMode, *rpcConfig, bitcoindMode.EstimateMode,
fallBackFeeRate.FeePerKWeight(), fallBackFeeRate.FeePerKWeight(),
) )
@ -421,7 +474,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
btcdHost = btcdMode.RPCHost btcdHost = btcdMode.RPCHost
} else { } else {
btcdHost = fmt.Sprintf("%v:%v", btcdMode.RPCHost, btcdHost = fmt.Sprintf("%v:%v", btcdMode.RPCHost,
cfg.ActiveNetParams.rpcPort) cfg.ActiveNetParams.RPCPort)
} }
btcdUser := btcdMode.RPCUser btcdUser := btcdMode.RPCUser
@ -436,7 +489,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
DisableConnectOnNew: true, DisableConnectOnNew: true,
DisableAutoReconnect: false, DisableAutoReconnect: false,
} }
cc.chainNotifier, err = btcdnotify.New( cc.ChainNotifier, err = btcdnotify.New(
rpcConfig, cfg.ActiveNetParams.Params, hintCache, hintCache, rpcConfig, cfg.ActiveNetParams.Params, hintCache, hintCache,
) )
if err != nil { if err != nil {
@ -445,9 +498,9 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// Finally, we'll create an instance of the default chain view to be // Finally, we'll create an instance of the default chain view to be
// used within the routing layer. // used within the routing layer.
cc.chainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig) cc.ChainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig)
if err != nil { if err != nil {
srvrLog.Errorf("unable to create chain view: %v", err) log.Errorf("unable to create chain view: %v", err)
return nil, err return nil, err
} }
@ -466,14 +519,14 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
if !cfg.Bitcoin.SimNet && !cfg.Litecoin.SimNet && if !cfg.Bitcoin.SimNet && !cfg.Litecoin.SimNet &&
!cfg.Bitcoin.RegTest && !cfg.Litecoin.RegTest { !cfg.Bitcoin.RegTest && !cfg.Litecoin.RegTest {
ltndLog.Infof("Initializing btcd backed fee estimator") log.Info("Initializing btcd backed fee estimator")
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
// if we're using btcd as a backend, then we can use // if we're using btcd as a backend, then we can use
// live fee estimates, rather than a statically coded // live fee estimates, rather than a statically coded
// value. // value.
fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000) fallBackFeeRate := chainfee.SatPerKVByte(25 * 1000)
cc.feeEstimator, err = chainfee.NewBtcdEstimator( cc.FeeEstimator, err = chainfee.NewBtcdEstimator(
*rpcConfig, fallBackFeeRate.FeePerKWeight(), *rpcConfig, fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
@ -491,10 +544,10 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
// manual or automated test cases. // manual or automated test cases.
cacheFees := !cfg.Bitcoin.RegTest cacheFees := !cfg.Bitcoin.RegTest
ltndLog.Infof("Using external fee estimator %v: cached=%v", log.Infof("Using external fee estimator %v: cached=%v",
cfg.FeeURL, cacheFees) cfg.FeeURL, cacheFees)
cc.feeEstimator = chainfee.NewWebAPIEstimator( cc.FeeEstimator = chainfee.NewWebAPIEstimator(
chainfee.SparseConfFeeSource{ chainfee.SparseConfFeeSource{
URL: cfg.FeeURL, URL: cfg.FeeURL,
}, },
@ -503,7 +556,7 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
} }
// Start fee estimator. // Start fee estimator.
if err := cc.feeEstimator.Start(); err != nil { if err := cc.FeeEstimator.Start(); err != nil {
return nil, err return nil, err
} }
@ -513,32 +566,32 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
return nil, err return nil, err
} }
cc.msgSigner = wc cc.MsgSigner = wc
cc.signer = wc cc.Signer = wc
cc.chainIO = wc cc.ChainIO = wc
cc.wc = wc cc.Wc = wc
// Select the default channel constraints for the primary chain. // Select the default channel constraints for the primary chain.
channelConstraints := defaultBtcChannelConstraints channelConstraints := DefaultBtcChannelConstraints
if cfg.registeredChains.PrimaryChain() == litecoinChain { if cfg.PrimaryChain() == LitecoinChain {
channelConstraints = defaultLtcChannelConstraints channelConstraints = DefaultLtcChannelConstraints
} }
keyRing := keychain.NewBtcWalletKeyRing( keyRing := keychain.NewBtcWalletKeyRing(
wc.InternalWallet(), cfg.ActiveNetParams.CoinType, wc.InternalWallet(), cfg.ActiveNetParams.CoinType,
) )
cc.keyRing = keyRing cc.KeyRing = keyRing
// Create, and start the lnwallet, which handles the core payment // Create, and start the lnwallet, which handles the core payment
// channel logic, and exposes control via proxy state machines. // channel logic, and exposes control via proxy state machines.
walletCfg := lnwallet.Config{ walletCfg := lnwallet.Config{
Database: remoteDB, Database: cfg.RemoteChanDB,
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
WalletController: wc, WalletController: wc,
Signer: cc.signer, Signer: cc.Signer,
FeeEstimator: cc.feeEstimator, FeeEstimator: cc.FeeEstimator,
SecretKeyRing: keyRing, SecretKeyRing: keyRing,
ChainIO: cc.chainIO, ChainIO: cc.ChainIO,
DefaultConstraints: channelConstraints, DefaultConstraints: channelConstraints,
NetParams: *cfg.ActiveNetParams.Params, NetParams: *cfg.ActiveNetParams.Params,
} }
@ -552,42 +605,42 @@ func newChainControlFromConfig(cfg *Config, localDB, remoteDB *channeldb.DB,
return nil, err return nil, err
} }
ltndLog.Info("LightningWallet opened") log.Info("LightningWallet opened")
cc.wallet = lnWallet cc.Wallet = lnWallet
return cc, nil return cc, nil
} }
var ( var (
// bitcoinTestnetGenesis is the genesis hash of Bitcoin's testnet // BitcoinTestnetGenesis is the genesis hash of Bitcoin's testnet
// chain. // chain.
bitcoinTestnetGenesis = chainhash.Hash([chainhash.HashSize]byte{ BitcoinTestnetGenesis = chainhash.Hash([chainhash.HashSize]byte{
0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71,
0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae,
0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad,
0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00,
}) })
// bitcoinMainnetGenesis is the genesis hash of Bitcoin's main chain. // BitcoinMainnetGenesis is the genesis hash of Bitcoin's main chain.
bitcoinMainnetGenesis = chainhash.Hash([chainhash.HashSize]byte{ BitcoinMainnetGenesis = chainhash.Hash([chainhash.HashSize]byte{
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
}) })
// litecoinTestnetGenesis is the genesis hash of Litecoin's testnet4 // LitecoinTestnetGenesis is the genesis hash of Litecoin's testnet4
// chain. // chain.
litecoinTestnetGenesis = chainhash.Hash([chainhash.HashSize]byte{ LitecoinTestnetGenesis = chainhash.Hash([chainhash.HashSize]byte{
0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6, 0xe6, 0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6, 0xe6,
0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f, 0x57, 0x88, 0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f, 0x57, 0x88,
0x0d, 0x1a, 0x21, 0x56, 0x9e, 0x13, 0xee, 0xfd, 0x0d, 0x1a, 0x21, 0x56, 0x9e, 0x13, 0xee, 0xfd,
0xd9, 0x51, 0x28, 0x4b, 0x5a, 0x62, 0x66, 0x49, 0xd9, 0x51, 0x28, 0x4b, 0x5a, 0x62, 0x66, 0x49,
}) })
// litecoinMainnetGenesis is the genesis hash of Litecoin's main chain. // LitecoinMainnetGenesis is the genesis hash of Litecoin's main chain.
litecoinMainnetGenesis = chainhash.Hash([chainhash.HashSize]byte{ LitecoinMainnetGenesis = chainhash.Hash([chainhash.HashSize]byte{
0xe2, 0xbf, 0x04, 0x7e, 0x7e, 0x5a, 0x19, 0x1a, 0xe2, 0xbf, 0x04, 0x7e, 0x7e, 0x5a, 0x19, 0x1a,
0xa4, 0xef, 0x34, 0xd3, 0x14, 0x97, 0x9d, 0xc9, 0xa4, 0xef, 0x34, 0xd3, 0x14, 0x97, 0x9d, 0xc9,
0x98, 0x6e, 0x0f, 0x19, 0x25, 0x1e, 0xda, 0xba, 0x98, 0x6e, 0x0f, 0x19, 0x25, 0x1e, 0xda, 0xba,
@ -595,16 +648,16 @@ var (
}) })
// chainMap is a simple index that maps a chain's genesis hash to the // chainMap is a simple index that maps a chain's genesis hash to the
// chainCode enum for that chain. // ChainCode enum for that chain.
chainMap = map[chainhash.Hash]chainCode{ chainMap = map[chainhash.Hash]ChainCode{
bitcoinTestnetGenesis: bitcoinChain, BitcoinTestnetGenesis: BitcoinChain,
litecoinTestnetGenesis: litecoinChain, LitecoinTestnetGenesis: LitecoinChain,
bitcoinMainnetGenesis: bitcoinChain, BitcoinMainnetGenesis: BitcoinChain,
litecoinMainnetGenesis: litecoinChain, LitecoinMainnetGenesis: LitecoinChain,
} }
// chainDNSSeeds is a map of a chain's hash to the set of DNS seeds // ChainDNSSeeds is a map of a chain's hash to the set of DNS seeds
// that will be use to bootstrap peers upon first startup. // that will be use to bootstrap peers upon first startup.
// //
// The first item in the array is the primary host we'll use to attempt // The first item in the array is the primary host we'll use to attempt
@ -616,8 +669,8 @@ var (
// //
// TODO(roasbeef): extend and collapse these and chainparams.go into // TODO(roasbeef): extend and collapse these and chainparams.go into
// struct like chaincfg.Params // struct like chaincfg.Params
chainDNSSeeds = map[chainhash.Hash][][2]string{ ChainDNSSeeds = map[chainhash.Hash][][2]string{
bitcoinMainnetGenesis: { BitcoinMainnetGenesis: {
{ {
"nodes.lightning.directory", "nodes.lightning.directory",
"soa.nodes.lightning.directory", "soa.nodes.lightning.directory",
@ -627,14 +680,14 @@ var (
}, },
}, },
bitcoinTestnetGenesis: { BitcoinTestnetGenesis: {
{ {
"test.nodes.lightning.directory", "test.nodes.lightning.directory",
"soa.nodes.lightning.directory", "soa.nodes.lightning.directory",
}, },
}, },
litecoinMainnetGenesis: { LitecoinMainnetGenesis: {
{ {
"ltc.nodes.lightning.directory", "ltc.nodes.lightning.directory",
"soa.nodes.lightning.directory", "soa.nodes.lightning.directory",
@ -643,44 +696,48 @@ var (
} }
) )
// chainRegistry keeps track of the current chains // ChainRegistry keeps track of the current chains
type chainRegistry struct { type ChainRegistry struct {
sync.RWMutex sync.RWMutex
activeChains map[chainCode]*chainControl activeChains map[ChainCode]*ChainControl
netParams map[chainCode]*bitcoinNetParams netParams map[ChainCode]*BitcoinNetParams
primaryChain chainCode primaryChain ChainCode
} }
// newChainRegistry creates a new chainRegistry. // NewChainRegistry creates a new ChainRegistry.
func newChainRegistry() *chainRegistry { func NewChainRegistry() *ChainRegistry {
return &chainRegistry{ return &ChainRegistry{
activeChains: make(map[chainCode]*chainControl), activeChains: make(map[ChainCode]*ChainControl),
netParams: make(map[chainCode]*bitcoinNetParams), netParams: make(map[ChainCode]*BitcoinNetParams),
} }
} }
// RegisterChain assigns an active chainControl instance to a target chain // RegisterChain assigns an active ChainControl instance to a target chain
// identified by its chainCode. // identified by its ChainCode.
func (c *chainRegistry) RegisterChain(newChain chainCode, cc *chainControl) { func (c *ChainRegistry) RegisterChain(newChain ChainCode,
cc *ChainControl) {
c.Lock() c.Lock()
c.activeChains[newChain] = cc c.activeChains[newChain] = cc
c.Unlock() c.Unlock()
} }
// LookupChain attempts to lookup an active chainControl instance for the // LookupChain attempts to lookup an active ChainControl instance for the
// target chain. // target chain.
func (c *chainRegistry) LookupChain(targetChain chainCode) (*chainControl, bool) { func (c *ChainRegistry) LookupChain(targetChain ChainCode) (
*ChainControl, bool) {
c.RLock() c.RLock()
cc, ok := c.activeChains[targetChain] cc, ok := c.activeChains[targetChain]
c.RUnlock() c.RUnlock()
return cc, ok return cc, ok
} }
// LookupChainByHash attempts to look up an active chainControl which // LookupChainByHash attempts to look up an active ChainControl which
// corresponds to the passed genesis hash. // corresponds to the passed genesis hash.
func (c *chainRegistry) LookupChainByHash(chainHash chainhash.Hash) (*chainControl, bool) { func (c *ChainRegistry) LookupChainByHash(chainHash chainhash.Hash) (*ChainControl, bool) {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
@ -694,7 +751,7 @@ func (c *chainRegistry) LookupChainByHash(chainHash chainhash.Hash) (*chainContr
} }
// RegisterPrimaryChain sets a target chain as the "home chain" for lnd. // RegisterPrimaryChain sets a target chain as the "home chain" for lnd.
func (c *chainRegistry) RegisterPrimaryChain(cc chainCode) { func (c *ChainRegistry) RegisterPrimaryChain(cc ChainCode) {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
@ -704,7 +761,7 @@ func (c *chainRegistry) RegisterPrimaryChain(cc chainCode) {
// PrimaryChain returns the primary chain for this running lnd instance. The // PrimaryChain returns the primary chain for this running lnd instance. The
// primary chain is considered the "home base" while the other registered // primary chain is considered the "home base" while the other registered
// chains are treated as secondary chains. // chains are treated as secondary chains.
func (c *chainRegistry) PrimaryChain() chainCode { func (c *ChainRegistry) PrimaryChain() ChainCode {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
@ -712,11 +769,11 @@ func (c *chainRegistry) PrimaryChain() chainCode {
} }
// ActiveChains returns a slice containing the active chains. // ActiveChains returns a slice containing the active chains.
func (c *chainRegistry) ActiveChains() []chainCode { func (c *ChainRegistry) ActiveChains() []ChainCode {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
chains := make([]chainCode, 0, len(c.activeChains)) chains := make([]ChainCode, 0, len(c.activeChains))
for activeChain := range c.activeChains { for activeChain := range c.activeChains {
chains = append(chains, activeChain) chains = append(chains, activeChain)
} }
@ -725,132 +782,9 @@ func (c *chainRegistry) ActiveChains() []chainCode {
} }
// NumActiveChains returns the total number of active chains. // NumActiveChains returns the total number of active chains.
func (c *chainRegistry) NumActiveChains() uint32 { func (c *ChainRegistry) NumActiveChains() uint32 {
c.RLock() c.RLock()
defer c.RUnlock() defer c.RUnlock()
return uint32(len(c.activeChains)) return uint32(len(c.activeChains))
} }
// initNeutrinoBackend inits a new instance of the neutrino light client
// backend given a target chain directory to store the chain state.
func initNeutrinoBackend(cfg *Config, chainDir string) (*neutrino.ChainService,
func(), error) {
// First we'll open the database file for neutrino, creating the
// database if needed. We append the normalized network name here to
// match the behavior of btcwallet.
dbPath := filepath.Join(
chainDir,
normalizeNetwork(cfg.ActiveNetParams.Name),
)
// Ensure that the neutrino db path exists.
if err := os.MkdirAll(dbPath, 0700); err != nil {
return nil, nil, err
}
dbName := filepath.Join(dbPath, "neutrino.db")
db, err := walletdb.Create("bdb", dbName, !cfg.SyncFreelist)
if err != nil {
return nil, nil, fmt.Errorf("unable to create neutrino "+
"database: %v", err)
}
headerStateAssertion, err := parseHeaderStateAssertion(
cfg.NeutrinoMode.AssertFilterHeader,
)
if err != nil {
db.Close()
return nil, nil, err
}
// With the database open, we can now create an instance of the
// neutrino light client. We pass in relevant configuration parameters
// required.
config := neutrino.Config{
DataDir: dbPath,
Database: db,
ChainParams: *cfg.ActiveNetParams.Params,
AddPeers: cfg.NeutrinoMode.AddPeers,
ConnectPeers: cfg.NeutrinoMode.ConnectPeers,
Dialer: func(addr net.Addr) (net.Conn, error) {
return cfg.net.Dial(
addr.Network(), addr.String(),
cfg.ConnectionTimeout,
)
},
NameResolver: func(host string) ([]net.IP, error) {
addrs, err := cfg.net.LookupHost(host)
if err != nil {
return nil, err
}
ips := make([]net.IP, 0, len(addrs))
for _, strIP := range addrs {
ip := net.ParseIP(strIP)
if ip == nil {
continue
}
ips = append(ips, ip)
}
return ips, nil
},
AssertFilterHeader: headerStateAssertion,
}
neutrino.MaxPeers = 8
neutrino.BanDuration = time.Hour * 48
neutrino.UserAgentName = cfg.NeutrinoMode.UserAgentName
neutrino.UserAgentVersion = cfg.NeutrinoMode.UserAgentVersion
neutrinoCS, err := neutrino.NewChainService(config)
if err != nil {
db.Close()
return nil, nil, fmt.Errorf("unable to create neutrino light "+
"client: %v", err)
}
if err := neutrinoCS.Start(); err != nil {
db.Close()
return nil, nil, err
}
cleanUp := func() {
neutrinoCS.Stop()
db.Close()
}
return neutrinoCS, cleanUp, nil
}
// parseHeaderStateAssertion parses the user-specified neutrino header state
// into a headerfs.FilterHeader.
func parseHeaderStateAssertion(state string) (*headerfs.FilterHeader, error) {
if len(state) == 0 {
return nil, nil
}
split := strings.Split(state, ":")
if len(split) != 2 {
return nil, fmt.Errorf("header state assertion %v in "+
"unexpected format, expected format height:hash", state)
}
height, err := strconv.ParseUint(split[0], 10, 32)
if err != nil {
return nil, fmt.Errorf("invalid filter header height: %v", err)
}
hash, err := chainhash.NewHashFromStr(split[1])
if err != nil {
return nil, fmt.Errorf("invalid filter header hash: %v", err)
}
return &headerfs.FilterHeader{
Height: uint32(height),
FilterHash: *hash,
}, nil
}

24
chainreg/log.go Normal file

@ -0,0 +1,24 @@
package chainreg
import (
"github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/build"
)
// log is a logger that is initialized with the btclog.Disabled logger.
var log btclog.Logger
// The default amount of logging is none.
func init() {
UseLogger(build.NewSubLogger("CHRE", nil))
}
// DisableLog disables all logging output.
func DisableLog() {
UseLogger(btclog.Disabled)
}
// UseLogger uses a specified Logger to output package logging info.
func UseLogger(logger btclog.Logger) {
log = logger
}

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/route"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -27,7 +27,7 @@ var buildRouteCommand = cli.Command{
Name: "final_cltv_delta", Name: "final_cltv_delta",
Usage: "number of blocks the last hop has to reveal " + Usage: "number of blocks the last hop has to reveal " +
"the preimage", "the preimage",
Value: lnd.DefaultBitcoinTimeLockDelta, Value: chainreg.DefaultBitcoinTimeLockDelta,
}, },
cli.StringFlag{ cli.StringFlag{
Name: "hops", Name: "hops",

@ -23,6 +23,7 @@ import (
"github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino"
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/discovery" "github.com/lightningnetwork/lnd/discovery"
@ -311,7 +312,7 @@ type Config struct {
// registeredChains keeps track of all chains that have been registered // registeredChains keeps track of all chains that have been registered
// with the daemon. // with the daemon.
registeredChains *chainRegistry registeredChains *chainreg.ChainRegistry
// networkDir is the path to the directory of the currently active // networkDir is the path to the directory of the currently active
// network. This path will hold the files related to each different // network. This path will hold the files related to each different
@ -319,7 +320,7 @@ type Config struct {
networkDir string networkDir string
// ActiveNetParams contains parameters of the target chain. // ActiveNetParams contains parameters of the target chain.
ActiveNetParams bitcoinNetParams ActiveNetParams chainreg.BitcoinNetParams
} }
// DefaultConfig returns all default values for the Config struct. // DefaultConfig returns all default values for the Config struct.
@ -338,11 +339,11 @@ func DefaultConfig() Config {
MaxLogFileSize: defaultMaxLogFileSize, MaxLogFileSize: defaultMaxLogFileSize,
AcceptorTimeout: defaultAcceptorTimeout, AcceptorTimeout: defaultAcceptorTimeout,
Bitcoin: &lncfg.Chain{ Bitcoin: &lncfg.Chain{
MinHTLCIn: defaultBitcoinMinHTLCInMSat, MinHTLCIn: chainreg.DefaultBitcoinMinHTLCInMSat,
MinHTLCOut: defaultBitcoinMinHTLCOutMSat, MinHTLCOut: chainreg.DefaultBitcoinMinHTLCOutMSat,
BaseFee: DefaultBitcoinBaseFeeMSat, BaseFee: chainreg.DefaultBitcoinBaseFeeMSat,
FeeRate: DefaultBitcoinFeeRate, FeeRate: chainreg.DefaultBitcoinFeeRate,
TimeLockDelta: DefaultBitcoinTimeLockDelta, TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta,
Node: "btcd", Node: "btcd",
}, },
BtcdMode: &lncfg.Btcd{ BtcdMode: &lncfg.Btcd{
@ -356,11 +357,11 @@ func DefaultConfig() Config {
EstimateMode: defaultBitcoindEstimateMode, EstimateMode: defaultBitcoindEstimateMode,
}, },
Litecoin: &lncfg.Chain{ Litecoin: &lncfg.Chain{
MinHTLCIn: defaultLitecoinMinHTLCInMSat, MinHTLCIn: chainreg.DefaultLitecoinMinHTLCInMSat,
MinHTLCOut: defaultLitecoinMinHTLCOutMSat, MinHTLCOut: chainreg.DefaultLitecoinMinHTLCOutMSat,
BaseFee: defaultLitecoinBaseFeeMSat, BaseFee: chainreg.DefaultLitecoinBaseFeeMSat,
FeeRate: defaultLitecoinFeeRate, FeeRate: chainreg.DefaultLitecoinFeeRate,
TimeLockDelta: defaultLitecoinTimeLockDelta, TimeLockDelta: chainreg.DefaultLitecoinTimeLockDelta,
Node: "ltcd", Node: "ltcd",
}, },
LtcdMode: &lncfg.Btcd{ LtcdMode: &lncfg.Btcd{
@ -451,8 +452,8 @@ func DefaultConfig() Config {
MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation, MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation,
LogWriter: build.NewRotatingLogWriter(), LogWriter: build.NewRotatingLogWriter(),
DB: lncfg.DefaultDB(), DB: lncfg.DefaultDB(),
registeredChains: newChainRegistry(), registeredChains: chainreg.NewChainRegistry(),
ActiveNetParams: bitcoinTestNetParams, ActiveNetParams: chainreg.BitcoinTestNetParams,
} }
} }
@ -829,22 +830,22 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// number of network flags passed; assign active network params // number of network flags passed; assign active network params
// while we're at it. // while we're at it.
numNets := 0 numNets := 0
var ltcParams litecoinNetParams var ltcParams chainreg.LitecoinNetParams
if cfg.Litecoin.MainNet { if cfg.Litecoin.MainNet {
numNets++ numNets++
ltcParams = litecoinMainNetParams ltcParams = chainreg.LitecoinMainNetParams
} }
if cfg.Litecoin.TestNet3 { if cfg.Litecoin.TestNet3 {
numNets++ numNets++
ltcParams = litecoinTestNetParams ltcParams = chainreg.LitecoinTestNetParams
} }
if cfg.Litecoin.RegTest { if cfg.Litecoin.RegTest {
numNets++ numNets++
ltcParams = litecoinRegTestNetParams ltcParams = chainreg.LitecoinRegTestNetParams
} }
if cfg.Litecoin.SimNet { if cfg.Litecoin.SimNet {
numNets++ numNets++
ltcParams = litecoinSimNetParams ltcParams = chainreg.LitecoinSimNetParams
} }
if numNets > 1 { if numNets > 1 {
@ -868,12 +869,12 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// throughout the codebase we required chaincfg.Params. So as a // throughout the codebase we required chaincfg.Params. So as a
// temporary hack, we'll mutate the default net params for // temporary hack, we'll mutate the default net params for
// bitcoin with the litecoin specific information. // bitcoin with the litecoin specific information.
applyLitecoinParams(&cfg.ActiveNetParams, &ltcParams) chainreg.ApplyLitecoinParams(&cfg.ActiveNetParams, &ltcParams)
switch cfg.Litecoin.Node { switch cfg.Litecoin.Node {
case "ltcd": case "ltcd":
err := parseRPCParams(cfg.Litecoin, cfg.LtcdMode, err := parseRPCParams(cfg.Litecoin, cfg.LtcdMode,
litecoinChain, funcName, cfg.ActiveNetParams) chainreg.LitecoinChain, funcName, cfg.ActiveNetParams)
if err != nil { if err != nil {
err := fmt.Errorf("unable to load RPC "+ err := fmt.Errorf("unable to load RPC "+
"credentials for ltcd: %v", err) "credentials for ltcd: %v", err)
@ -885,7 +886,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
"support simnet", funcName) "support simnet", funcName)
} }
err := parseRPCParams(cfg.Litecoin, cfg.LitecoindMode, err := parseRPCParams(cfg.Litecoin, cfg.LitecoindMode,
litecoinChain, funcName, cfg.ActiveNetParams) chainreg.LitecoinChain, funcName, cfg.ActiveNetParams)
if err != nil { if err != nil {
err := fmt.Errorf("unable to load RPC "+ err := fmt.Errorf("unable to load RPC "+
"credentials for litecoind: %v", err) "credentials for litecoind: %v", err)
@ -899,11 +900,11 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
cfg.Litecoin.ChainDir = filepath.Join(cfg.DataDir, cfg.Litecoin.ChainDir = filepath.Join(cfg.DataDir,
defaultChainSubDirname, defaultChainSubDirname,
litecoinChain.String()) chainreg.LitecoinChain.String())
// Finally we'll register the litecoin chain as our current // Finally we'll register the litecoin chain as our current
// primary chain. // primary chain.
cfg.registeredChains.RegisterPrimaryChain(litecoinChain) cfg.registeredChains.RegisterPrimaryChain(chainreg.LitecoinChain)
MaxFundingAmount = maxLtcFundingAmount MaxFundingAmount = maxLtcFundingAmount
case cfg.Bitcoin.Active: case cfg.Bitcoin.Active:
@ -913,19 +914,19 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
numNets := 0 numNets := 0
if cfg.Bitcoin.MainNet { if cfg.Bitcoin.MainNet {
numNets++ numNets++
cfg.ActiveNetParams = bitcoinMainNetParams cfg.ActiveNetParams = chainreg.BitcoinMainNetParams
} }
if cfg.Bitcoin.TestNet3 { if cfg.Bitcoin.TestNet3 {
numNets++ numNets++
cfg.ActiveNetParams = bitcoinTestNetParams cfg.ActiveNetParams = chainreg.BitcoinTestNetParams
} }
if cfg.Bitcoin.RegTest { if cfg.Bitcoin.RegTest {
numNets++ numNets++
cfg.ActiveNetParams = bitcoinRegTestNetParams cfg.ActiveNetParams = chainreg.BitcoinRegTestNetParams
} }
if cfg.Bitcoin.SimNet { if cfg.Bitcoin.SimNet {
numNets++ numNets++
cfg.ActiveNetParams = bitcoinSimNetParams cfg.ActiveNetParams = chainreg.BitcoinSimNetParams
} }
if numNets > 1 { if numNets > 1 {
str := "%s: The mainnet, testnet, regtest, and " + str := "%s: The mainnet, testnet, regtest, and " +
@ -953,7 +954,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
switch cfg.Bitcoin.Node { switch cfg.Bitcoin.Node {
case "btcd": case "btcd":
err := parseRPCParams( err := parseRPCParams(
cfg.Bitcoin, cfg.BtcdMode, bitcoinChain, funcName, cfg.Bitcoin, cfg.BtcdMode, chainreg.BitcoinChain, funcName,
cfg.ActiveNetParams, cfg.ActiveNetParams,
) )
if err != nil { if err != nil {
@ -968,7 +969,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
} }
err := parseRPCParams( err := parseRPCParams(
cfg.Bitcoin, cfg.BitcoindMode, bitcoinChain, funcName, cfg.Bitcoin, cfg.BitcoindMode, chainreg.BitcoinChain, funcName,
cfg.ActiveNetParams, cfg.ActiveNetParams,
) )
if err != nil { if err != nil {
@ -987,11 +988,11 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
cfg.Bitcoin.ChainDir = filepath.Join(cfg.DataDir, cfg.Bitcoin.ChainDir = filepath.Join(cfg.DataDir,
defaultChainSubDirname, defaultChainSubDirname,
bitcoinChain.String()) chainreg.BitcoinChain.String())
// Finally we'll register the bitcoin chain as our current // Finally we'll register the bitcoin chain as our current
// primary chain. // primary chain.
cfg.registeredChains.RegisterPrimaryChain(bitcoinChain) cfg.registeredChains.RegisterPrimaryChain(chainreg.BitcoinChain)
} }
// Ensure that the user didn't attempt to specify negative values for // Ensure that the user didn't attempt to specify negative values for
@ -1047,7 +1048,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
cfg.networkDir = filepath.Join( cfg.networkDir = filepath.Join(
cfg.DataDir, defaultChainSubDirname, cfg.DataDir, defaultChainSubDirname,
cfg.registeredChains.PrimaryChain().String(), cfg.registeredChains.PrimaryChain().String(),
normalizeNetwork(cfg.ActiveNetParams.Name), lncfg.NormalizeNetwork(cfg.ActiveNetParams.Name),
) )
// If a custom macaroon directory wasn't specified and the data // If a custom macaroon directory wasn't specified and the data
@ -1081,7 +1082,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
// per network in the same fashion as the data directory. // per network in the same fashion as the data directory.
cfg.LogDir = filepath.Join(cfg.LogDir, cfg.LogDir = filepath.Join(cfg.LogDir,
cfg.registeredChains.PrimaryChain().String(), cfg.registeredChains.PrimaryChain().String(),
normalizeNetwork(cfg.ActiveNetParams.Name)) lncfg.NormalizeNetwork(cfg.ActiveNetParams.Name))
// A log writer must be passed in, otherwise we can't function and would // A log writer must be passed in, otherwise we can't function and would
// run into a panic later on. // run into a panic later on.
@ -1279,11 +1280,11 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
func (c *Config) localDatabaseDir() string { func (c *Config) localDatabaseDir() string {
return filepath.Join(c.DataDir, return filepath.Join(c.DataDir,
defaultGraphSubDirname, defaultGraphSubDirname,
normalizeNetwork(c.ActiveNetParams.Name)) lncfg.NormalizeNetwork(c.ActiveNetParams.Name))
} }
func (c *Config) networkName() string { func (c *Config) networkName() string {
return normalizeNetwork(c.ActiveNetParams.Name) return lncfg.NormalizeNetwork(c.ActiveNetParams.Name)
} }
// CleanAndExpandPath expands environment variables and leading ~ in the // CleanAndExpandPath expands environment variables and leading ~ in the
@ -1312,8 +1313,9 @@ func CleanAndExpandPath(path string) string {
return filepath.Clean(os.ExpandEnv(path)) return filepath.Clean(os.ExpandEnv(path))
} }
func parseRPCParams(cConfig *lncfg.Chain, nodeConfig interface{}, net chainCode, func parseRPCParams(cConfig *lncfg.Chain, nodeConfig interface{},
funcName string, netParams bitcoinNetParams) error { // nolint:unparam net chainreg.ChainCode, funcName string,
netParams chainreg.BitcoinNetParams) error { // nolint:unparam
// First, we'll check our node config to make sure the RPC parameters // First, we'll check our node config to make sure the RPC parameters
// were set correctly. We'll also determine the path to the conf file // were set correctly. We'll also determine the path to the conf file
@ -1329,11 +1331,11 @@ func parseRPCParams(cConfig *lncfg.Chain, nodeConfig interface{}, net chainCode,
// Get the daemon name for displaying proper errors. // Get the daemon name for displaying proper errors.
switch net { switch net {
case bitcoinChain: case chainreg.BitcoinChain:
daemonName = "btcd" daemonName = "btcd"
confDir = conf.Dir confDir = conf.Dir
confFile = "btcd" confFile = "btcd"
case litecoinChain: case chainreg.LitecoinChain:
daemonName = "ltcd" daemonName = "ltcd"
confDir = conf.Dir confDir = conf.Dir
confFile = "ltcd" confFile = "ltcd"
@ -1376,11 +1378,11 @@ func parseRPCParams(cConfig *lncfg.Chain, nodeConfig interface{}, net chainCode,
// Get the daemon name for displaying proper errors. // Get the daemon name for displaying proper errors.
switch net { switch net {
case bitcoinChain: case chainreg.BitcoinChain:
daemonName = "bitcoind" daemonName = "bitcoind"
confDir = conf.Dir confDir = conf.Dir
confFile = "bitcoin" confFile = "bitcoin"
case litecoinChain: case chainreg.LitecoinChain:
daemonName = "litecoind" daemonName = "litecoind"
confDir = conf.Dir confDir = conf.Dir
confFile = "litecoin" confFile = "litecoin"
@ -1617,13 +1619,3 @@ func checkEstimateMode(estimateMode string) error {
return fmt.Errorf("estimatemode must be one of the following: %v", return fmt.Errorf("estimatemode must be one of the following: %v",
bitcoindEstimateModes[:]) bitcoindEstimateModes[:])
} }
// normalizeNetwork returns the common name of a network type used to create
// file paths. This allows differently versioned networks to use the same path.
func normalizeNetwork(network string) string {
if strings.HasPrefix(network, "testnet") {
return "testnet"
}
return network
}

@ -15,6 +15,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanacceptor" "github.com/lightningnetwork/lnd/chanacceptor"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channeldb/kvdb" "github.com/lightningnetwork/lnd/channeldb/kvdb"
@ -75,7 +76,7 @@ const (
// maxLtcFundingAmount is a soft-limit of the maximum channel size // maxLtcFundingAmount is a soft-limit of the maximum channel size
// currently accepted on the Litecoin chain within the Lightning // currently accepted on the Litecoin chain within the Lightning
// Protocol. // Protocol.
maxLtcFundingAmount = MaxBtcFundingAmount * btcToLtcConversionRate maxLtcFundingAmount = MaxBtcFundingAmount * chainreg.BtcToLtcConversionRate
) )
var ( var (
@ -357,7 +358,7 @@ type fundingConfig struct {
// RegisteredChains keeps track of all chains that have been registered // RegisteredChains keeps track of all chains that have been registered
// with the daemon. // with the daemon.
RegisteredChains *chainRegistry RegisteredChains *chainreg.ChainRegistry
} }
// fundingManager acts as an orchestrator/bridge between the wallet's // fundingManager acts as an orchestrator/bridge between the wallet's
@ -3060,10 +3061,10 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// We'll determine our dust limit depending on which chain is active. // We'll determine our dust limit depending on which chain is active.
var ourDustLimit btcutil.Amount var ourDustLimit btcutil.Amount
switch f.cfg.RegisteredChains.PrimaryChain() { switch f.cfg.RegisteredChains.PrimaryChain() {
case bitcoinChain: case chainreg.BitcoinChain:
ourDustLimit = lnwallet.DefaultDustLimit() ourDustLimit = lnwallet.DefaultDustLimit()
case litecoinChain: case chainreg.LitecoinChain:
ourDustLimit = defaultLitecoinDustLimit ourDustLimit = chainreg.DefaultLitecoinDustLimit
} }
fndgLog.Infof("Initiating fundingRequest(local_amt=%v "+ fndgLog.Infof("Initiating fundingRequest(local_amt=%v "+

@ -21,9 +21,8 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanacceptor" "github.com/lightningnetwork/lnd/chanacceptor"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channelnotifier" "github.com/lightningnetwork/lnd/channelnotifier"
@ -31,6 +30,7 @@ import (
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnpeer"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest/mock" "github.com/lightningnetwork/lnd/lntest/mock"
@ -104,7 +104,7 @@ var (
_, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10) _, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10)
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10) _, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
fundingNetParams = bitcoinTestNetParams fundingNetParams = chainreg.BitcoinTestNetParams
) )
type mockNotifier struct { type mockNotifier struct {
@ -271,7 +271,7 @@ func createTestWallet(cdb *channeldb.DB, netParams *chaincfg.Params,
ChainIO: bio, ChainIO: bio,
FeeEstimator: estimator, FeeEstimator: estimator,
NetParams: *netParams, NetParams: *netParams,
DefaultConstraints: defaultBtcChannelConstraints, DefaultConstraints: chainreg.DefaultBtcChannelConstraints,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -437,7 +437,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
NotifyOpenChannelEvent: evt.NotifyOpenChannelEvent, NotifyOpenChannelEvent: evt.NotifyOpenChannelEvent,
OpenChannelPredicate: chainedAcceptor, OpenChannelPredicate: chainedAcceptor,
NotifyPendingOpenChannelEvent: evt.NotifyPendingOpenChannelEvent, NotifyPendingOpenChannelEvent: evt.NotifyPendingOpenChannelEvent,
RegisteredChains: newChainRegistry(), RegisteredChains: chainreg.NewChainRegistry(),
} }
for _, op := range options { for _, op := range options {

@ -87,3 +87,13 @@ func CleanAndExpandPath(path string) string {
// but the variables can still be expanded via POSIX-style $VARIABLE. // but the variables can still be expanded via POSIX-style $VARIABLE.
return filepath.Clean(os.ExpandEnv(path)) return filepath.Clean(os.ExpandEnv(path))
} }
// NormalizeNetwork returns the common name of a network type used to create
// file paths. This allows differently versioned networks to use the same path.
func NormalizeNetwork(network string) string {
if strings.HasPrefix(network, "testnet") {
return "testnet"
}
return network
}

183
lnd.go

@ -15,14 +15,18 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime/pprof" "runtime/pprof"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcwallet/wallet" "github.com/btcsuite/btcwallet/wallet"
"github.com/btcsuite/btcwallet/walletdb"
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime" proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino"
"github.com/lightninglabs/neutrino/headerfs"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -32,6 +36,7 @@ import (
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/cert" "github.com/lightningnetwork/lnd/cert"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanacceptor" "github.com/lightningnetwork/lnd/chanacceptor"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
@ -293,7 +298,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
// light client instance, if enabled, in order to allow it to sync // light client instance, if enabled, in order to allow it to sync
// while the rest of the daemon continues startup. // while the rest of the daemon continues startup.
mainChain := cfg.Bitcoin mainChain := cfg.Bitcoin
if cfg.registeredChains.PrimaryChain() == litecoinChain { if cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain {
mainChain = cfg.Litecoin mainChain = cfg.Litecoin
} }
var neutrinoCS *neutrino.ChainService var neutrinoCS *neutrino.ChainService
@ -445,11 +450,29 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
// When we create the chain control, we need storage for the height // When we create the chain control, we need storage for the height
// hints and also the wallet itself, for these two we want them to be // hints and also the wallet itself, for these two we want them to be
// replicated, so we'll pass in the remote channel DB instance. // replicated, so we'll pass in the remote channel DB instance.
activeChainControl, err := newChainControlFromConfig( chainControlCfg := &chainreg.Config{
cfg, localChanDB, remoteChanDB, privateWalletPw, publicWalletPw, Bitcoin: cfg.Bitcoin,
walletInitParams.Birthday, walletInitParams.RecoveryWindow, Litecoin: cfg.Litecoin,
walletInitParams.Wallet, neutrinoCS, PrimaryChain: cfg.registeredChains.PrimaryChain,
) HeightHintCacheQueryDisable: cfg.HeightHintCacheQueryDisable,
NeutrinoMode: cfg.NeutrinoMode,
BitcoindMode: cfg.BitcoindMode,
LitecoindMode: cfg.LitecoindMode,
BtcdMode: cfg.BtcdMode,
LtcdMode: cfg.LtcdMode,
LocalChanDB: localChanDB,
RemoteChanDB: remoteChanDB,
PrivateWalletPw: privateWalletPw,
PublicWalletPw: publicWalletPw,
Birthday: walletInitParams.Birthday,
RecoveryWindow: walletInitParams.RecoveryWindow,
Wallet: walletInitParams.Wallet,
NeutrinoCS: neutrinoCS,
ActiveNetParams: cfg.ActiveNetParams,
FeeURL: cfg.FeeURL,
}
activeChainControl, err := chainreg.NewChainControl(chainControlCfg)
if err != nil { if err != nil {
err := fmt.Errorf("unable to create chain control: %v", err) err := fmt.Errorf("unable to create chain control: %v", err)
ltndLog.Error(err) ltndLog.Error(err)
@ -463,7 +486,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
cfg.registeredChains.RegisterChain(primaryChain, activeChainControl) cfg.registeredChains.RegisterChain(primaryChain, activeChainControl)
// TODO(roasbeef): add rotation // TODO(roasbeef): add rotation
idKeyDesc, err := activeChainControl.keyRing.DeriveKey( idKeyDesc, err := activeChainControl.KeyRing.DeriveKey(
keychain.KeyLocator{ keychain.KeyLocator{
Family: keychain.KeyFamilyNodeKey, Family: keychain.KeyFamilyNodeKey,
Index: 0, Index: 0,
@ -524,7 +547,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
towerDBDir := filepath.Join( towerDBDir := filepath.Join(
cfg.Watchtower.TowerDir, cfg.Watchtower.TowerDir,
cfg.registeredChains.PrimaryChain().String(), cfg.registeredChains.PrimaryChain().String(),
normalizeNetwork(cfg.ActiveNetParams.Name), lncfg.NormalizeNetwork(cfg.ActiveNetParams.Name),
) )
towerDB, err := wtdb.OpenTowerDB(towerDBDir) towerDB, err := wtdb.OpenTowerDB(towerDBDir)
@ -536,7 +559,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
} }
defer towerDB.Close() defer towerDB.Close()
towerKeyDesc, err := activeChainControl.keyRing.DeriveKey( towerKeyDesc, err := activeChainControl.KeyRing.DeriveKey(
keychain.KeyLocator{ keychain.KeyLocator{
Family: keychain.KeyFamilyTowerID, Family: keychain.KeyFamilyTowerID,
Index: 0, Index: 0,
@ -549,19 +572,19 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
} }
wtCfg := &watchtower.Config{ wtCfg := &watchtower.Config{
BlockFetcher: activeChainControl.chainIO, BlockFetcher: activeChainControl.ChainIO,
DB: towerDB, DB: towerDB,
EpochRegistrar: activeChainControl.chainNotifier, EpochRegistrar: activeChainControl.ChainNotifier,
Net: cfg.net, Net: cfg.net,
NewAddress: func() (btcutil.Address, error) { NewAddress: func() (btcutil.Address, error) {
return activeChainControl.wallet.NewAddress( return activeChainControl.Wallet.NewAddress(
lnwallet.WitnessPubKey, false, lnwallet.WitnessPubKey, false,
) )
}, },
NodeKeyECDH: keychain.NewPubKeyECDH( NodeKeyECDH: keychain.NewPubKeyECDH(
towerKeyDesc, activeChainControl.keyRing, towerKeyDesc, activeChainControl.KeyRing,
), ),
PublishTx: activeChainControl.wallet.PublishTransaction, PublishTx: activeChainControl.Wallet.PublishTransaction,
ChainHash: *cfg.ActiveNetParams.GenesisHash, ChainHash: *cfg.ActiveNetParams.GenesisHash,
} }
@ -674,7 +697,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
if !(cfg.Bitcoin.RegTest || cfg.Bitcoin.SimNet || if !(cfg.Bitcoin.RegTest || cfg.Bitcoin.SimNet ||
cfg.Litecoin.RegTest || cfg.Litecoin.SimNet) { cfg.Litecoin.RegTest || cfg.Litecoin.SimNet) {
_, bestHeight, err := activeChainControl.chainIO.GetBestBlock() _, bestHeight, err := activeChainControl.ChainIO.GetBestBlock()
if err != nil { if err != nil {
err := fmt.Errorf("unable to determine chain tip: %v", err := fmt.Errorf("unable to determine chain tip: %v",
err) err)
@ -690,7 +713,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
return nil return nil
} }
synced, _, err := activeChainControl.wallet.IsSynced() synced, _, err := activeChainControl.Wallet.IsSynced()
if err != nil { if err != nil {
err := fmt.Errorf("unable to determine if "+ err := fmt.Errorf("unable to determine if "+
"wallet is synced: %v", err) "wallet is synced: %v", err)
@ -705,7 +728,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
} }
_, bestHeight, err = activeChainControl.chainIO.GetBestBlock() _, bestHeight, err = activeChainControl.ChainIO.GetBestBlock()
if err != nil { if err != nil {
err := fmt.Errorf("unable to determine chain tip: %v", err := fmt.Errorf("unable to determine chain tip: %v",
err) err)
@ -1034,7 +1057,7 @@ func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
defer grpcServer.GracefulStop() defer grpcServer.GracefulStop()
chainConfig := cfg.Bitcoin chainConfig := cfg.Bitcoin
if cfg.registeredChains.PrimaryChain() == litecoinChain { if cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain {
chainConfig = cfg.Litecoin chainConfig = cfg.Litecoin
} }
@ -1311,3 +1334,127 @@ func initializeDatabases(ctx context.Context,
return localChanDB, remoteChanDB, cleanUp, nil return localChanDB, remoteChanDB, cleanUp, nil
} }
// initNeutrinoBackend inits a new instance of the neutrino light client
// backend given a target chain directory to store the chain state.
func initNeutrinoBackend(cfg *Config, chainDir string) (*neutrino.ChainService,
func(), error) {
// First we'll open the database file for neutrino, creating the
// database if needed. We append the normalized network name here to
// match the behavior of btcwallet.
dbPath := filepath.Join(
chainDir, lncfg.NormalizeNetwork(cfg.ActiveNetParams.Name),
)
// Ensure that the neutrino db path exists.
if err := os.MkdirAll(dbPath, 0700); err != nil {
return nil, nil, err
}
dbName := filepath.Join(dbPath, "neutrino.db")
db, err := walletdb.Create("bdb", dbName, !cfg.SyncFreelist)
if err != nil {
return nil, nil, fmt.Errorf("unable to create neutrino "+
"database: %v", err)
}
headerStateAssertion, err := parseHeaderStateAssertion(
cfg.NeutrinoMode.AssertFilterHeader,
)
if err != nil {
db.Close()
return nil, nil, err
}
// With the database open, we can now create an instance of the
// neutrino light client. We pass in relevant configuration parameters
// required.
config := neutrino.Config{
DataDir: dbPath,
Database: db,
ChainParams: *cfg.ActiveNetParams.Params,
AddPeers: cfg.NeutrinoMode.AddPeers,
ConnectPeers: cfg.NeutrinoMode.ConnectPeers,
Dialer: func(addr net.Addr) (net.Conn, error) {
return cfg.net.Dial(
addr.Network(), addr.String(),
cfg.ConnectionTimeout,
)
},
NameResolver: func(host string) ([]net.IP, error) {
addrs, err := cfg.net.LookupHost(host)
if err != nil {
return nil, err
}
ips := make([]net.IP, 0, len(addrs))
for _, strIP := range addrs {
ip := net.ParseIP(strIP)
if ip == nil {
continue
}
ips = append(ips, ip)
}
return ips, nil
},
AssertFilterHeader: headerStateAssertion,
}
neutrino.MaxPeers = 8
neutrino.BanDuration = time.Hour * 48
neutrino.UserAgentName = cfg.NeutrinoMode.UserAgentName
neutrino.UserAgentVersion = cfg.NeutrinoMode.UserAgentVersion
neutrinoCS, err := neutrino.NewChainService(config)
if err != nil {
db.Close()
return nil, nil, fmt.Errorf("unable to create neutrino light "+
"client: %v", err)
}
if err := neutrinoCS.Start(); err != nil {
db.Close()
return nil, nil, err
}
cleanUp := func() {
if err := neutrinoCS.Stop(); err != nil {
ltndLog.Infof("Unable to stop neutrino light client: %v", err)
}
db.Close()
}
return neutrinoCS, cleanUp, nil
}
// parseHeaderStateAssertion parses the user-specified neutrino header state
// into a headerfs.FilterHeader.
func parseHeaderStateAssertion(state string) (*headerfs.FilterHeader, error) {
if len(state) == 0 {
return nil, nil
}
split := strings.Split(state, ":")
if len(split) != 2 {
return nil, fmt.Errorf("header state assertion %v in "+
"unexpected format, expected format height:hash", state)
}
height, err := strconv.ParseUint(split[0], 10, 32)
if err != nil {
return nil, fmt.Errorf("invalid filter header height: %v", err)
}
hash, err := chainhash.NewHashFromStr(split[1])
if err != nil {
return nil, fmt.Errorf("invalid filter header hash: %v", err)
}
return &headerfs.FilterHeader{
Height: uint32(height),
FilterHash: *hash,
}, nil
}

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest"
@ -402,7 +403,7 @@ func (c *interceptorTestContext) buildRoute(ctx context.Context, amtMsat int64,
req := &routerrpc.BuildRouteRequest{ req := &routerrpc.BuildRouteRequest{
AmtMsat: amtMsat, AmtMsat: amtMsat,
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta, FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
HopPubkeys: rpcHops, HopPubkeys: rpcHops,
} }

@ -9,6 +9,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest"
@ -91,7 +92,7 @@ func testSendToRouteMultiPath(net *lntest.NetworkHarness, t *harnessTest) {
req := &routerrpc.BuildRouteRequest{ req := &routerrpc.BuildRouteRequest{
AmtMsat: int64(amt * 1000), AmtMsat: int64(amt * 1000),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta, FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
HopPubkeys: rpcHops, HopPubkeys: rpcHops,
} }

@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest" "github.com/lightningnetwork/lnd/lntest"
@ -173,7 +174,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
const aliceFeeRatePPM = 100000 const aliceFeeRatePPM = 100000
updateChannelPolicy( updateChannelPolicy(
t, net.Alice, chanPointAlice, aliceBaseFeeSat*1000, t, net.Alice, chanPointAlice, aliceBaseFeeSat*1000,
aliceFeeRatePPM, lnd.DefaultBitcoinTimeLockDelta, maxHtlc, aliceFeeRatePPM, chainreg.DefaultBitcoinTimeLockDelta, maxHtlc,
carol, carol,
) )
@ -181,7 +182,7 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
const daveFeeRatePPM = 150000 const daveFeeRatePPM = 150000
updateChannelPolicy( updateChannelPolicy(
t, dave, chanPointDave, daveBaseFeeSat*1000, daveFeeRatePPM, t, dave, chanPointDave, daveBaseFeeSat*1000, daveFeeRatePPM,
lnd.DefaultBitcoinTimeLockDelta, maxHtlc, carol, chainreg.DefaultBitcoinTimeLockDelta, maxHtlc, carol,
) )
// Before we start sending payments, subscribe to htlc events for each // Before we start sending payments, subscribe to htlc events for each

@ -31,6 +31,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/labels" "github.com/lightningnetwork/lnd/labels"
@ -1859,7 +1860,7 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
const ( const (
defaultFeeBase = 1000 defaultFeeBase = 1000
defaultFeeRate = 1 defaultFeeRate = 1
defaultTimeLockDelta = lnd.DefaultBitcoinTimeLockDelta defaultTimeLockDelta = chainreg.DefaultBitcoinTimeLockDelta
defaultMinHtlc = 1000 defaultMinHtlc = 1000
) )
defaultMaxHtlc := calculateMaxHtlc(lnd.MaxBtcFundingAmount) defaultMaxHtlc := calculateMaxHtlc(lnd.MaxBtcFundingAmount)
@ -3155,7 +3156,7 @@ func testChannelUnsettledBalance(net *lntest.NetworkHarness, t *harnessTest) {
Dest: carolPubKey, Dest: carolPubKey,
Amt: int64(payAmt), Amt: int64(payAmt),
PaymentHash: makeFakePayHash(t), PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta, FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
TimeoutSeconds: 60, TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat, FeeLimitMsat: noFeeLimitMsat,
}) })
@ -3452,7 +3453,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest,
// TODO(roasbeef): should check default value in config here // TODO(roasbeef): should check default value in config here
// instead, or make delay a param // instead, or make delay a param
defaultCLTV := uint32(lnd.DefaultBitcoinTimeLockDelta) defaultCLTV := uint32(chainreg.DefaultBitcoinTimeLockDelta)
// We must let Alice have an open channel before she can send a node // We must let Alice have an open channel before she can send a node
// announcement, so we open a channel with Carol, // announcement, so we open a channel with Carol,
@ -3510,7 +3511,7 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest,
Dest: carolPubKey, Dest: carolPubKey,
Amt: int64(paymentAmt), Amt: int64(paymentAmt),
PaymentHash: makeFakePayHash(t), PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta, FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
TimeoutSeconds: 60, TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat, FeeLimitMsat: noFeeLimitMsat,
}, },
@ -5793,7 +5794,7 @@ func testMultiHopSendToRoute(net *lntest.NetworkHarness, t *harnessTest) {
routesReq := &lnrpc.QueryRoutesRequest{ routesReq := &lnrpc.QueryRoutesRequest{
PubKey: carol.PubKeyStr, PubKey: carol.PubKeyStr,
Amt: paymentAmt, Amt: paymentAmt,
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta, FinalCltvDelta: chainreg.DefaultBitcoinTimeLockDelta,
} }
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
routes, err := net.Alice.QueryRoutes(ctxt, routesReq) routes, err := net.Alice.QueryRoutes(ctxt, routesReq)
@ -7959,7 +7960,7 @@ func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) {
// We'll need to mine some blocks in order to mark the channel fully // We'll need to mine some blocks in order to mark the channel fully
// closed. // closed.
_, err = net.Miner.Node.Generate(lnd.DefaultBitcoinTimeLockDelta - defaultCSV) _, err = net.Miner.Node.Generate(chainreg.DefaultBitcoinTimeLockDelta - defaultCSV)
if err != nil { if err != nil {
t.Fatalf("unable to generate blocks: %v", err) t.Fatalf("unable to generate blocks: %v", err)
} }
@ -12603,7 +12604,7 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
// Alice -> Carol -> Dave // Alice -> Carol -> Dave
baseFee := int64(10000) baseFee := int64(10000)
feeRate := int64(5) feeRate := int64(5)
timeLockDelta := uint32(lnd.DefaultBitcoinTimeLockDelta) timeLockDelta := uint32(chainreg.DefaultBitcoinTimeLockDelta)
maxHtlc := calculateMaxHtlc(chanAmt) maxHtlc := calculateMaxHtlc(chanAmt)
expectedPolicy := &lnrpc.RoutingPolicy{ expectedPolicy := &lnrpc.RoutingPolicy{
@ -12864,9 +12865,9 @@ func testSendUpdateDisableChannel(net *lntest.NetworkHarness, t *harnessTest) {
// We should expect to see a channel update with the default routing // We should expect to see a channel update with the default routing
// policy, except that it should indicate the channel is disabled. // policy, except that it should indicate the channel is disabled.
expectedPolicy := &lnrpc.RoutingPolicy{ expectedPolicy := &lnrpc.RoutingPolicy{
FeeBaseMsat: int64(lnd.DefaultBitcoinBaseFeeMSat), FeeBaseMsat: int64(chainreg.DefaultBitcoinBaseFeeMSat),
FeeRateMilliMsat: int64(lnd.DefaultBitcoinFeeRate), FeeRateMilliMsat: int64(chainreg.DefaultBitcoinFeeRate),
TimeLockDelta: lnd.DefaultBitcoinTimeLockDelta, TimeLockDelta: chainreg.DefaultBitcoinTimeLockDelta,
MinHtlc: 1000, // default value MinHtlc: 1000, // default value
MaxHtlcMsat: calculateMaxHtlc(chanAmt), MaxHtlcMsat: calculateMaxHtlc(chanAmt),
Disabled: true, Disabled: true,

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
) )
@ -54,7 +55,7 @@ func TestNurseryStoreInit(t *testing.T) {
} }
defer cleanUp() defer cleanUp()
ns, err := newNurseryStore(&bitcoinTestnetGenesis, cdb) ns, err := newNurseryStore(&chainreg.BitcoinTestnetGenesis, cdb)
if err != nil { if err != nil {
t.Fatalf("unable to open nursery store: %v", err) t.Fatalf("unable to open nursery store: %v", err)
} }
@ -74,7 +75,7 @@ func TestNurseryStoreIncubate(t *testing.T) {
} }
defer cleanUp() defer cleanUp()
ns, err := newNurseryStore(&bitcoinTestnetGenesis, cdb) ns, err := newNurseryStore(&chainreg.BitcoinTestnetGenesis, cdb)
if err != nil { if err != nil {
t.Fatalf("unable to open nursery store: %v", err) t.Fatalf("unable to open nursery store: %v", err)
} }
@ -315,7 +316,7 @@ func TestNurseryStoreGraduate(t *testing.T) {
} }
defer cleanUp() defer cleanUp()
ns, err := newNurseryStore(&bitcoinTestnetGenesis, cdb) ns, err := newNurseryStore(&chainreg.BitcoinTestnetGenesis, cdb)
if err != nil { if err != nil {
t.Fatalf("unable to open nursery store: %v", err) t.Fatalf("unable to open nursery store: %v", err)
} }

@ -9,6 +9,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/tor"
@ -76,7 +77,7 @@ type chanController struct {
minConfs int32 minConfs int32
confTarget uint32 confTarget uint32
chanMinHtlcIn lnwire.MilliSatoshi chanMinHtlcIn lnwire.MilliSatoshi
netParams bitcoinNetParams netParams chainreg.BitcoinNetParams
} }
// OpenChannel opens a channel to a target peer, with a capacity of the // OpenChannel opens a channel to a target peer, with a capacity of the
@ -87,7 +88,7 @@ func (c *chanController) OpenChannel(target *btcec.PublicKey,
// With the connection established, we'll now establish our connection // With the connection established, we'll now establish our connection
// to the target peer, waiting for the first update before we exit. // to the target peer, waiting for the first update before we exit.
feePerKw, err := c.server.cc.feeEstimator.EstimateFeePerKW( feePerKw, err := c.server.cc.FeeEstimator.EstimateFeePerKW(
c.confTarget, c.confTarget,
) )
if err != nil { if err != nil {
@ -134,8 +135,8 @@ var _ autopilot.ChannelController = (*chanController)(nil)
// interfaces needed to drive it won't be launched before the Manager's // interfaces needed to drive it won't be launched before the Manager's
// StartAgent method is called. // StartAgent method is called.
func initAutoPilot(svr *server, cfg *lncfg.AutoPilot, func initAutoPilot(svr *server, cfg *lncfg.AutoPilot,
chainCfg *lncfg.Chain, netParams bitcoinNetParams) (*autopilot.ManagerCfg, chainCfg *lncfg.Chain, netParams chainreg.BitcoinNetParams) (
error) { *autopilot.ManagerCfg, error) {
atplLog.Infof("Instantiating autopilot with active=%v, "+ atplLog.Infof("Instantiating autopilot with active=%v, "+
"max_channels=%d, allocation=%f, min_chan_size=%d, "+ "max_channels=%d, allocation=%f, min_chan_size=%d, "+
@ -178,7 +179,7 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot,
netParams: netParams, netParams: netParams,
}, },
WalletBalance: func() (btcutil.Amount, error) { WalletBalance: func() (btcutil.Amount, error) {
return svr.cc.wallet.ConfirmedBalance(cfg.MinConfs) return svr.cc.Wallet.ConfirmedBalance(cfg.MinConfs)
}, },
Graph: autopilot.ChannelGraphFromDatabase(svr.localChanDB.ChannelGraph()), Graph: autopilot.ChannelGraphFromDatabase(svr.localChanDB.ChannelGraph()),
Constraints: atplConstraints, Constraints: atplConstraints,
@ -289,7 +290,7 @@ func initAutoPilot(svr *server, cfg *lncfg.AutoPilot,
Node: autopilot.NewNodeID(channel.IdentityPub), Node: autopilot.NewNodeID(channel.IdentityPub),
}, nil }, nil
}, },
SubscribeTransactions: svr.cc.wallet.SubscribeTransactions, SubscribeTransactions: svr.cc.Wallet.SubscribeTransactions,
SubscribeTopology: svr.chanRouter.SubscribeTopology, SubscribeTopology: svr.chanRouter.SubscribeTopology,
}, nil }, nil
} }

@ -32,6 +32,7 @@ import (
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime" proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanacceptor" "github.com/lightningnetwork/lnd/chanacceptor"
"github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/chanfitness" "github.com/lightningnetwork/lnd/chanfitness"
@ -1051,7 +1052,7 @@ func (r *rpcServer) sendCoinsOnChain(paymentMap map[string]int64,
return nil, err return nil, err
} }
tx, err := r.server.cc.wallet.SendOutputs(outputs, feeRate, minconf, label) tx, err := r.server.cc.Wallet.SendOutputs(outputs, feeRate, minconf, label)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1083,8 +1084,8 @@ func (r *rpcServer) ListUnspent(ctx context.Context,
// any other concurrent processes attempting to lock any UTXOs which may // any other concurrent processes attempting to lock any UTXOs which may
// be shown available to us. // be shown available to us.
var utxos []*lnwallet.Utxo var utxos []*lnwallet.Utxo
err = r.server.cc.wallet.WithCoinSelectLock(func() error { err = r.server.cc.Wallet.WithCoinSelectLock(func() error {
utxos, err = r.server.cc.wallet.ListUnspentWitness( utxos, err = r.server.cc.Wallet.ListUnspentWitness(
minConfs, maxConfs, minConfs, maxConfs,
) )
return err return err
@ -1126,7 +1127,7 @@ func (r *rpcServer) EstimateFee(ctx context.Context,
// target. // target.
target := in.TargetConf target := in.TargetConf
feePerKw, err := sweep.DetermineFeePerKw( feePerKw, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{ r.server.cc.FeeEstimator, sweep.FeePreference{
ConfTarget: uint32(target), ConfTarget: uint32(target),
}, },
) )
@ -1137,7 +1138,7 @@ func (r *rpcServer) EstimateFee(ctx context.Context,
// We will ask the wallet to create a tx using this fee rate. We set // We will ask the wallet to create a tx using this fee rate. We set
// dryRun=true to avoid inflating the change addresses in the db. // dryRun=true to avoid inflating the change addresses in the db.
var tx *txauthor.AuthoredTx var tx *txauthor.AuthoredTx
wallet := r.server.cc.wallet wallet := r.server.cc.Wallet
err = wallet.WithCoinSelectLock(func() error { err = wallet.WithCoinSelectLock(func() error {
tx, err = wallet.CreateSimpleTx(outputs, feePerKw, true) tx, err = wallet.CreateSimpleTx(outputs, feePerKw, true)
return err return err
@ -1173,7 +1174,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
// appropriate fee rate for this transaction. // appropriate fee rate for this transaction.
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight() satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feePerKw, err := sweep.DetermineFeePerKw( feePerKw, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{ r.server.cc.FeeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf), ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw, FeeRate: satPerKw,
}, },
@ -1226,7 +1227,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
var txid *chainhash.Hash var txid *chainhash.Hash
wallet := r.server.cc.wallet wallet := r.server.cc.Wallet
// If the send all flag is active, then we'll attempt to sweep all the // If the send all flag is active, then we'll attempt to sweep all the
// coins in the wallet in a single transaction (if possible), // coins in the wallet in a single transaction (if possible),
@ -1240,7 +1241,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
"active") "active")
} }
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock() _, bestHeight, err := r.server.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1252,7 +1253,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
sweepTxPkg, err := sweep.CraftSweepAllTx( sweepTxPkg, err := sweep.CraftSweepAllTx(
feePerKw, uint32(bestHeight), targetAddr, wallet, feePerKw, uint32(bestHeight), targetAddr, wallet,
wallet.WalletController, wallet.WalletController, wallet.WalletController, wallet.WalletController,
r.server.cc.feeEstimator, r.server.cc.signer, r.server.cc.FeeEstimator, r.server.cc.Signer,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -1312,7 +1313,7 @@ func (r *rpcServer) SendMany(ctx context.Context,
// appropriate fee rate for this transaction. // appropriate fee rate for this transaction.
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight() satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feePerKw, err := sweep.DetermineFeePerKw( feePerKw, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{ r.server.cc.FeeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf), ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw, FeeRate: satPerKw,
}, },
@ -1341,7 +1342,7 @@ func (r *rpcServer) SendMany(ctx context.Context,
// We'll attempt to send to the target set of outputs, ensuring that we // We'll attempt to send to the target set of outputs, ensuring that we
// synchronize with any other ongoing coin selection attempts which // synchronize with any other ongoing coin selection attempts which
// happen to also be concurrently executing. // happen to also be concurrently executing.
wallet := r.server.cc.wallet wallet := r.server.cc.Wallet
err = wallet.WithCoinSelectLock(func() error { err = wallet.WithCoinSelectLock(func() error {
sendManyTXID, err := r.sendCoinsOnChain( sendManyTXID, err := r.sendCoinsOnChain(
in.AddrToAmount, feePerKw, minConfs, label, in.AddrToAmount, feePerKw, minConfs, label,
@ -1375,7 +1376,7 @@ func (r *rpcServer) NewAddress(ctx context.Context,
) )
switch in.Type { switch in.Type {
case lnrpc.AddressType_WITNESS_PUBKEY_HASH: case lnrpc.AddressType_WITNESS_PUBKEY_HASH:
addr, err = r.server.cc.wallet.NewAddress( addr, err = r.server.cc.Wallet.NewAddress(
lnwallet.WitnessPubKey, false, lnwallet.WitnessPubKey, false,
) )
if err != nil { if err != nil {
@ -1383,7 +1384,7 @@ func (r *rpcServer) NewAddress(ctx context.Context,
} }
case lnrpc.AddressType_NESTED_PUBKEY_HASH: case lnrpc.AddressType_NESTED_PUBKEY_HASH:
addr, err = r.server.cc.wallet.NewAddress( addr, err = r.server.cc.Wallet.NewAddress(
lnwallet.NestedWitnessPubKey, false, lnwallet.NestedWitnessPubKey, false,
) )
if err != nil { if err != nil {
@ -1391,7 +1392,7 @@ func (r *rpcServer) NewAddress(ctx context.Context,
} }
case lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH: case lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH:
addr, err = r.server.cc.wallet.LastUnusedAddress( addr, err = r.server.cc.Wallet.LastUnusedAddress(
lnwallet.WitnessPubKey, lnwallet.WitnessPubKey,
) )
if err != nil { if err != nil {
@ -1399,7 +1400,7 @@ func (r *rpcServer) NewAddress(ctx context.Context,
} }
case lnrpc.AddressType_UNUSED_NESTED_PUBKEY_HASH: case lnrpc.AddressType_UNUSED_NESTED_PUBKEY_HASH:
addr, err = r.server.cc.wallet.LastUnusedAddress( addr, err = r.server.cc.Wallet.LastUnusedAddress(
lnwallet.NestedWitnessPubKey, lnwallet.NestedWitnessPubKey,
) )
if err != nil { if err != nil {
@ -1743,7 +1744,7 @@ func (r *rpcServer) canOpenChannel() error {
// Creation of channels before the wallet syncs up is currently // Creation of channels before the wallet syncs up is currently
// disallowed. // disallowed.
isSynced, _, err := r.server.cc.wallet.IsSynced() isSynced, _, err := r.server.cc.Wallet.IsSynced()
if err != nil { if err != nil {
return err return err
} }
@ -1863,7 +1864,7 @@ func (r *rpcServer) parseOpenChannelReq(in *lnrpc.OpenChannelRequest,
// appropriate fee rate for the funding transaction. // appropriate fee rate for the funding transaction.
satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight() satPerKw := chainfee.SatPerKVByte(in.SatPerByte * 1000).FeePerKWeight()
feeRate, err := sweep.DetermineFeePerKw( feeRate, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{ r.server.cc.FeeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf), ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw, FeeRate: satPerKw,
}, },
@ -1931,7 +1932,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
// to obtain the channel point details. // to obtain the channel point details.
copy(req.pendingChanID[:], chanPointShim.PendingChanId) copy(req.pendingChanID[:], chanPointShim.PendingChanId)
req.chanFunder, err = newFundingShimAssembler( req.chanFunder, err = newFundingShimAssembler(
chanPointShim, true, r.server.cc.keyRing, chanPointShim, true, r.server.cc.KeyRing,
) )
if err != nil { if err != nil {
return err return err
@ -1950,7 +1951,7 @@ func (r *rpcServer) OpenChannel(in *lnrpc.OpenChannelRequest,
copy(req.pendingChanID[:], psbtShim.PendingChanId) copy(req.pendingChanID[:], psbtShim.PendingChanId)
req.chanFunder, err = newPsbtAssembler( req.chanFunder, err = newPsbtAssembler(
in, req.minConfs, psbtShim, in, req.minConfs, psbtShim,
&r.server.cc.wallet.Cfg.NetParams, &r.server.cc.Wallet.Cfg.NetParams,
) )
if err != nil { if err != nil {
return err return err
@ -2155,7 +2156,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
// Retrieve the best height of the chain, which we'll use to complete // Retrieve the best height of the chain, which we'll use to complete
// either closing flow. // either closing flow.
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock() _, bestHeight, err := r.server.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return err return err
} }
@ -2202,7 +2203,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
} }
errChan = make(chan error, 1) errChan = make(chan error, 1)
notifier := r.server.cc.chainNotifier notifier := r.server.cc.ChainNotifier
go peer.WaitForChanToClose(uint32(bestHeight), notifier, errChan, chanPoint, go peer.WaitForChanToClose(uint32(bestHeight), notifier, errChan, chanPoint,
&closingTxid, closingTx.TxOut[0].PkScript, func() { &closingTxid, closingTx.TxOut[0].PkScript, func() {
// Respond to the local subsystem which // Respond to the local subsystem which
@ -2246,7 +2247,7 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
in.SatPerByte * 1000, in.SatPerByte * 1000,
).FeePerKWeight() ).FeePerKWeight()
feeRate, err := sweep.DetermineFeePerKw( feeRate, err := sweep.DetermineFeePerKw(
r.server.cc.feeEstimator, sweep.FeePreference{ r.server.cc.FeeEstimator, sweep.FeePreference{
ConfTarget: uint32(in.TargetConf), ConfTarget: uint32(in.TargetConf),
FeeRate: satPerKw, FeeRate: satPerKw,
}, },
@ -2408,7 +2409,7 @@ func (r *rpcServer) AbandonChannel(_ context.Context,
// When we remove the channel from the database, we need to set a close // When we remove the channel from the database, we need to set a close
// height, so we'll just use the current best known height. // height, so we'll just use the current best known height.
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock() _, bestHeight, err := r.server.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2522,18 +2523,18 @@ func (r *rpcServer) GetInfo(ctx context.Context,
idPub := r.server.identityECDH.PubKey().SerializeCompressed() idPub := r.server.identityECDH.PubKey().SerializeCompressed()
encodedIDPub := hex.EncodeToString(idPub) encodedIDPub := hex.EncodeToString(idPub)
bestHash, bestHeight, err := r.server.cc.chainIO.GetBestBlock() bestHash, bestHeight, err := r.server.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to get best block info: %v", err) return nil, fmt.Errorf("unable to get best block info: %v", err)
} }
isSynced, bestHeaderTimestamp, err := r.server.cc.wallet.IsSynced() isSynced, bestHeaderTimestamp, err := r.server.cc.Wallet.IsSynced()
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to sync PoV of the wallet "+ return nil, fmt.Errorf("unable to sync PoV of the wallet "+
"with current best block in the main chain: %v", err) "with current best block in the main chain: %v", err)
} }
network := normalizeNetwork(r.cfg.ActiveNetParams.Name) network := lncfg.NormalizeNetwork(r.cfg.ActiveNetParams.Name)
activeChains := make([]*lnrpc.Chain, r.cfg.registeredChains.NumActiveChains()) activeChains := make([]*lnrpc.Chain, r.cfg.registeredChains.NumActiveChains())
for i, chain := range r.cfg.registeredChains.ActiveChains() { for i, chain := range r.cfg.registeredChains.ActiveChains() {
activeChains[i] = &lnrpc.Chain{ activeChains[i] = &lnrpc.Chain{
@ -2584,7 +2585,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
BlockHeight: uint32(bestHeight), BlockHeight: uint32(bestHeight),
BlockHash: bestHash.String(), BlockHash: bestHash.String(),
SyncedToChain: isSynced, SyncedToChain: isSynced,
Testnet: isTestnet(&r.cfg.ActiveNetParams), Testnet: chainreg.IsTestnet(&r.cfg.ActiveNetParams),
Chains: activeChains, Chains: activeChains,
Uris: uris, Uris: uris,
Alias: nodeAnn.Alias.String(), Alias: nodeAnn.Alias.String(),
@ -2603,7 +2604,7 @@ func (r *rpcServer) GetInfo(ctx context.Context,
func (r *rpcServer) GetRecoveryInfo(ctx context.Context, func (r *rpcServer) GetRecoveryInfo(ctx context.Context,
in *lnrpc.GetRecoveryInfoRequest) (*lnrpc.GetRecoveryInfoResponse, error) { in *lnrpc.GetRecoveryInfoRequest) (*lnrpc.GetRecoveryInfoResponse, error) {
isRecoveryMode, progress, err := r.server.cc.wallet.GetRecoveryInfo() isRecoveryMode, progress, err := r.server.cc.Wallet.GetRecoveryInfo()
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to get wallet recovery info: %v", err) return nil, fmt.Errorf("unable to get wallet recovery info: %v", err)
} }
@ -2804,7 +2805,7 @@ func (r *rpcServer) WalletBalance(ctx context.Context,
in *lnrpc.WalletBalanceRequest) (*lnrpc.WalletBalanceResponse, error) { in *lnrpc.WalletBalanceRequest) (*lnrpc.WalletBalanceResponse, error) {
// Get total balance, from txs that have >= 0 confirmations. // Get total balance, from txs that have >= 0 confirmations.
totalBal, err := r.server.cc.wallet.ConfirmedBalance(0) totalBal, err := r.server.cc.Wallet.ConfirmedBalance(0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2812,7 +2813,7 @@ func (r *rpcServer) WalletBalance(ctx context.Context,
// Get confirmed balance, from txs that have >= 1 confirmations. // Get confirmed balance, from txs that have >= 1 confirmations.
// TODO(halseth): get both unconfirmed and confirmed balance in one // TODO(halseth): get both unconfirmed and confirmed balance in one
// call, as this is racy. // call, as this is racy.
confirmedBal, err := r.server.cc.wallet.ConfirmedBalance(1) confirmedBal, err := r.server.cc.Wallet.ConfirmedBalance(1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -2980,7 +2981,7 @@ func (r *rpcServer) PendingChannels(ctx context.Context,
} }
} }
_, currentHeight, err := r.server.cc.chainIO.GetBestBlock() _, currentHeight, err := r.server.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -4723,7 +4724,7 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
invoice *lnrpc.Invoice) (*lnrpc.AddInvoiceResponse, error) { invoice *lnrpc.Invoice) (*lnrpc.AddInvoiceResponse, error) {
defaultDelta := r.cfg.Bitcoin.TimeLockDelta defaultDelta := r.cfg.Bitcoin.TimeLockDelta
if r.cfg.registeredChains.PrimaryChain() == litecoinChain { if r.cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain {
defaultDelta = r.cfg.Litecoin.TimeLockDelta defaultDelta = r.cfg.Litecoin.TimeLockDelta
} }
@ -4923,7 +4924,7 @@ func (r *rpcServer) SubscribeInvoices(req *lnrpc.InvoiceSubscription,
func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest, func (r *rpcServer) SubscribeTransactions(req *lnrpc.GetTransactionsRequest,
updateStream lnrpc.Lightning_SubscribeTransactionsServer) error { updateStream lnrpc.Lightning_SubscribeTransactionsServer) error {
txClient, err := r.server.cc.wallet.SubscribeTransactions() txClient, err := r.server.cc.Wallet.SubscribeTransactions()
if err != nil { if err != nil {
return err return err
} }
@ -4989,7 +4990,7 @@ func (r *rpcServer) GetTransactions(ctx context.Context,
endHeight = req.EndHeight endHeight = req.EndHeight
} }
transactions, err := r.server.cc.wallet.ListTransactionDetails( transactions, err := r.server.cc.Wallet.ListTransactionDetails(
req.StartHeight, endHeight, req.StartHeight, endHeight,
) )
if err != nil { if err != nil {
@ -6090,7 +6091,7 @@ func (r *rpcServer) ExportChannelBackup(ctx context.Context,
// backup. // backup.
packedBackups, err := chanbackup.PackStaticChanBackups( packedBackups, err := chanbackup.PackStaticChanBackups(
[]chanbackup.Single{*unpackedBackup}, []chanbackup.Single{*unpackedBackup},
r.server.cc.keyRing, r.server.cc.KeyRing,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("packing of back ups failed: %v", err) return nil, fmt.Errorf("packing of back ups failed: %v", err)
@ -6147,7 +6148,7 @@ func (r *rpcServer) VerifyChanBackup(ctx context.Context,
// With our PackedSingles created, we'll attempt to unpack the // With our PackedSingles created, we'll attempt to unpack the
// backup. If this fails, then we know the backup is invalid for // backup. If this fails, then we know the backup is invalid for
// some reason. // some reason.
_, err := chanBackup.Unpack(r.server.cc.keyRing) _, err := chanBackup.Unpack(r.server.cc.KeyRing)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid single channel "+ return nil, fmt.Errorf("invalid single channel "+
"backup: %v", err) "backup: %v", err)
@ -6161,7 +6162,7 @@ func (r *rpcServer) VerifyChanBackup(ctx context.Context,
// We'll now attempt to unpack the Multi. If this fails, then we // We'll now attempt to unpack the Multi. If this fails, then we
// know it's invalid. // know it's invalid.
_, err := packedMulti.Unpack(r.server.cc.keyRing) _, err := packedMulti.Unpack(r.server.cc.KeyRing)
if err != nil { if err != nil {
return nil, fmt.Errorf("invalid multi channel backup: "+ return nil, fmt.Errorf("invalid multi channel backup: "+
"%v", err) "%v", err)
@ -6180,7 +6181,7 @@ func (r *rpcServer) createBackupSnapshot(backups []chanbackup.Single) (
// Once we have the set of back ups, we'll attempt to pack them all // Once we have the set of back ups, we'll attempt to pack them all
// into a series of single channel backups. // into a series of single channel backups.
singleChanPackedBackups, err := chanbackup.PackStaticChanBackups( singleChanPackedBackups, err := chanbackup.PackStaticChanBackups(
backups, r.server.cc.keyRing, backups, r.server.cc.KeyRing,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to pack set of chan "+ return nil, fmt.Errorf("unable to pack set of chan "+
@ -6218,7 +6219,7 @@ func (r *rpcServer) createBackupSnapshot(backups []chanbackup.Single) (
unpackedMultiBackup := chanbackup.Multi{ unpackedMultiBackup := chanbackup.Multi{
StaticBackups: backups, StaticBackups: backups,
} }
err = unpackedMultiBackup.PackToWriter(&b, r.server.cc.keyRing) err = unpackedMultiBackup.PackToWriter(&b, r.server.cc.KeyRing)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to multi-pack backups: %v", err) return nil, fmt.Errorf("unable to multi-pack backups: %v", err)
} }
@ -6273,7 +6274,7 @@ func (r *rpcServer) RestoreChannelBackups(ctx context.Context,
// backups. // backups.
chanRestorer := &chanDBRestorer{ chanRestorer := &chanDBRestorer{
db: r.server.remoteChanDB, db: r.server.remoteChanDB,
secretKeys: r.server.cc.keyRing, secretKeys: r.server.cc.KeyRing,
chainArb: r.server.chainArb, chainArb: r.server.chainArb,
} }
@ -6298,7 +6299,7 @@ func (r *rpcServer) RestoreChannelBackups(ctx context.Context,
// channel peers. // channel peers.
err := chanbackup.UnpackAndRecoverSingles( err := chanbackup.UnpackAndRecoverSingles(
chanbackup.PackedSingles(packedBackups), chanbackup.PackedSingles(packedBackups),
r.server.cc.keyRing, chanRestorer, r.server, r.server.cc.KeyRing, chanRestorer, r.server,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to unpack single "+ return nil, fmt.Errorf("unable to unpack single "+
@ -6314,7 +6315,7 @@ func (r *rpcServer) RestoreChannelBackups(ctx context.Context,
// channel peers. // channel peers.
packedMulti := chanbackup.PackedMulti(packedMultiBackup) packedMulti := chanbackup.PackedMulti(packedMultiBackup)
err := chanbackup.UnpackAndRecoverMulti( err := chanbackup.UnpackAndRecoverMulti(
packedMulti, r.server.cc.keyRing, chanRestorer, packedMulti, r.server.cc.KeyRing, chanRestorer,
r.server, r.server,
) )
if err != nil { if err != nil {
@ -6757,7 +6758,7 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
// chanfunding.Assembler that is able to express proper // chanfunding.Assembler that is able to express proper
// formulation of this expected channel. // formulation of this expected channel.
shimAssembler, err := newFundingShimAssembler( shimAssembler, err := newFundingShimAssembler(
rpcShimIntent, false, r.server.cc.keyRing, rpcShimIntent, false, r.server.cc.KeyRing,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -6775,7 +6776,7 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
// pending channel ID, then this shim will be dispatched in // pending channel ID, then this shim will be dispatched in
// place of our regular funding workflow. // place of our regular funding workflow.
copy(pendingChanID[:], rpcShimIntent.PendingChanId) copy(pendingChanID[:], rpcShimIntent.PendingChanId)
err = r.server.cc.wallet.RegisterFundingIntent( err = r.server.cc.Wallet.RegisterFundingIntent(
pendingChanID, shimIntent, pendingChanID, shimIntent,
) )
if err != nil { if err != nil {
@ -6799,7 +6800,7 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
in.GetShimCancel().PendingChanId) in.GetShimCancel().PendingChanId)
copy(pendingChanID[:], in.GetShimCancel().PendingChanId) copy(pendingChanID[:], in.GetShimCancel().PendingChanId)
err := r.server.cc.wallet.CancelFundingIntent(pendingChanID) err := r.server.cc.Wallet.CancelFundingIntent(pendingChanID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -6819,7 +6820,7 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
return nil, fmt.Errorf("error parsing psbt: %v", err) return nil, fmt.Errorf("error parsing psbt: %v", err)
} }
err = r.server.cc.wallet.PsbtFundingVerify( err = r.server.cc.Wallet.PsbtFundingVerify(
pendingChanID, packet, pendingChanID, packet,
) )
if err != nil { if err != nil {
@ -6872,7 +6873,7 @@ func (r *rpcServer) FundingStateStep(ctx context.Context,
"finalize missing") "finalize missing")
} }
err = r.server.cc.wallet.PsbtFundingFinalize( err = r.server.cc.Wallet.PsbtFundingFinalize(
pendingChanID, packet, rawTx, pendingChanID, packet, rawTx,
) )
if err != nil { if err != nil {

132
server.go

@ -27,6 +27,7 @@ import (
sphinx "github.com/lightningnetwork/lightning-onion" sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/brontide" "github.com/lightningnetwork/lnd/brontide"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/chanacceptor" "github.com/lightningnetwork/lnd/chanacceptor"
"github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanbackup"
"github.com/lightningnetwork/lnd/chanfitness" "github.com/lightningnetwork/lnd/chanfitness"
@ -66,7 +67,6 @@ import (
"github.com/lightningnetwork/lnd/tor" "github.com/lightningnetwork/lnd/tor"
"github.com/lightningnetwork/lnd/walletunlocker" "github.com/lightningnetwork/lnd/walletunlocker"
"github.com/lightningnetwork/lnd/watchtower/wtclient" "github.com/lightningnetwork/lnd/watchtower/wtclient"
"github.com/lightningnetwork/lnd/watchtower/wtdb"
"github.com/lightningnetwork/lnd/watchtower/wtpolicy" "github.com/lightningnetwork/lnd/watchtower/wtpolicy"
"github.com/lightningnetwork/lnd/watchtower/wtserver" "github.com/lightningnetwork/lnd/watchtower/wtserver"
) )
@ -203,7 +203,7 @@ type server struct {
// intended to replace it. // intended to replace it.
scheduledPeerConnection map[string]func() scheduledPeerConnection map[string]func()
cc *chainControl cc *chainreg.ChainControl
fundingMgr *fundingManager fundingMgr *fundingManager
@ -338,7 +338,7 @@ func noiseDial(idKey keychain.SingleKeyECDH,
// passed listener address. // passed listener address.
func newServer(cfg *Config, listenAddrs []net.Addr, func newServer(cfg *Config, listenAddrs []net.Addr,
localChanDB, remoteChanDB *channeldb.DB, localChanDB, remoteChanDB *channeldb.DB,
towerClientDB *wtdb.ClientDB, cc *chainControl, towerClientDB wtclient.DB, cc *chainreg.ChainControl,
nodeKeyDesc *keychain.KeyDescriptor, nodeKeyDesc *keychain.KeyDescriptor,
chansToRestore walletunlocker.ChannelsToRecover, chansToRestore walletunlocker.ChannelsToRecover,
chanPredicate chanacceptor.ChannelAcceptor, chanPredicate chanacceptor.ChannelAcceptor,
@ -346,9 +346,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
var ( var (
err error err error
nodeKeyECDH = keychain.NewPubKeyECDH(*nodeKeyDesc, cc.keyRing) nodeKeyECDH = keychain.NewPubKeyECDH(*nodeKeyDesc, cc.KeyRing)
nodeKeySigner = keychain.NewPubKeyDigestSigner( nodeKeySigner = keychain.NewPubKeyDigestSigner(
*nodeKeyDesc, cc.keyRing, *nodeKeyDesc, cc.KeyRing,
) )
) )
@ -374,7 +374,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
sharedSecretPath := filepath.Join( sharedSecretPath := filepath.Join(
cfg.localDatabaseDir(), defaultSphinxDbName, cfg.localDatabaseDir(), defaultSphinxDbName,
) )
replayLog := htlcswitch.NewDecayedLog(sharedSecretPath, cc.chainNotifier) replayLog := htlcswitch.NewDecayedLog(sharedSecretPath, cc.ChainNotifier)
sphinxRouter := sphinx.NewRouter( sphinxRouter := sphinx.NewRouter(
nodeKeyECDH, cfg.ActiveNetParams.Params, replayLog, nodeKeyECDH, cfg.ActiveNetParams.Params, replayLog,
) )
@ -422,7 +422,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
localChanDB: localChanDB, localChanDB: localChanDB,
remoteChanDB: remoteChanDB, remoteChanDB: remoteChanDB,
cc: cc, cc: cc,
sigPool: lnwallet.NewSigPool(cfg.Workers.Sig, cc.signer), sigPool: lnwallet.NewSigPool(cfg.Workers.Sig, cc.Signer),
writePool: writePool, writePool: writePool,
readPool: readPool, readPool: readPool,
chansToRestore: chansToRestore, chansToRestore: chansToRestore,
@ -468,7 +468,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
subscribers: make(map[uint64]*preimageSubscriber), subscribers: make(map[uint64]*preimageSubscriber),
} }
_, currentHeight, err := s.cc.chainIO.GetBestBlock() _, currentHeight, err := s.cc.ChainIO.GetBestBlock()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -495,7 +495,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
SwitchPackager: channeldb.NewSwitchPackager(), SwitchPackager: channeldb.NewSwitchPackager(),
ExtractErrorEncrypter: s.sphinx.ExtractErrorEncrypter, ExtractErrorEncrypter: s.sphinx.ExtractErrorEncrypter,
FetchLastChannelUpdate: s.fetchLastChanUpdate(), FetchLastChannelUpdate: s.fetchLastChanUpdate(),
Notifier: s.cc.chainNotifier, Notifier: s.cc.ChainNotifier,
HtlcNotifier: s.htlcNotifier, HtlcNotifier: s.htlcNotifier,
FwdEventTicker: ticker.New(htlcswitch.DefaultFwdEventInterval), FwdEventTicker: ticker.New(htlcswitch.DefaultFwdEventInterval),
LogEventTicker: ticker.New(htlcswitch.DefaultLogInterval), LogEventTicker: ticker.New(htlcswitch.DefaultLogInterval),
@ -752,8 +752,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
s.chanRouter, err = routing.New(routing.Config{ s.chanRouter, err = routing.New(routing.Config{
Graph: chanGraph, Graph: chanGraph,
Chain: cc.chainIO, Chain: cc.ChainIO,
ChainView: cc.chainView, ChainView: cc.ChainView,
Payer: s.htlcSwitch, Payer: s.htlcSwitch,
Control: s.controlTower, Control: s.controlTower,
MissionControl: s.missionControl, MissionControl: s.missionControl,
@ -782,7 +782,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
s.authGossiper = discovery.New(discovery.Config{ s.authGossiper = discovery.New(discovery.Config{
Router: s.chanRouter, Router: s.chanRouter,
Notifier: s.cc.chainNotifier, Notifier: s.cc.ChainNotifier,
ChainHash: *s.cfg.ActiveNetParams.GenesisHash, ChainHash: *s.cfg.ActiveNetParams.GenesisHash,
Broadcast: s.BroadcastMessage, Broadcast: s.BroadcastMessage,
ChanSeries: chanSeries, ChanSeries: chanSeries,
@ -833,14 +833,14 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
} }
s.sweeper = sweep.New(&sweep.UtxoSweeperConfig{ s.sweeper = sweep.New(&sweep.UtxoSweeperConfig{
FeeEstimator: cc.feeEstimator, FeeEstimator: cc.FeeEstimator,
GenSweepScript: newSweepPkScriptGen(cc.wallet), GenSweepScript: newSweepPkScriptGen(cc.Wallet),
Signer: cc.wallet.Cfg.Signer, Signer: cc.Wallet.Cfg.Signer,
Wallet: cc.wallet, Wallet: cc.Wallet,
NewBatchTimer: func() <-chan time.Time { NewBatchTimer: func() <-chan time.Time {
return time.NewTimer(sweep.DefaultBatchWindowDuration).C return time.NewTimer(sweep.DefaultBatchWindowDuration).C
}, },
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
Store: sweeperStore, Store: sweeperStore,
MaxInputsPerTx: sweep.DefaultMaxInputsPerTx, MaxInputsPerTx: sweep.DefaultMaxInputsPerTx,
MaxSweepAttempts: sweep.DefaultMaxSweepAttempts, MaxSweepAttempts: sweep.DefaultMaxSweepAttempts,
@ -850,12 +850,12 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
}) })
s.utxoNursery = newUtxoNursery(&NurseryConfig{ s.utxoNursery = newUtxoNursery(&NurseryConfig{
ChainIO: cc.chainIO, ChainIO: cc.ChainIO,
ConfDepth: 1, ConfDepth: 1,
FetchClosedChannels: remoteChanDB.FetchClosedChannels, FetchClosedChannels: remoteChanDB.FetchClosedChannels,
FetchClosedChannel: remoteChanDB.FetchClosedChannel, FetchClosedChannel: remoteChanDB.FetchClosedChannel,
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
PublishTransaction: cc.wallet.PublishTransaction, PublishTransaction: cc.Wallet.PublishTransaction,
Store: utxnStore, Store: utxnStore,
SweepInput: s.sweeper.SweepInput, SweepInput: s.sweeper.SweepInput,
}) })
@ -880,8 +880,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
ChainHash: *s.cfg.ActiveNetParams.GenesisHash, ChainHash: *s.cfg.ActiveNetParams.GenesisHash,
IncomingBroadcastDelta: lncfg.DefaultIncomingBroadcastDelta, IncomingBroadcastDelta: lncfg.DefaultIncomingBroadcastDelta,
OutgoingBroadcastDelta: lncfg.DefaultOutgoingBroadcastDelta, OutgoingBroadcastDelta: lncfg.DefaultOutgoingBroadcastDelta,
NewSweepAddr: newSweepPkScriptGen(cc.wallet), NewSweepAddr: newSweepPkScriptGen(cc.Wallet),
PublishTx: cc.wallet.PublishTransaction, PublishTx: cc.Wallet.PublishTransaction,
DeliverResolutionMsg: func(msgs ...contractcourt.ResolutionMsg) error { DeliverResolutionMsg: func(msgs ...contractcourt.ResolutionMsg) error {
for _, msg := range msgs { for _, msg := range msgs {
err := s.htlcSwitch.ProcessContractResolution(msg) err := s.htlcSwitch.ProcessContractResolution(msg)
@ -913,16 +913,16 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
) )
}, },
PreimageDB: s.witnessBeacon, PreimageDB: s.witnessBeacon,
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
Signer: cc.wallet.Cfg.Signer, Signer: cc.Wallet.Cfg.Signer,
FeeEstimator: cc.feeEstimator, FeeEstimator: cc.FeeEstimator,
ChainIO: cc.chainIO, ChainIO: cc.ChainIO,
MarkLinkInactive: func(chanPoint wire.OutPoint) error { MarkLinkInactive: func(chanPoint wire.OutPoint) error {
chanID := lnwire.NewChanIDFromOutPoint(&chanPoint) chanID := lnwire.NewChanIDFromOutPoint(&chanPoint)
s.htlcSwitch.RemoveLink(chanID) s.htlcSwitch.RemoveLink(chanID)
return nil return nil
}, },
IsOurAddress: cc.wallet.IsOurAddress, IsOurAddress: cc.Wallet.IsOurAddress,
ContractBreach: func(chanPoint wire.OutPoint, ContractBreach: func(chanPoint wire.OutPoint,
breachRet *lnwallet.BreachRetribution) error { breachRet *lnwallet.BreachRetribution) error {
event := &ContractBreachEvent{ event := &ContractBreachEvent{
@ -959,12 +959,12 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
s.breachArbiter = newBreachArbiter(&BreachConfig{ s.breachArbiter = newBreachArbiter(&BreachConfig{
CloseLink: closeLink, CloseLink: closeLink,
DB: remoteChanDB, DB: remoteChanDB,
Estimator: s.cc.feeEstimator, Estimator: s.cc.FeeEstimator,
GenSweepScript: newSweepPkScriptGen(cc.wallet), GenSweepScript: newSweepPkScriptGen(cc.Wallet),
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
PublishTransaction: cc.wallet.PublishTransaction, PublishTransaction: cc.Wallet.PublishTransaction,
ContractBreaches: contractBreaches, ContractBreaches: contractBreaches,
Signer: cc.wallet.Cfg.Signer, Signer: cc.Wallet.Cfg.Signer,
Store: newRetributionStore(remoteChanDB), Store: newRetributionStore(remoteChanDB),
}) })
@ -974,7 +974,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
chainCfg := cfg.Bitcoin chainCfg := cfg.Bitcoin
minRemoteDelay := minBtcRemoteDelay minRemoteDelay := minBtcRemoteDelay
maxRemoteDelay := maxBtcRemoteDelay maxRemoteDelay := maxBtcRemoteDelay
if primaryChain == litecoinChain { if primaryChain == chainreg.LitecoinChain {
chainCfg = cfg.Litecoin chainCfg = cfg.Litecoin
minRemoteDelay = minLtcRemoteDelay minRemoteDelay = minLtcRemoteDelay
maxRemoteDelay = maxLtcRemoteDelay maxRemoteDelay = maxLtcRemoteDelay
@ -988,13 +988,13 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
s.fundingMgr, err = newFundingManager(fundingConfig{ s.fundingMgr, err = newFundingManager(fundingConfig{
NoWumboChans: !cfg.ProtocolOptions.Wumbo(), NoWumboChans: !cfg.ProtocolOptions.Wumbo(),
IDKey: nodeKeyECDH.PubKey(), IDKey: nodeKeyECDH.PubKey(),
Wallet: cc.wallet, Wallet: cc.Wallet,
PublishTransaction: cc.wallet.PublishTransaction, PublishTransaction: cc.Wallet.PublishTransaction,
UpdateLabel: func(hash chainhash.Hash, label string) error { UpdateLabel: func(hash chainhash.Hash, label string) error {
return cc.wallet.LabelTransaction(hash, label, true) return cc.Wallet.LabelTransaction(hash, label, true)
}, },
Notifier: cc.chainNotifier, Notifier: cc.ChainNotifier,
FeeEstimator: cc.feeEstimator, FeeEstimator: cc.FeeEstimator,
SignMessage: func(pubKey *btcec.PublicKey, SignMessage: func(pubKey *btcec.PublicKey,
msg []byte) (input.Signature, error) { msg []byte) (input.Signature, error) {
@ -1002,7 +1002,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
return s.nodeSigner.SignMessage(pubKey, msg) return s.nodeSigner.SignMessage(pubKey, msg)
} }
return cc.msgSigner.SignMessage(pubKey, msg) return cc.MsgSigner.SignMessage(pubKey, msg)
}, },
CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, error) { CurrentNodeAnnouncement: func() (lnwire.NodeAnnouncement, error) {
return s.genNodeAnnouncement(true) return s.genNodeAnnouncement(true)
@ -1032,8 +1032,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
return nil, fmt.Errorf("unable to find channel") return nil, fmt.Errorf("unable to find channel")
}, },
DefaultRoutingPolicy: cc.routingPolicy, DefaultRoutingPolicy: cc.RoutingPolicy,
DefaultMinHtlcIn: cc.minHtlcIn, DefaultMinHtlcIn: cc.MinHtlcIn,
NumRequiredConfs: func(chanAmt btcutil.Amount, NumRequiredConfs: func(chanAmt btcutil.Amount,
pushAmt lnwire.MilliSatoshi) uint16 { pushAmt lnwire.MilliSatoshi) uint16 {
// For large channels we increase the number // For large channels we increase the number
@ -1196,7 +1196,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
return nil, err return nil, err
} }
s.chanSubSwapper, err = chanbackup.NewSubSwapper( s.chanSubSwapper, err = chanbackup.NewSubSwapper(
startingChans, chanNotifier, s.cc.keyRing, backupFile, startingChans, chanNotifier, s.cc.KeyRing, backupFile,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -1249,9 +1249,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
} }
s.towerClient, err = wtclient.New(&wtclient.Config{ s.towerClient, err = wtclient.New(&wtclient.Config{
Signer: cc.wallet.Cfg.Signer, Signer: cc.Wallet.Cfg.Signer,
NewAddress: newSweepPkScriptGen(cc.wallet), NewAddress: newSweepPkScriptGen(cc.Wallet),
SecretKeyRing: s.cc.keyRing, SecretKeyRing: s.cc.KeyRing,
Dial: cfg.net.Dial, Dial: cfg.net.Dial,
AuthDial: authDial, AuthDial: authDial,
DB: towerClientDB, DB: towerClientDB,
@ -1292,7 +1292,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
chainHealthCheck := healthcheck.NewObservation( chainHealthCheck := healthcheck.NewObservation(
"chain backend", "chain backend",
func() error { func() error {
_, _, err := cc.chainIO.GetBestBlock() _, _, err := cc.ChainIO.GetBestBlock()
return err return err
}, },
cfg.HealthChecks.ChainCheck.Interval, cfg.HealthChecks.ChainCheck.Interval,
@ -1412,7 +1412,7 @@ func (s *server) Start() error {
startErr = err startErr = err
return return
} }
if err := s.cc.chainNotifier.Start(); err != nil { if err := s.cc.ChainNotifier.Start(); err != nil {
startErr = err startErr = err
return return
} }
@ -1490,13 +1490,13 @@ func (s *server) Start() error {
// recovery _before_ we even accept connections from any peers. // recovery _before_ we even accept connections from any peers.
chanRestorer := &chanDBRestorer{ chanRestorer := &chanDBRestorer{
db: s.remoteChanDB, db: s.remoteChanDB,
secretKeys: s.cc.keyRing, secretKeys: s.cc.KeyRing,
chainArb: s.chainArb, chainArb: s.chainArb,
} }
if len(s.chansToRestore.PackedSingleChanBackups) != 0 { if len(s.chansToRestore.PackedSingleChanBackups) != 0 {
err := chanbackup.UnpackAndRecoverSingles( err := chanbackup.UnpackAndRecoverSingles(
s.chansToRestore.PackedSingleChanBackups, s.chansToRestore.PackedSingleChanBackups,
s.cc.keyRing, chanRestorer, s, s.cc.KeyRing, chanRestorer, s,
) )
if err != nil { if err != nil {
startErr = fmt.Errorf("unable to unpack single "+ startErr = fmt.Errorf("unable to unpack single "+
@ -1507,7 +1507,7 @@ func (s *server) Start() error {
if len(s.chansToRestore.PackedMultiChanBackup) != 0 { if len(s.chansToRestore.PackedMultiChanBackup) != 0 {
err := chanbackup.UnpackAndRecoverMulti( err := chanbackup.UnpackAndRecoverMulti(
s.chansToRestore.PackedMultiChanBackup, s.chansToRestore.PackedMultiChanBackup,
s.cc.keyRing, chanRestorer, s, s.cc.KeyRing, chanRestorer, s,
) )
if err != nil { if err != nil {
startErr = fmt.Errorf("unable to unpack chan "+ startErr = fmt.Errorf("unable to unpack chan "+
@ -1578,7 +1578,9 @@ func (s *server) Stop() error {
// Shutdown the wallet, funding manager, and the rpc server. // Shutdown the wallet, funding manager, and the rpc server.
s.chanStatusMgr.Stop() s.chanStatusMgr.Stop()
s.cc.chainNotifier.Stop() if err := s.cc.ChainNotifier.Stop(); err != nil {
srvrLog.Warnf("Unable to stop ChainNotifier: %v", err)
}
s.chanRouter.Stop() s.chanRouter.Stop()
s.htlcSwitch.Stop() s.htlcSwitch.Stop()
s.sphinx.Stop() s.sphinx.Stop()
@ -1590,10 +1592,16 @@ func (s *server) Stop() error {
s.channelNotifier.Stop() s.channelNotifier.Stop()
s.peerNotifier.Stop() s.peerNotifier.Stop()
s.htlcNotifier.Stop() s.htlcNotifier.Stop()
s.cc.wallet.Shutdown() if err := s.cc.Wallet.Shutdown(); err != nil {
s.cc.chainView.Stop() srvrLog.Warnf("Unable to stop Wallet: %v", err)
}
if err := s.cc.ChainView.Stop(); err != nil {
srvrLog.Warnf("Unable to stop ChainView: %v", err)
}
s.connMgr.Stop() s.connMgr.Stop()
s.cc.feeEstimator.Stop() if err := s.cc.FeeEstimator.Stop(); err != nil {
srvrLog.Warnf("Unable to stop FeeEstimator: %v", err)
}
s.invoices.Stop() s.invoices.Stop()
s.fundingMgr.Stop() s.fundingMgr.Stop()
s.chanSubSwapper.Stop() s.chanSubSwapper.Stop()
@ -1852,7 +1860,7 @@ func initNetworkBootstrappers(s *server) ([]discovery.NetworkPeerBootstrapper, e
// If this isn't simnet mode, then one of our additional bootstrapping // If this isn't simnet mode, then one of our additional bootstrapping
// sources will be the set of running DNS seeds. // sources will be the set of running DNS seeds.
if !s.cfg.Bitcoin.SimNet || !s.cfg.Litecoin.SimNet { if !s.cfg.Bitcoin.SimNet || !s.cfg.Litecoin.SimNet {
dnsSeeds, ok := chainDNSSeeds[*s.cfg.ActiveNetParams.GenesisHash] dnsSeeds, ok := chainreg.ChainDNSSeeds[*s.cfg.ActiveNetParams.GenesisHash]
// If we have a set of DNS seeds for this chain, then we'll add // If we have a set of DNS seeds for this chain, then we'll add
// it as an additional bootstrapping source. // it as an additional bootstrapping source.
@ -2964,13 +2972,13 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq,
ChainArb: s.chainArb, ChainArb: s.chainArb,
AuthGossiper: s.authGossiper, AuthGossiper: s.authGossiper,
ChanStatusMgr: s.chanStatusMgr, ChanStatusMgr: s.chanStatusMgr,
ChainIO: s.cc.chainIO, ChainIO: s.cc.ChainIO,
FeeEstimator: s.cc.feeEstimator, FeeEstimator: s.cc.FeeEstimator,
Signer: s.cc.wallet.Cfg.Signer, Signer: s.cc.Wallet.Cfg.Signer,
SigPool: s.sigPool, SigPool: s.sigPool,
Wallet: s.cc.wallet, Wallet: s.cc.Wallet,
ChainNotifier: s.cc.chainNotifier, ChainNotifier: s.cc.ChainNotifier,
RoutingPolicy: s.cc.routingPolicy, RoutingPolicy: s.cc.RoutingPolicy,
Sphinx: s.sphinx, Sphinx: s.sphinx,
WitnessBeacon: s.witnessBeacon, WitnessBeacon: s.witnessBeacon,
Invoices: s.invoices, Invoices: s.invoices,
@ -3572,7 +3580,7 @@ func (s *server) OpenChannel(
// If the fee rate wasn't specified, then we'll use a default // If the fee rate wasn't specified, then we'll use a default
// confirmation target. // confirmation target.
if req.fundingFeePerKw == 0 { if req.fundingFeePerKw == 0 {
estimator := s.cc.feeEstimator estimator := s.cc.FeeEstimator
feeRate, err := estimator.EstimateFeePerKW(6) feeRate, err := estimator.EstimateFeePerKW(6)
if err != nil { if err != nil {
req.err <- err req.err <- err

@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btclog" "github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/autopilot" "github.com/lightningnetwork/lnd/autopilot"
"github.com/lightningnetwork/lnd/chainreg"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/invoices"
@ -81,7 +82,8 @@ type subRPCServerConfigs struct {
// //
// NOTE: This MUST be called before any callers are permitted to execute the // NOTE: This MUST be called before any callers are permitted to execute the
// FetchConfig method. // FetchConfig method.
func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, cc *chainControl, func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config,
cc *chainreg.ChainControl,
networkDir string, macService *macaroons.Service, networkDir string, macService *macaroons.Service,
atpl *autopilot.Manager, atpl *autopilot.Manager,
invoiceRegistry *invoices.InvoiceRegistry, invoiceRegistry *invoices.InvoiceRegistry,
@ -132,10 +134,10 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, cc *chainControl
reflect.ValueOf(networkDir), reflect.ValueOf(networkDir),
) )
subCfgValue.FieldByName("Signer").Set( subCfgValue.FieldByName("Signer").Set(
reflect.ValueOf(cc.signer), reflect.ValueOf(cc.Signer),
) )
subCfgValue.FieldByName("KeyRing").Set( subCfgValue.FieldByName("KeyRing").Set(
reflect.ValueOf(cc.keyRing), reflect.ValueOf(cc.KeyRing),
) )
case *walletrpc.Config: case *walletrpc.Config:
@ -148,22 +150,22 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, cc *chainControl
reflect.ValueOf(macService), reflect.ValueOf(macService),
) )
subCfgValue.FieldByName("FeeEstimator").Set( subCfgValue.FieldByName("FeeEstimator").Set(
reflect.ValueOf(cc.feeEstimator), reflect.ValueOf(cc.FeeEstimator),
) )
subCfgValue.FieldByName("Wallet").Set( subCfgValue.FieldByName("Wallet").Set(
reflect.ValueOf(cc.wallet), reflect.ValueOf(cc.Wallet),
) )
subCfgValue.FieldByName("CoinSelectionLocker").Set( subCfgValue.FieldByName("CoinSelectionLocker").Set(
reflect.ValueOf(cc.wallet), reflect.ValueOf(cc.Wallet),
) )
subCfgValue.FieldByName("KeyRing").Set( subCfgValue.FieldByName("KeyRing").Set(
reflect.ValueOf(cc.keyRing), reflect.ValueOf(cc.KeyRing),
) )
subCfgValue.FieldByName("Sweeper").Set( subCfgValue.FieldByName("Sweeper").Set(
reflect.ValueOf(sweeper), reflect.ValueOf(sweeper),
) )
subCfgValue.FieldByName("Chain").Set( subCfgValue.FieldByName("Chain").Set(
reflect.ValueOf(cc.chainIO), reflect.ValueOf(cc.ChainIO),
) )
subCfgValue.FieldByName("ChainParams").Set( subCfgValue.FieldByName("ChainParams").Set(
reflect.ValueOf(activeNetParams), reflect.ValueOf(activeNetParams),
@ -186,7 +188,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, cc *chainControl
reflect.ValueOf(macService), reflect.ValueOf(macService),
) )
subCfgValue.FieldByName("ChainNotifier").Set( subCfgValue.FieldByName("ChainNotifier").Set(
reflect.ValueOf(cc.chainNotifier), reflect.ValueOf(cc.ChainNotifier),
) )
case *invoicesrpc.Config: case *invoicesrpc.Config:
@ -211,7 +213,7 @@ func (s *subRPCServerConfigs) PopulateDependencies(cfg *Config, cc *chainControl
reflect.ValueOf(nodeSigner), reflect.ValueOf(nodeSigner),
) )
defaultDelta := cfg.Bitcoin.TimeLockDelta defaultDelta := cfg.Bitcoin.TimeLockDelta
if cfg.registeredChains.PrimaryChain() == litecoinChain { if cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain {
defaultDelta = cfg.Litecoin.TimeLockDelta defaultDelta = cfg.Litecoin.TimeLockDelta
} }
subCfgValue.FieldByName("DefaultCLTVExpiry").Set( subCfgValue.FieldByName("DefaultCLTVExpiry").Set(