Merge pull request #838 from cfromknecht/litecoind-backend
Litecoind Backend
This commit is contained in:
commit
695b09e32b
@ -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)
|
||||
|
88
config.go
88
config.go
@ -52,16 +52,6 @@ const (
|
||||
// HTLCs on our channels.
|
||||
minTimeLockDelta = 4
|
||||
|
||||
defaultBitcoinMinHTLCMSat = 1000
|
||||
defaultBitcoinBaseFeeMSat = 1000
|
||||
defaultBitcoinFeeRate = 1
|
||||
defaultBitcoinTimeLockDelta = 144
|
||||
|
||||
defaultLitecoinMinHTLCMSat = 1000
|
||||
defaultLitecoinBaseFeeMSat = 1000
|
||||
defaultLitecoinFeeRate = 1
|
||||
defaultLitecoinTimeLockDelta = 576
|
||||
|
||||
defaultAlias = ""
|
||||
defaultColor = "#3399FF"
|
||||
)
|
||||
@ -82,14 +72,15 @@ var (
|
||||
defaultLtcdDir = btcutil.AppDataDir("ltcd", false)
|
||||
defaultLtcdRPCCertFile = filepath.Join(defaultLtcdDir, "rpc.cert")
|
||||
|
||||
defaultBitcoindDir = btcutil.AppDataDir("bitcoin", false)
|
||||
defaultBitcoindDir = btcutil.AppDataDir("bitcoin", false)
|
||||
defaultLitecoindDir = btcutil.AppDataDir("litecoin", false)
|
||||
)
|
||||
|
||||
type chainConfig struct {
|
||||
Active bool `long:"active" description:"If the chain should be active or not."`
|
||||
ChainDir string `long:"chaindir" description:"The directory to store the chain's data within."`
|
||||
|
||||
Node string `long:"node" description:"The blockchain interface to use." choice:"btcd" choice:"bitcoind" choice:"neutrino"`
|
||||
Node string `long:"node" description:"The blockchain interface to use." choice:"btcd" choice:"bitcoind" choice:"neutrino" choice:"ltcd" choice:"litecoind"`
|
||||
|
||||
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
||||
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
||||
@ -182,8 +173,9 @@ type config struct {
|
||||
BitcoindMode *bitcoindConfig `group:"bitcoind" namespace:"bitcoind"`
|
||||
NeutrinoMode *neutrinoConfig `group:"neutrino" namespace:"neutrino"`
|
||||
|
||||
Litecoin *chainConfig `group:"Litecoin" namespace:"litecoin"`
|
||||
LtcdMode *btcdConfig `group:"ltcd" namespace:"ltcd"`
|
||||
Litecoin *chainConfig `group:"Litecoin" namespace:"litecoin"`
|
||||
LtcdMode *btcdConfig `group:"ltcd" namespace:"ltcd"`
|
||||
LitecoindMode *bitcoindConfig `group:"litecoind" namespace:"litecoind"`
|
||||
|
||||
Autopilot *autoPilotConfig `group:"autopilot" namespace:"autopilot"`
|
||||
|
||||
@ -241,13 +233,17 @@ func loadConfig() (*config, error) {
|
||||
BaseFee: defaultLitecoinBaseFeeMSat,
|
||||
FeeRate: defaultLitecoinFeeRate,
|
||||
TimeLockDelta: defaultLitecoinTimeLockDelta,
|
||||
Node: "btcd",
|
||||
Node: "ltcd",
|
||||
},
|
||||
LtcdMode: &btcdConfig{
|
||||
Dir: defaultLtcdDir,
|
||||
RPCHost: defaultRPCHost,
|
||||
RPCCert: defaultLtcdRPCCertFile,
|
||||
},
|
||||
LitecoindMode: &bitcoindConfig{
|
||||
Dir: defaultLitecoindDir,
|
||||
RPCHost: defaultRPCHost,
|
||||
},
|
||||
MaxPendingChannels: defaultMaxPendingChannels,
|
||||
NoEncryptWallet: defaultNoEncryptWallet,
|
||||
Autopilot: &autoPilotConfig{
|
||||
@ -333,6 +329,7 @@ func loadConfig() (*config, error) {
|
||||
cfg.BtcdMode.Dir = cleanAndExpandPath(cfg.BtcdMode.Dir)
|
||||
cfg.LtcdMode.Dir = cleanAndExpandPath(cfg.LtcdMode.Dir)
|
||||
cfg.BitcoindMode.Dir = cleanAndExpandPath(cfg.BitcoindMode.Dir)
|
||||
cfg.LitecoindMode.Dir = cleanAndExpandPath(cfg.LitecoindMode.Dir)
|
||||
|
||||
// Setup dial and DNS resolution functions depending on the specified
|
||||
// options. The default is to use the standard golang "net" package
|
||||
@ -398,17 +395,16 @@ func loadConfig() (*config, error) {
|
||||
str := "%s: simnet mode for litecoin not currently supported"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
if cfg.Litecoin.RegTest {
|
||||
str := "%s: regnet mode for litecoin not currently supported"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
|
||||
if cfg.Litecoin.TimeLockDelta < minTimeLockDelta {
|
||||
return nil, fmt.Errorf("timelockdelta must be at least %v",
|
||||
minTimeLockDelta)
|
||||
}
|
||||
|
||||
if cfg.Litecoin.Node != "btcd" {
|
||||
str := "%s: only ltcd (`btcd`) mode supported for litecoin at this time"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
|
||||
// The litecoin chain is the current active chain. However
|
||||
// throughout the codebase we required chaincfg.Params. So as a
|
||||
// temporary hack, we'll mutate the default net params for
|
||||
@ -417,12 +413,31 @@ func loadConfig() (*config, error) {
|
||||
applyLitecoinParams(¶mCopy)
|
||||
activeNetParams = paramCopy
|
||||
|
||||
err := parseRPCParams(cfg.Litecoin, cfg.LtcdMode, litecoinChain,
|
||||
funcName)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to load RPC credentials for "+
|
||||
"ltcd: %v", err)
|
||||
return nil, err
|
||||
switch cfg.Litecoin.Node {
|
||||
case "ltcd":
|
||||
err := parseRPCParams(cfg.Litecoin, cfg.LtcdMode,
|
||||
litecoinChain, funcName)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to load RPC "+
|
||||
"credentials for ltcd: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
case "litecoind":
|
||||
if cfg.Litecoin.SimNet {
|
||||
return nil, fmt.Errorf("%s: litecoind does not "+
|
||||
"support simnet", funcName)
|
||||
}
|
||||
err := parseRPCParams(cfg.Litecoin, cfg.LitecoindMode,
|
||||
litecoinChain, funcName)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to load RPC "+
|
||||
"credentials for litecoind: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
str := "%s: only ltcd and litecoind mode supported for " +
|
||||
"litecoin at this time"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
|
||||
cfg.Litecoin.ChainDir = filepath.Join(cfg.DataDir,
|
||||
@ -485,6 +500,10 @@ func loadConfig() (*config, error) {
|
||||
}
|
||||
case "neutrino":
|
||||
// No need to get RPC parameters.
|
||||
default:
|
||||
str := "%s: only btcd, bitcoind, and neutrino mode " +
|
||||
"supported for bitcoin at this time"
|
||||
return nil, fmt.Errorf(str, funcName)
|
||||
}
|
||||
|
||||
cfg.Bitcoin.ChainDir = filepath.Join(cfg.DataDir,
|
||||
@ -762,9 +781,16 @@ func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
|
||||
"bitcoind.zmqpath")
|
||||
}
|
||||
|
||||
daemonName = "bitcoind"
|
||||
confDir = conf.Dir
|
||||
confFile = "bitcoin"
|
||||
switch net {
|
||||
case bitcoinChain:
|
||||
daemonName = "bitcoind"
|
||||
confDir = conf.Dir
|
||||
confFile = "bitcoin"
|
||||
case litecoinChain:
|
||||
daemonName = "litecoind"
|
||||
confDir = conf.Dir
|
||||
confFile = "litecoin"
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in simnet mode, then the running btcd instance won't read
|
||||
@ -780,7 +806,7 @@ func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
|
||||
|
||||
confFile = filepath.Join(confDir, fmt.Sprintf("%v.conf", confFile))
|
||||
switch cConfig.Node {
|
||||
case "btcd":
|
||||
case "btcd", "ltcd":
|
||||
nConf := nodeConfig.(*btcdConfig)
|
||||
rpcUser, rpcPass, err := extractBtcdRPCParams(confFile)
|
||||
if err != nil {
|
||||
@ -789,7 +815,7 @@ func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
|
||||
err)
|
||||
}
|
||||
nConf.RPCUser, nConf.RPCPass = rpcUser, rpcPass
|
||||
case "bitcoind":
|
||||
case "bitcoind", "litecoind":
|
||||
nConf := nodeConfig.(*bitcoindConfig)
|
||||
rpcUser, rpcPass, zmqPath, err := extractBitcoindRPCParams(confFile)
|
||||
if err != nil {
|
||||
|
@ -178,17 +178,33 @@ installing `lnd` in preparation for the
|
||||
lnd --bitcoin.active --bitcoin.testnet --debuglevel=debug --btcd.rpcuser=kek --btcd.rpcpass=kek --externalip=X.X.X.X
|
||||
```
|
||||
|
||||
#### Running lnd using the bitcoind backend
|
||||
#### Running lnd using the bitcoind or litecoind backend
|
||||
|
||||
To configure your bitcoind backend for use with lnd, first complete and verify the following:
|
||||
The configuration for bitcoind and litecoind are nearly identical, the following
|
||||
steps can be mirrored with loss of generality to enable a litecoind backend.
|
||||
Setup will be described in regards to `bitciond`, but note that `lnd` uses a
|
||||
distinct `litecoin.node=litecoind` argument and analogous subconfigurations
|
||||
prefixed by `litecoind`.
|
||||
|
||||
- The `bitcoind` instance must
|
||||
be configured with `--txindex` just like `btcd` above
|
||||
- Additionally, since `lnd` uses [ZeroMQ](https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md) to interface with `bitcoind`, *your `bitcoind` installation must be compiled with ZMQ*. If you installed it from source, this is likely the case, but if you installed it via Homebrew in the past it may not be included ([this has now been fixed](https://github.com/Homebrew/homebrew-core/pull/23088) in the latest Homebrew recipe for bitcoin)
|
||||
- Configure the `bitcoind` instance for ZMQ with `--zmqpubrawblock` and `--zmqpubrawtx`
|
||||
(the latter is optional but allows you to see unconfirmed transactions in your
|
||||
wallet). They must be combined in the same ZMQ socket address (e.g. `--zmqpubrawblock=tcp://127.0.0.1:28332` and `--zmqpubrawtx=tcp://127.0.0.1:28332`).
|
||||
- Start `bitcoind` running against testnet, and let it complete a full sync with the testnet chain (alternatively, use `--bitcoind.regtest` instead).
|
||||
To configure your bitcoind backend for use with lnd, first complete and verify
|
||||
the following:
|
||||
|
||||
- The `bitcoind` instance must be configured with `--txindex` just like `btcd`
|
||||
above
|
||||
- Additionally, since `lnd` uses
|
||||
[ZeroMQ](https://github.com/bitcoin/bitcoin/blob/master/doc/zmq.md) to
|
||||
interface with `bitcoind`, *your `bitcoind` installation must be compiled with
|
||||
ZMQ*. If you installed it from source, this is likely the case, but if you
|
||||
installed it via Homebrew in the past it may not be included ([this has now
|
||||
been fixed](https://github.com/Homebrew/homebrew-core/pull/23088) in the
|
||||
latest Homebrew recipe for bitcoin)
|
||||
- Configure the `bitcoind` instance for ZMQ with `--zmqpubrawblock` and
|
||||
`--zmqpubrawtx` (the latter is optional but allows you to see unconfirmed
|
||||
transactions in your wallet). They must be combined in the same ZMQ socket
|
||||
address (e.g. `--zmqpubrawblock=tcp://127.0.0.1:28332` and
|
||||
`--zmqpubrawtx=tcp://127.0.0.1:28332`).
|
||||
- Start `bitcoind` running against testnet, and let it complete a full sync with
|
||||
the testnet chain (alternatively, use `--bitcoind.regtest` instead).
|
||||
|
||||
Here's a sample `bitcoin.conf` for use with lnd:
|
||||
```
|
||||
@ -268,8 +284,8 @@ Notice the `[Bitcoin]` section. This section houses the parameters for the
|
||||
Bitcoin chain. `lnd` also supports Litecoin testnet4 (but not both BTC and LTC
|
||||
at the same time), so when working with Litecoin be sure to set to parameters
|
||||
for Litecoin accordingly. For node configuration, the sections are called
|
||||
`[Btcd]`, `[Bitcoind]`, `[Neutrino]`, and `[Ltcd]` depending on which chain
|
||||
and node type you're using.
|
||||
`[Btcd]`, `[Bitcoind]`, `[Neutrino]`, `[Ltcd]`, and `[Litecoind]` depending on
|
||||
which chain and node type you're using.
|
||||
|
||||
# Accurate as of:
|
||||
- _roasbeef/btcd commit:_ `f8c02aff4e7a807ba0c1349e2db03695d8e790e8`
|
||||
|
@ -42,12 +42,19 @@ const (
|
||||
// TODO(roasbeef): add command line param to modify
|
||||
maxFundingAmount = btcutil.Amount(1 << 24)
|
||||
|
||||
// minRemoteDelay and maxRemoteDelay is the extremes of the CSV delay
|
||||
// we will require the remote to use for its commitment transaction.
|
||||
// The actual delay we will require will be somewhere between these
|
||||
// values, depending on channel size.
|
||||
minRemoteDelay = 144
|
||||
maxRemoteDelay = 2016
|
||||
// minBtcRemoteDelay and maxBtcRemoteDelay is the extremes of the
|
||||
// Bitcoin CSV delay we will require the remote to use for its
|
||||
// commitment transaction. The actual delay we will require will be
|
||||
// somewhere between these values, depending on channel size.
|
||||
minBtcRemoteDelay uint16 = 144
|
||||
maxBtcRemoteDelay uint16 = 2016
|
||||
|
||||
// minLtcRemoteDelay and maxLtcRemoteDelay is the extremes of the
|
||||
// Litecoin CSV delay we will require the remote to use for its
|
||||
// commitment transaction. The actual delay we will require will be
|
||||
// somewhere between these values, depending on channel size.
|
||||
minLtcRemoteDelay uint16 = 576
|
||||
maxLtcRemoteDelay uint16 = 8064
|
||||
|
||||
// maxWaitNumBlocksFundingConf is the maximum number of blocks to wait
|
||||
// for the funding transaction to be confirmed before forgetting about
|
||||
|
@ -166,7 +166,7 @@ func createTestWallet(cdb *channeldb.DB, netParams *chaincfg.Params,
|
||||
ChainIO: bio,
|
||||
FeeEstimator: estimator,
|
||||
NetParams: *netParams,
|
||||
DefaultConstraints: defaultChannelConstraints,
|
||||
DefaultConstraints: defaultBtcChannelConstraints,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
17
lnd.go
17
lnd.go
@ -238,6 +238,17 @@ func lndMain() error {
|
||||
primaryChain := registeredChains.PrimaryChain()
|
||||
registeredChains.RegisterChain(primaryChain, activeChainControl)
|
||||
|
||||
// Select the configuration and furnding parameters for Bitcoin or
|
||||
// Litecoin, depending on the primary registered chain.
|
||||
chainCfg := cfg.Bitcoin
|
||||
minRemoteDelay := minBtcRemoteDelay
|
||||
maxRemoteDelay := maxBtcRemoteDelay
|
||||
if primaryChain == litecoinChain {
|
||||
chainCfg = cfg.Litecoin
|
||||
minRemoteDelay = minLtcRemoteDelay
|
||||
maxRemoteDelay = maxLtcRemoteDelay
|
||||
}
|
||||
|
||||
// TODO(roasbeef): add rotation
|
||||
idPrivKey, err := activeChainControl.wallet.DerivePrivKey(keychain.KeyDescriptor{
|
||||
KeyLocator: keychain.KeyLocator{
|
||||
@ -340,7 +351,7 @@ func lndMain() error {
|
||||
// In case the user has explicitly specified
|
||||
// a default value for the number of
|
||||
// confirmations, we use it.
|
||||
defaultConf := uint16(cfg.Bitcoin.DefaultNumChanConfs)
|
||||
defaultConf := uint16(chainCfg.DefaultNumChanConfs)
|
||||
if defaultConf != 0 {
|
||||
return defaultConf
|
||||
}
|
||||
@ -373,13 +384,13 @@ func lndMain() error {
|
||||
// In case the user has explicitly specified
|
||||
// a default value for the remote delay, we
|
||||
// use it.
|
||||
defaultDelay := uint16(cfg.Bitcoin.DefaultRemoteDelay)
|
||||
defaultDelay := uint16(chainCfg.DefaultRemoteDelay)
|
||||
if defaultDelay > 0 {
|
||||
return defaultDelay
|
||||
}
|
||||
|
||||
// If not we scale according to channel size.
|
||||
delay := uint16(maxRemoteDelay *
|
||||
delay := uint16(btcutil.Amount(maxRemoteDelay) *
|
||||
chanAmt / maxFundingAmount)
|
||||
if delay < minRemoteDelay {
|
||||
delay = minRemoteDelay
|
||||
|
@ -2095,6 +2095,9 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
|
||||
default:
|
||||
// TODO(roasbeef): assumes set delta between versions
|
||||
defaultDelta := cfg.Bitcoin.TimeLockDelta
|
||||
if registeredChains.PrimaryChain() == litecoinChain {
|
||||
defaultDelta = cfg.Litecoin.TimeLockDelta
|
||||
}
|
||||
options = append(options, zpay32.CLTVExpiry(uint64(defaultDelta)))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user