chainregistry: generalize bitcoind logic to handle litecoind

This commit is contained in:
Conner Fromknecht 2018-03-13 21:15:20 -07:00
parent 5e21c38fdb
commit 5f7a62913f
No known key found for this signature in database
GPG Key ID: 39DE78FBE6ACB0EF

View File

@ -22,23 +22,46 @@ import (
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/chainview"
"github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/rpcclient"
"github.com/roasbeef/btcutil"
"github.com/roasbeef/btcwallet/chain"
"github.com/roasbeef/btcwallet/walletdb"
)
// defaultChannelConstraints is the default set of channel constraints that are
// meant to be used when initially funding a channel.
const (
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?
var defaultChannelConstraints = channeldb.ChannelConstraints{
var defaultBtcChannelConstraints = channeldb.ChannelConstraints{
DustLimit: lnwallet.DefaultDustLimit(),
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
// currently supported within lnd.
type chainCode uint32
@ -111,7 +134,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
TimeLockDelta: cfg.Bitcoin.TimeLockDelta,
}
cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeeRate: 50,
FeeRate: defaultBitcoinStaticFeeRate,
}
case litecoinChain:
cc.routingPolicy = htlcswitch.ForwardingPolicy{
@ -121,7 +144,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
TimeLockDelta: cfg.Litecoin.TimeLockDelta,
}
cc.feeEstimator = lnwallet.StaticFeeEstimator{
FeeRate: 100,
FeeRate: defaultLitecoinStaticFeeRate,
}
default:
return nil, nil, fmt.Errorf("Default routing policy for "+
@ -223,17 +246,24 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
// database.
walletConfig.ChainSource = chain.NewNeutrinoClient(svc)
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
// bitcoind node. If the specified host for the btcd/ltcd RPC
// server already has a port specified, then we use that
// directly. Otherwise, we assume the default port according to
// the selected chain parameters.
var bitcoindHost string
if strings.Contains(cfg.BitcoindMode.RPCHost, ":") {
bitcoindHost = cfg.BitcoindMode.RPCHost
if strings.Contains(bitcoindMode.RPCHost, ":") {
bitcoindHost = bitcoindMode.RPCHost
} else {
// The RPC ports specified in chainparams.go assume
// btcd, which picks a different port so that btcwallet
@ -245,13 +275,13 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
}
rpcPort -= 2
bitcoindHost = fmt.Sprintf("%v:%d",
cfg.BitcoindMode.RPCHost, rpcPort)
if cfg.Bitcoin.RegTest {
bitcoindMode.RPCHost, rpcPort)
if cfg.Bitcoin.Active && cfg.Bitcoin.RegTest {
conn, err := net.Dial("tcp", bitcoindHost)
if err != nil || conn == nil {
rpcPort = 18443
bitcoindHost = fmt.Sprintf("%v:%d",
cfg.BitcoindMode.RPCHost,
bitcoindMode.RPCHost,
rpcPort)
} else {
conn.Close()
@ -259,8 +289,8 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
}
}
bitcoindUser := cfg.BitcoindMode.RPCUser
bitcoindPass := cfg.BitcoindMode.RPCPass
bitcoindUser := bitcoindMode.RPCUser
bitcoindPass := bitcoindMode.RPCPass
rpcConfig := &rpcclient.ConnConfig{
Host: bitcoindHost,
User: bitcoindUser,
@ -271,7 +301,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
HTTPPostMode: true,
}
cc.chainNotifier, err = bitcoindnotify.New(rpcConfig,
cfg.BitcoindMode.ZMQPath, *activeNetParams.Params)
bitcoindMode.ZMQPath, *activeNetParams.Params)
if err != nil {
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
// be used within the routing layer.
cc.chainView, err = chainview.NewBitcoindFilteredChainView(
*rpcConfig, cfg.BitcoindMode.ZMQPath,
*rpcConfig, bitcoindMode.ZMQPath,
*activeNetParams.Params)
if err != nil {
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.
bitcoindConn, err = chain.NewBitcoindClient(
activeNetParams.Params, bitcoindHost, bitcoindUser,
bitcoindPass, cfg.BitcoindMode.ZMQPath,
bitcoindPass, bitcoindMode.ZMQPath,
time.Millisecond*100)
if err != nil {
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
// proper fee estimator for testnet.
if !cfg.Bitcoin.RegTest {
if cfg.Bitcoin.Active && !cfg.Bitcoin.RegTest {
ltndLog.Infof("Initializing bitcoind backed fee estimator")
// 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 {
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.
//
// 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.chainIO = wc
// Select the default channel constraints for the primary chain.
channelConstraints := defaultBtcChannelConstraints
if registeredChains.PrimaryChain() == litecoinChain {
channelConstraints = defaultLtcChannelConstraints
}
keyRing := keychain.NewBtcWalletKeyRing(
wc.InternalWallet(), activeNetParams.CoinType,
)
@ -451,7 +504,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
FeeEstimator: cc.feeEstimator,
SecretKeyRing: keyRing,
ChainIO: cc.chainIO,
DefaultConstraints: defaultChannelConstraints,
DefaultConstraints: channelConstraints,
NetParams: *activeNetParams.Params,
}
wallet, err := lnwallet.NewLightningWallet(walletCfg)