04d0e099cc
This commit adds a new agent to the codebase: the chainRegistry. In a multi-chain future, the chainRegistry will be the dispatch point capable of mapping cross-chain parameters, and a particular chain to the chainControl for that chain. The chainControl struct encompasses the 3 primary interfaces used within the daemon to register for events, and drive other workflows.
165 lines
4.3 KiB
Go
165 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
|
"github.com/lightningnetwork/lnd/lnwallet"
|
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
|
)
|
|
|
|
// chainCode is an enum-like structure for keeping track of the chains currently
|
|
// supported within lnd.
|
|
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.
|
|
type chainControl struct {
|
|
chainIO lnwallet.BlockChainIO
|
|
chainNotifier chainntnfs.ChainNotifier
|
|
|
|
wallet *lnwallet.LightningWallet
|
|
}
|
|
|
|
var (
|
|
// bitcoinGenesis is the genesis hash of Bitcoin's testnet chain.
|
|
bitcoinGenesis = chainhash.Hash([chainhash.HashSize]byte{
|
|
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
|
|
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
|
|
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
|
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
})
|
|
|
|
// litecoinGenesis is the genesis hash of Litecoin's testnet4 chain.
|
|
litecoinGenesis = chainhash.Hash([chainhash.HashSize]byte{
|
|
0xa0, 0x29, 0x3e, 0x4e, 0xeb, 0x3d, 0xa6, 0xe6,
|
|
0xf5, 0x6f, 0x81, 0xed, 0x59, 0x5f, 0x57, 0x88,
|
|
0x0d, 0x1a, 0x21, 0x56, 0x9e, 0x13, 0xee, 0xfd,
|
|
0xd9, 0x51, 0x28, 0x4b, 0x5a, 0x62, 0x66, 0x49,
|
|
})
|
|
|
|
// chainMap is a simple index that maps a chain's genesis hash to the
|
|
// chainCode enum for that chain.
|
|
chainMap = map[chainhash.Hash]chainCode{
|
|
bitcoinGenesis: bitcoinChain,
|
|
litecoinGenesis: litecoinChain,
|
|
}
|
|
|
|
// reverseChainMap is the inverse of the chainMap above: it maps the
|
|
// chain enum for a chain to its genesis hash.
|
|
reverseChainMap = map[chainCode]chainhash.Hash{
|
|
bitcoinChain: bitcoinGenesis,
|
|
litecoinChain: litecoinGenesis,
|
|
}
|
|
)
|
|
|
|
// chainRegistry keeps track of the current chains
|
|
type chainRegistry struct {
|
|
sync.RWMutex
|
|
|
|
activeChains map[chainCode]*chainControl
|
|
netParams map[chainCode]*bitcoinNetParams
|
|
|
|
primaryChain chainCode
|
|
}
|
|
|
|
// newChainRegistry creates a new chainRegistry.
|
|
func newChainRegistry() *chainRegistry {
|
|
return &chainRegistry{
|
|
activeChains: make(map[chainCode]*chainControl),
|
|
netParams: make(map[chainCode]*bitcoinNetParams),
|
|
}
|
|
}
|
|
|
|
// RegisterChain assigns an active chainControl instance to a target chain
|
|
// identified by its chainCode.
|
|
func (c *chainRegistry) RegisterChain(newChain chainCode, cc *chainControl) {
|
|
c.Lock()
|
|
c.activeChains[newChain] = cc
|
|
c.Unlock()
|
|
}
|
|
|
|
// LookupChain attempts to lookup an active chainControl instance for the
|
|
// target chain.
|
|
func (c *chainRegistry) LookupChain(targetChain chainCode) (*chainControl, bool) {
|
|
c.RLock()
|
|
cc, ok := c.activeChains[targetChain]
|
|
c.RUnlock()
|
|
return cc, ok
|
|
}
|
|
|
|
// LookupChainByHash attempts to look up an active chainControl which
|
|
// corresponds to the passed genesis hash.
|
|
func (c *chainRegistry) LookupChainByHash(chainHash chainhash.Hash) (*chainControl, bool) {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
|
|
targetChain, ok := chainMap[chainHash]
|
|
if !ok {
|
|
return nil, ok
|
|
}
|
|
|
|
cc, ok := c.activeChains[targetChain]
|
|
return cc, ok
|
|
}
|
|
|
|
// RegisterPrimaryChain sets a target chain as the "home chain" for lnd.
|
|
func (c *chainRegistry) RegisterPrimaryChain(cc chainCode) {
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
|
|
c.primaryChain = cc
|
|
}
|
|
|
|
// PrimaryChain returns the primary chain for this running lnd instance. The
|
|
// primary chain is considered the "home base" while the other registered
|
|
// chains are treated as secondary chains.
|
|
func (c *chainRegistry) PrimaryChain() chainCode {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
|
|
return c.primaryChain
|
|
}
|
|
|
|
// ActiveChains returns the total number of active chains.
|
|
func (c *chainRegistry) ActiveChains() []chainCode {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
|
|
chains := make([]chainCode, 0, len(c.activeChains))
|
|
for activeChain := range c.activeChains {
|
|
chains = append(chains, activeChain)
|
|
}
|
|
|
|
return chains
|
|
}
|
|
|
|
// NumActiveChains returns the total number of active chains.
|
|
func (c *chainRegistry) NumActiveChains() uint32 {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
|
|
return uint32(len(c.activeChains))
|
|
}
|