multi: add nochainbackend option
This commit is contained in:
4 files changed
+236
-1
No files matched your search
@@ -690,6 +690,22 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "nochainbackend":
|
||||||
|
backend := &NoChainBackend{}
|
||||||
|
source := &NoChainSource{
|
||||||
|
BestBlockTime: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
cc.ChainNotifier = backend
|
||||||
|
cc.ChainView = backend
|
||||||
|
cc.FeeEstimator = backend
|
||||||
|
|
||||||
|
cc.ChainSource = source
|
||||||
|
cc.HealthCheck = func() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, nil, fmt.Errorf("unknown node type: %s",
|
return nil, nil, fmt.Errorf("unknown node type: %s",
|
||||||
homeChainConfig.Node)
|
homeChainConfig.Node)
|
||||||
|
|||||||
@@ -0,0 +1,215 @@
|
|||||||
|
package chainreg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
"github.com/btcsuite/btcutil"
|
||||||
|
"github.com/btcsuite/btcwallet/chain"
|
||||||
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||||
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
|
"github.com/lightningnetwork/lnd/routing/chainview"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// defaultFee is the fee that is returned by NoChainBackend.
|
||||||
|
defaultFee = chainfee.FeePerKwFloor
|
||||||
|
|
||||||
|
// noChainBackendName is the backend name returned by NoChainBackend.
|
||||||
|
noChainBackendName = "nochainbackend"
|
||||||
|
|
||||||
|
// errNotImplemented is the error that is returned by NoChainBackend for
|
||||||
|
// any operation that is not supported by it. Such paths should in
|
||||||
|
// practice never been hit, so seeing this error either means a remote
|
||||||
|
// signing instance was used for an unsupported purpose or a previously
|
||||||
|
// forgotten edge case path was hit.
|
||||||
|
errNotImplemented = errors.New("not implemented in nochainbackend " +
|
||||||
|
"mode")
|
||||||
|
|
||||||
|
// noChainBackendBestHash is the chain hash of the chain tip that is
|
||||||
|
// returned by NoChainBackend.
|
||||||
|
noChainBackendBestHash = &chainhash.Hash{0x01}
|
||||||
|
|
||||||
|
// noChainBackendBestHeight is the best height that is returned by
|
||||||
|
// NoChainBackend.
|
||||||
|
noChainBackendBestHeight int32 = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoChainBackend is a mock implementation of the following interfaces:
|
||||||
|
// - chainview.FilteredChainView
|
||||||
|
// - chainntnfs.ChainNotifier
|
||||||
|
// - chainfee.Estimator
|
||||||
|
type NoChainBackend struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) EstimateFeePerKW(uint32) (chainfee.SatPerKWeight,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
return defaultFee, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) RelayFeePerKW() chainfee.SatPerKWeight {
|
||||||
|
return defaultFee
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) RegisterConfirmationsNtfn(*chainhash.Hash, []byte,
|
||||||
|
uint32, uint32) (*chainntnfs.ConfirmationEvent, error) {
|
||||||
|
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) RegisterSpendNtfn(*wire.OutPoint, []byte,
|
||||||
|
uint32) (*chainntnfs.SpendEvent, error) {
|
||||||
|
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) RegisterBlockEpochNtfn(
|
||||||
|
*chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
|
||||||
|
|
||||||
|
epochChan := make(chan *chainntnfs.BlockEpoch)
|
||||||
|
return &chainntnfs.BlockEpochEvent{
|
||||||
|
Epochs: epochChan,
|
||||||
|
Cancel: func() {
|
||||||
|
close(epochChan)
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) Started() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) FilteredBlocks() <-chan *chainview.FilteredBlock {
|
||||||
|
return make(chan *chainview.FilteredBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) DisconnectedBlocks() <-chan *chainview.FilteredBlock {
|
||||||
|
return make(chan *chainview.FilteredBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) UpdateFilter([]channeldb.EdgePoint, uint32) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) FilterBlock(*chainhash.Hash) (*chainview.FilteredBlock,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) Start() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainBackend) Stop() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ chainview.FilteredChainView = (*NoChainBackend)(nil)
|
||||||
|
var _ chainntnfs.ChainNotifier = (*NoChainBackend)(nil)
|
||||||
|
var _ chainfee.Estimator = (*NoChainBackend)(nil)
|
||||||
|
|
||||||
|
// NoChainSource is a mock implementation of chain.Interface.
|
||||||
|
// The mock is designed to return static values where necessary to make any
|
||||||
|
// caller believe the chain is fully synced to virtual block height 1 (hash
|
||||||
|
// 0x0000..0001). That should avoid calls to other methods completely since they
|
||||||
|
// are only used for advancing the chain forward.
|
||||||
|
type NoChainSource struct {
|
||||||
|
notifChan chan interface{}
|
||||||
|
|
||||||
|
BestBlockTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) Start() error {
|
||||||
|
n.notifChan = make(chan interface{})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
n.notifChan <- &chain.RescanFinished{
|
||||||
|
Hash: noChainBackendBestHash,
|
||||||
|
Height: noChainBackendBestHeight,
|
||||||
|
Time: n.BestBlockTime,
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) Stop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) WaitForShutdown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) GetBestBlock() (*chainhash.Hash, int32, error) {
|
||||||
|
return noChainBackendBestHash, noChainBackendBestHeight, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) GetBlock(*chainhash.Hash) (*wire.MsgBlock, error) {
|
||||||
|
return &wire.MsgBlock{
|
||||||
|
Header: wire.BlockHeader{
|
||||||
|
Timestamp: n.BestBlockTime,
|
||||||
|
},
|
||||||
|
Transactions: []*wire.MsgTx{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) GetBlockHash(int64) (*chainhash.Hash, error) {
|
||||||
|
return noChainBackendBestHash, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) GetBlockHeader(*chainhash.Hash) (*wire.BlockHeader,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
return &wire.BlockHeader{
|
||||||
|
Timestamp: n.BestBlockTime,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) IsCurrent() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) FilterBlocks(
|
||||||
|
*chain.FilterBlocksRequest) (*chain.FilterBlocksResponse, error) {
|
||||||
|
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) BlockStamp() (*waddrmgr.BlockStamp, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) SendRawTransaction(*wire.MsgTx, bool) (*chainhash.Hash,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) Rescan(*chainhash.Hash, []btcutil.Address,
|
||||||
|
map[wire.OutPoint]btcutil.Address) error {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) NotifyReceived([]btcutil.Address) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) NotifyBlocks() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) Notifications() <-chan interface{} {
|
||||||
|
return n.notifChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoChainSource) BackEnd() string {
|
||||||
|
return noChainBackendName
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ chain.Interface = (*NoChainSource)(nil)
|
||||||
@@ -1230,6 +1230,10 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
|
|||||||
case "neutrino":
|
case "neutrino":
|
||||||
// No need to get RPC parameters.
|
// No need to get RPC parameters.
|
||||||
|
|
||||||
|
case "nochainbackend":
|
||||||
|
// Nothing to configure, we're running without any chain
|
||||||
|
// backend whatsoever (pure signing mode).
|
||||||
|
|
||||||
default:
|
default:
|
||||||
str := "only btcd, bitcoind, and neutrino mode " +
|
str := "only btcd, bitcoind, and neutrino mode " +
|
||||||
"supported for bitcoin at this time"
|
"supported for bitcoin at this time"
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ type Chain struct {
|
|||||||
Active bool `long:"active" description:"If the chain should be active or not."`
|
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."`
|
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" choice:"ltcd" choice:"litecoind"`
|
Node string `long:"node" description:"The blockchain interface to use." choice:"btcd" choice:"bitcoind" choice:"neutrino" choice:"ltcd" choice:"litecoind" choice:"nochainbackend"`
|
||||||
|
|
||||||
MainNet bool `long:"mainnet" description:"Use the main network"`
|
MainNet bool `long:"mainnet" description:"Use the main network"`
|
||||||
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
||||||
|
|||||||
Reference in new issue
Block a user