chainregistry: generalize bitcoind logic to handle litecoind

This commit is contained in:
Conner Fromknecht committed 2018-03-14 16:57:37 -07:00
1 parent 5e21c38fdb
commit 5f7a62913f
1 file changed
+74 -21
+74 -21
View File
@@ -22,23 +22,46 @@ import (
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/chainview" "github.com/lightningnetwork/lnd/routing/chainview"
"github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/rpcclient" "github.com/roasbeef/btcd/rpcclient"
"github.com/roasbeef/btcutil"
"github.com/roasbeef/btcwallet/chain" "github.com/roasbeef/btcwallet/chain"
"github.com/roasbeef/btcwallet/walletdb" "github.com/roasbeef/btcwallet/walletdb"
) )
// defaultChannelConstraints is the default set of channel constraints that are const (
// meant to be used when initially funding a channel. defaultBitcoinMinHTLCMSat = lnwire.MilliSatoshi(1000)
defaultBitcoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
defaultBitcoinFeeRate = lnwire.MilliSatoshi(1)
defaultBitcoinTimeLockDelta = 144
defaultBitcoinStaticFeeRate = lnwallet.SatPerVByte(50)
defaultLitecoinMinHTLCMSat = lnwire.MilliSatoshi(1000)
defaultLitecoinBaseFeeMSat = lnwire.MilliSatoshi(1000)
defaultLitecoinFeeRate = lnwire.MilliSatoshi(1)
defaultLitecoinTimeLockDelta = 576
defaultLitecoinStaticFeeRate = lnwallet.SatPerVByte(200)
defaultLitecoinMinRelayFee = btcutil.Amount(1000)
)
// defaultBtcChannelConstraints is the default set of channel constraints that are
// meant to be used when initially funding a Bitcoin channel.
// //
// TODO(roasbeef): have one for both chains
// TODO(halseth): make configurable at startup? // TODO(halseth): make configurable at startup?
var defaultChannelConstraints = channeldb.ChannelConstraints{ var defaultBtcChannelConstraints = channeldb.ChannelConstraints{
DustLimit: lnwallet.DefaultDustLimit(), DustLimit: lnwallet.DefaultDustLimit(),
MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2, MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2,
} }
// defaultLtcChannelConstraints is the default set of channel constraints that are
// meant to be used when initially funding a Litecoin channel.
var defaultLtcChannelConstraints = channeldb.ChannelConstraints{
DustLimit: defaultLitecoinMinRelayFee,
MaxAcceptedHtlcs: lnwallet.MaxHTLCNumber / 2,
}
// chainCode is an enum-like structure for keeping track of the chains // chainCode is an enum-like structure for keeping track of the chains
// currently supported within lnd. // currently supported within lnd.
type chainCode uint32 type chainCode uint32
@@ -111,7 +134,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
TimeLockDelta: cfg.Bitcoin.TimeLockDelta, TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
} }
cc.feeEstimator = lnwallet.StaticFeeEstimator{ cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeeRate: 50, FeeRate: defaultBitcoinStaticFeeRate,
} }
case litecoinChain: case litecoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{ cc.routingPolicy = htlcswitch.ForwardingPolicy{
@@ -121,7 +144,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
TimeLockDelta: cfg.Litecoin.TimeLockDelta, TimeLockDelta: cfg.Litecoin.TimeLockDelta,
} }
cc.feeEstimator = lnwallet.StaticFeeEstimator{ cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeeRate: 100, FeeRate: defaultLitecoinStaticFeeRate,
} }
default: default:
return nil, nil, fmt.Errorf("Default routing policy for "+ return nil, nil, fmt.Errorf("Default routing policy for "+
@@ -223,17 +246,24 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// database. // database.
walletConfig.ChainSource = chain.NewNeutrinoClient(svc) walletConfig.ChainSource = chain.NewNeutrinoClient(svc)
cleanUp = func() { cleanUp = func() {
defer nodeDatabase.Close() nodeDatabase.Close()
}
case "bitcoind", "litecoind":
var bitcoindMode *bitcoindConfig
switch {
case cfg.Bitcoin.Active:
bitcoindMode = cfg.BitcoindMode
case cfg.Litecoin.Active:
bitcoindMode = cfg.LitecoindMode
} }
case "bitcoind":
// Otherwise, we'll be speaking directly via RPC and ZMQ to a // Otherwise, we'll be speaking directly via RPC and ZMQ to a
// bitcoind node. If the specified host for the btcd/ltcd RPC // bitcoind node. If the specified host for the btcd/ltcd RPC
// server already has a port specified, then we use that // server already has a port specified, then we use that
// directly. Otherwise, we assume the default port according to // directly. Otherwise, we assume the default port according to
// the selected chain parameters. // the selected chain parameters.
var bitcoindHost string var bitcoindHost string
if strings.Contains(cfg.BitcoindMode.RPCHost, ":") { if strings.Contains(bitcoindMode.RPCHost, ":") {
bitcoindHost = cfg.BitcoindMode.RPCHost bitcoindHost = bitcoindMode.RPCHost
} else { } else {
// The RPC ports specified in chainparams.go assume // The RPC ports specified in chainparams.go assume
// btcd, which picks a different port so that btcwallet // btcd, which picks a different port so that btcwallet
@@ -245,13 +275,13 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
} }
rpcPort -= 2 rpcPort -= 2
bitcoindHost = fmt.Sprintf("%v:%d", bitcoindHost = fmt.Sprintf("%v:%d",
cfg.BitcoindMode.RPCHost, rpcPort) bitcoindMode.RPCHost, rpcPort)
if cfg.Bitcoin.RegTest { if cfg.Bitcoin.Active && cfg.Bitcoin.RegTest {
conn, err := net.Dial("tcp", bitcoindHost) conn, err := net.Dial("tcp", bitcoindHost)
if err != nil || conn == nil { if err != nil || conn == nil {
rpcPort = 18443 rpcPort = 18443
bitcoindHost = fmt.Sprintf("%v:%d", bitcoindHost = fmt.Sprintf("%v:%d",
cfg.BitcoindMode.RPCHost, bitcoindMode.RPCHost,
rpcPort) rpcPort)
} else { } else {
conn.Close() conn.Close()
@@ -259,8 +289,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
} }
} }
bitcoindUser := cfg.BitcoindMode.RPCUser bitcoindUser := bitcoindMode.RPCUser
bitcoindPass := cfg.BitcoindMode.RPCPass bitcoindPass := bitcoindMode.RPCPass
rpcConfig := &rpcclient.ConnConfig{ rpcConfig := &rpcclient.ConnConfig{
Host: bitcoindHost, Host: bitcoindHost,
User: bitcoindUser, User: bitcoindUser,
@@ -271,7 +301,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
HTTPPostMode: true, HTTPPostMode: true,
} }
cc.chainNotifier, err = bitcoindnotify.New(rpcConfig, cc.chainNotifier, err = bitcoindnotify.New(rpcConfig,
cfg.BitcoindMode.ZMQPath, *activeNetParams.Params) bitcoindMode.ZMQPath, *activeNetParams.Params)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@@ -279,7 +309,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// Next, we'll create an instance of the bitcoind chain view to // Next, we'll create an instance of the bitcoind chain view to
// be used within the routing layer. // be used within the routing layer.
cc.chainView, err = chainview.NewBitcoindFilteredChainView( cc.chainView, err = chainview.NewBitcoindFilteredChainView(
*rpcConfig, cfg.BitcoindMode.ZMQPath, *rpcConfig, bitcoindMode.ZMQPath,
*activeNetParams.Params) *activeNetParams.Params)
if err != nil { if err != nil {
srvrLog.Errorf("unable to create chain view: %v", err) srvrLog.Errorf("unable to create chain view: %v", err)
@@ -290,7 +320,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// used by the wallet for notifications, calls, etc. // used by the wallet for notifications, calls, etc.
bitcoindConn, err = chain.NewBitcoindClient( bitcoindConn, err = chain.NewBitcoindClient(
activeNetParams.Params, bitcoindHost, bitcoindUser, activeNetParams.Params, bitcoindHost, bitcoindUser,
bitcoindPass, cfg.BitcoindMode.ZMQPath, bitcoindPass, bitcoindMode.ZMQPath,
time.Millisecond*100) time.Millisecond*100)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@@ -300,7 +330,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// 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
// proper fee estimator for testnet. // proper fee estimator for testnet.
if !cfg.Bitcoin.RegTest { if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest {
ltndLog.Infof("Initializing bitcoind backed fee estimator") ltndLog.Infof("Initializing bitcoind backed fee estimator")
// Finally, we'll re-initialize the fee estimator, as // Finally, we'll re-initialize the fee estimator, as
@@ -317,8 +347,25 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
if err := cc.feeEstimator.Start(); err != nil { if err := cc.feeEstimator.Start(); err != nil {
return nil, nil, err return nil, nil, err
} }
} else if cfg.Litecoin.Active {
ltndLog.Infof("Initializing litecoind backed fee estimator")
// Finally, we'll re-initialize the fee estimator, as
// if we're using litecoind as a backend, then we can
// use live fee estimates, rather than a statically
// coded value.
fallBackFeeRate := lnwallet.SatPerVByte(25)
cc.feeEstimator, err = lnwallet.NewBitcoindFeeEstimator(
*rpcConfig, fallBackFeeRate,
)
if err != nil {
return nil, nil, err
}
if err := cc.feeEstimator.Start(); err != nil {
return nil, nil, err
}
} }
case "btcd": case "btcd", "ltcd":
// Otherwise, we'll be speaking directly via RPC to a node. // Otherwise, we'll be speaking directly via RPC to a node.
// //
// So first we'll load btcd/ltcd's TLS cert for the RPC // So first we'll load btcd/ltcd's TLS cert for the RPC
@@ -437,6 +484,12 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
cc.signer = wc cc.signer = wc
cc.chainIO = wc cc.chainIO = wc
// Select the default channel constraints for the primary chain.
channelConstraints := defaultBtcChannelConstraints
if registeredChains.PrimaryChain() == litecoinChain {
channelConstraints = defaultLtcChannelConstraints
}
keyRing := keychain.NewBtcWalletKeyRing( keyRing := keychain.NewBtcWalletKeyRing(
wc.InternalWallet(), activeNetParams.CoinType, wc.InternalWallet(), activeNetParams.CoinType,
) )
@@ -451,7 +504,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
FeeEstimator: cc.feeEstimator, FeeEstimator: cc.feeEstimator,
SecretKeyRing: keyRing, SecretKeyRing: keyRing,
ChainIO: cc.chainIO, ChainIO: cc.chainIO,
DefaultConstraints: defaultChannelConstraints, DefaultConstraints: channelConstraints,
NetParams: *activeNetParams.Params, NetParams: *activeNetParams.Params,
} }
wallet, err := lnwallet.NewLightningWallet(walletCfg) wallet, err := lnwallet.NewLightningWallet(walletCfg)