Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use ChainInfo in authority to allow support chains dynamically #2380

Merged
merged 45 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
640aa3e
add combine list function
lumtis Jun 24, 2024
d642c10
remove unused functions and add combine default list method
lumtis Jun 24, 2024
0b852e8
use test package for chain_test
lumtis Jun 24, 2024
7881b53
use additional info parameter for methods
lumtis Jun 24, 2024
502261f
rename additional chains
lumtis Jun 24, 2024
7f83544
add GetChainList to authority interface
lumtis Jun 24, 2024
52ced26
iteration 1
lumtis Jun 24, 2024
a9af40d
Merge branch 'develop' into feat/read-chain-info
lumtis Jun 24, 2024
436bbe4
crosschain refactoring
lumtis Jun 25, 2024
59f28fe
fungible refacotring
lumtis Jun 25, 2024
384dd5f
lightclient refactoring
lumtis Jun 25, 2024
3dc2372
observer refactoring
lumtis Jun 25, 2024
ae4d0ff
add additional chain list in context
lumtis Jun 25, 2024
ebd7ae7
zetaclient modification
lumtis Jun 25, 2024
e1bec69
fix build error
lumtis Jun 25, 2024
48ac8f8
format
lumtis Jun 25, 2024
9c6b05b
changelog
lumtis Jun 25, 2024
746d09a
Merge branch 'develop' into feat/read-chain-info
lumtis Jun 25, 2024
b3ebf57
conflicts
lumtis Jun 26, 2024
65f6cbe
fix lint
lumtis Jun 26, 2024
672da05
test fixes 2
lumtis Jun 26, 2024
b373d17
observer test fix
lumtis Jun 26, 2024
4560118
zetaclient tests
lumtis Jun 26, 2024
0a6f256
fix test 2
lumtis Jun 26, 2024
994020a
add more tests
lumtis Jun 26, 2024
54dd10c
rename getChainList
lumtis Jun 26, 2024
30271ec
Merge branch 'develop' into feat/read-chain-info
lumtis Jun 26, 2024
075091f
add issues
lumtis Jun 26, 2024
bc9ff69
Merge branch 'develop' into feat/read-chain-info
lumtis Jun 26, 2024
4c4cccf
fix tests
lumtis Jun 26, 2024
0fd232f
Merge branch 'develop' into feat/read-chain-info
lumtis Jun 27, 2024
f842aa0
Update pkg/chains/chains.go
lumtis Jun 28, 2024
6e6b781
Update pkg/chains/chains.go
lumtis Jun 28, 2024
6adf45b
add TODO
lumtis Jun 28, 2024
1b07d96
Update x/authority/keeper/chain_info.go
lumtis Jun 28, 2024
adfd208
Update cmd/zetaclientd/debug.go
lumtis Jun 28, 2024
e935a3f
remove pointers in chains
lumtis Jun 28, 2024
54d6135
complete chain remove pointer
lumtis Jun 28, 2024
66e2b77
fix tests
lumtis Jun 28, 2024
a7af5d8
dmitry comments
lumtis Jun 28, 2024
52d5650
update comment
lumtis Jul 1, 2024
ab4ccf4
conflicts
lumtis Jul 2, 2024
c09b769
fix merge error
lumtis Jul 2, 2024
d066959
comments
lumtis Jul 2, 2024
bdc1b72
use nil
lumtis Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
* [2357](https://github.com/zeta-chain/node/pull/2357) - integrate base Signer structure into EVM/Bitcoin Signer
* [2359](https://github.com/zeta-chain/node/pull/2359) - integrate base Observer structure into EVM/Bitcoin Observer
* [2375](https://github.com/zeta-chain/node/pull/2375) - improve & speedup code formatting
* [2380](https://github.com/zeta-chain/node/pull/2380) - use `ChainInfo` in `authority` to allow dynamically support new chains
* [2395](https://github.com/zeta-chain/node/pull/2395) - converge AppContext with ZetaCoreContext in zetaclient

### Tests
Expand Down
16 changes: 8 additions & 8 deletions cmd/zetaclientd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,28 @@ func debugCmd(_ *cobra.Command, args []string) error {
if err != nil {
return err
}
chain := chains.GetChainFromChainID(chainID)
if chain == nil {
chain, found := chains.GetChainFromChainID(chainID, appContext.GetAdditionalChains())
if !found {
return fmt.Errorf("invalid chain id")
}

// get ballot identifier according to the chain type
if chains.IsEVMChain(chain.ChainId) {
if chains.IsEVMChain(chain.ChainId, appContext.GetAdditionalChains()) {
evmObserver := evmobserver.Observer{}
evmObserver.WithZetacoreClient(client)
var ethRPC *ethrpc.EthRPC
var client *ethclient.Client
coinType := coin.CoinType_Cmd
for chain, evmConfig := range cfg.GetAllEVMConfigs() {
if chainID == chain {
for chainIDFromConfig, evmConfig := range cfg.GetAllEVMConfigs() {
if chainIDFromConfig == chainID {
ethRPC = ethrpc.NewEthRPC(evmConfig.Endpoint)
client, err = ethclient.Dial(evmConfig.Endpoint)
if err != nil {
return err
}
evmObserver.WithEvmClient(client)
evmObserver.WithEvmJSONRPC(ethRPC)
evmObserver.WithChain(*chains.GetChainFromChainID(chainID))
evmObserver.WithChain(chain)
}
}
hash := ethcommon.HexToHash(inboundHash)
Expand Down Expand Up @@ -168,10 +168,10 @@ func debugCmd(_ *cobra.Command, args []string) error {
fmt.Println("CoinType not detected")
}
fmt.Println("CoinType : ", coinType)
} else if chains.IsBitcoinChain(chain.ChainId) {
} else if chains.IsBitcoinChain(chain.ChainId, appContext.GetAdditionalChains()) {
btcObserver := btcobserver.Observer{}
btcObserver.WithZetacoreClient(client)
btcObserver.WithChain(*chains.GetChainFromChainID(chainID))
btcObserver.WithChain(chain)
connCfg := &rpcclient.ConnConfig{
Host: cfg.BitcoinConfig.RPCHost,
User: cfg.BitcoinConfig.RPCUsername,
Expand Down
127 changes: 40 additions & 87 deletions pkg/chains/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@ import (
"strings"

"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcutil"
ethcommon "github.com/ethereum/go-ethereum/common"
)

type SigninAlgo string

// Chains represent a slice of Chain
type Chains []Chain

// Validate checks whether the chain is valid
// The function check the chain ID is positive and all enum fields have a defined value
func (chain Chain) Validate() error {
Expand Down Expand Up @@ -44,11 +38,6 @@ func (chain Chain) Validate() error {
return nil
}

// IsEqual compare two chain to see whether they represent the same chain
func (chain Chain) IsEqual(c Chain) bool {
return chain.ChainId == c.ChainId
}

// IsZetaChain returns true if the chain is a ZetaChain chain
func (chain Chain) IsZetaChain() bool {
return chain.Network == Network_zeta
Expand All @@ -63,13 +52,13 @@ func (chain Chain) IsExternalChain() bool {
// on EVM chain, it is 20Bytes
// on Bitcoin chain, it is P2WPKH address, []byte(bech32 encoded string)
func (chain Chain) EncodeAddress(b []byte) (string, error) {
if IsEVMChain(chain.ChainId) {
if chain.Consensus == Consensus_ethereum {
lumtis marked this conversation as resolved.
Show resolved Hide resolved
addr := ethcommon.BytesToAddress(b)
if addr == (ethcommon.Address{}) {
return "", fmt.Errorf("invalid EVM address")
}
return addr.Hex(), nil
} else if IsBitcoinChain(chain.ChainId) {
} else if chain.Consensus == Consensus_bitcoin {
addrStr := string(b)
chainParams, err := GetBTCChainParams(chain.ChainId)
if err != nil {
Expand All @@ -87,107 +76,75 @@ func (chain Chain) EncodeAddress(b []byte) (string, error) {
return "", fmt.Errorf("chain (%d) not supported", chain.ChainId)
}

func (chain Chain) BTCAddressFromWitnessProgram(witnessProgram []byte) (string, error) {
chainParams, err := GetBTCChainParams(chain.ChainId)
if err != nil {
return "", err
}
address, err := btcutil.NewAddressWitnessPubKeyHash(witnessProgram, chainParams)
if err != nil {
return "", err
}
return address.EncodeAddress(), nil
func (chain Chain) IsEVMChain() bool {
return chain.Consensus == Consensus_ethereum
}

// DecodeAddress decode the address string to bytes
func (chain Chain) DecodeAddress(addr string) ([]byte, error) {
return DecodeAddressFromChainID(chain.ChainId, addr)
func (chain Chain) IsBitcoinChain() bool {
return chain.Consensus == Consensus_bitcoin
}

// DecodeAddressFromChainID decode the address string to bytes
func DecodeAddressFromChainID(chainID int64, addr string) ([]byte, error) {
if IsEVMChain(chainID) {
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func DecodeAddressFromChainID(chainID int64, addr string, additionalChains []Chain) ([]byte, error) {
lumtis marked this conversation as resolved.
Show resolved Hide resolved
switch {
case IsEVMChain(chainID, additionalChains):
return ethcommon.HexToAddress(addr).Bytes(), nil
} else if IsBitcoinChain(chainID) {
case IsBitcoinChain(chainID, additionalChains):
return []byte(addr), nil
default:
return nil, fmt.Errorf("chain (%d) not supported", chainID)
}
return nil, fmt.Errorf("chain (%d) not supported", chainID)
}

// IsEVMChain returns true if the chain is an EVM chain or uses the ethereum consensus mechanism for block finality
func IsEVMChain(chainID int64) bool {
return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_ethereum))
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func IsEVMChain(chainID int64, additionalChains []Chain) bool {
lumtis marked this conversation as resolved.
Show resolved Hide resolved
return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_ethereum, additionalChains))
}

// IsBitcoinChain returns true if the chain is a Bitcoin-based chain or uses the bitcoin consensus mechanism for block finality
func IsBitcoinChain(chainID int64) bool {
return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_bitcoin))
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func IsBitcoinChain(chainID int64, additionalChains []Chain) bool {
return ChainIDInChainList(chainID, ChainListByConsensus(Consensus_bitcoin, additionalChains))
}

// IsEthereumChain returns true if the chain is an Ethereum chain
func IsEthereumChain(chainID int64) bool {
return ChainIDInChainList(chainID, ChainListByNetwork(Network_eth))
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func IsEthereumChain(chainID int64, additionalChains []Chain) bool {
return ChainIDInChainList(chainID, ChainListByNetwork(Network_eth, additionalChains))
}

// IsZetaChain returns true if the chain is a Zeta chain
func IsZetaChain(chainID int64) bool {
return ChainIDInChainList(chainID, ChainListByNetwork(Network_zeta))
}

// IsHeaderSupportedChain returns true if the chain's consensus supports block header-based verification
func IsHeaderSupportedChain(chainID int64) bool {
return ChainIDInChainList(chainID, ChainListForHeaderSupport())
}

// SupportMerkleProof returns true if the chain supports block header-based verification
func (chain Chain) SupportMerkleProof() bool {
return IsEVMChain(chain.ChainId) || IsBitcoinChain(chain.ChainId)
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func IsZetaChain(chainID int64, additionalChains []Chain) bool {
return ChainIDInChainList(chainID, ChainListByNetwork(Network_zeta, additionalChains))
}

// IsEmpty is to determinate whether the chain is empty
func (chain Chain) IsEmpty() bool {
return strings.TrimSpace(chain.String()) == ""
}

// Has check whether chain c is in the list
func (chains Chains) Has(c Chain) bool {
for _, ch := range chains {
if ch.IsEqual(c) {
return true
}
}
return false
}

// Distinct return a distinct set of chains, no duplicates
func (chains Chains) Distinct() Chains {
var newChains Chains
for _, chain := range chains {
if !newChains.Has(chain) {
newChains = append(newChains, chain)
}
}
return newChains
}

func (chains Chains) Strings() []string {
str := make([]string, len(chains))
for i, c := range chains {
str[i] = c.String()
}
return str
}

func GetChainFromChainID(chainID int64) *Chain {
chains := DefaultChainsList()
// GetChainFromChainID returns the chain from the chain ID
// additionalChains is a list of additional chains to search from
// in practice, it is used in the protocol to dynamically support new chains without doing an upgrade
func GetChainFromChainID(chainID int64, additionalChains []Chain) (Chain, bool) {
chains := CombineDefaultChainsList(additionalChains)
for _, chain := range chains {
if chainID == chain.ChainId {
return chain
return chain, true
}
}
return nil
return Chain{}, false
}

// GetBTCChainParams returns the bitcoin chain config params from the chain ID
func GetBTCChainParams(chainID int64) (*chaincfg.Params, error) {
switch chainID {
case 18444:
Expand All @@ -201,6 +158,7 @@ func GetBTCChainParams(chainID int64) (*chaincfg.Params, error) {
}
}

// GetBTCChainIDFromChainParams returns the bitcoin chain ID from the chain config params
func GetBTCChainIDFromChainParams(params *chaincfg.Params) (int64, error) {
switch params.Name {
case chaincfg.RegressionNetParams.Name:
Expand All @@ -214,13 +172,8 @@ func GetBTCChainIDFromChainParams(params *chaincfg.Params) (int64, error) {
}
}

// InChainList checks whether the chain is in the chain list
func (chain Chain) InChainList(chainList []*Chain) bool {
return ChainIDInChainList(chain.ChainId, chainList)
}

// ChainIDInChainList checks whether the chainID is in the chain list
func ChainIDInChainList(chainID int64, chainList []*Chain) bool {
func ChainIDInChainList(chainID int64, chainList []Chain) bool {
for _, c := range chainList {
if chainID == c.ChainId {
return true
Expand Down
Loading
Loading