Skip to content

Commit

Permalink
add solana and backwards compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
huangzhen1997 committed Nov 6, 2024
1 parent 28a3bb5 commit 392f8fb
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 16 deletions.
12 changes: 6 additions & 6 deletions evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
"gopkg.in/yaml.v3"
)

//go:generate go run genchains.go
//go:generate go run genchains_evm.go

//go:embed selectors.yml
var selectorsYml []byte

//go:embed test_selectors.yml
var testSelectorsYml []byte

type chainDetails struct {
type ChainDetails struct {
ChainSelector uint64 `yaml:"selector"`
ChainName string `yaml:"name"`
}
Expand All @@ -36,8 +36,8 @@ func init() {
}
}

func loadAllEVMSelectors() map[uint64]chainDetails {
output := make(map[uint64]chainDetails, len(evmSelectorsMap)+len(evmTestSelectorsMap))
func loadAllEVMSelectors() map[uint64]ChainDetails {
output := make(map[uint64]ChainDetails, len(evmSelectorsMap)+len(evmTestSelectorsMap))
for k, v := range evmSelectorsMap {
output[k] = v
}
Expand All @@ -47,9 +47,9 @@ func loadAllEVMSelectors() map[uint64]chainDetails {
return output
}

func parseYml(ymlFile []byte) map[uint64]chainDetails {
func parseYml(ymlFile []byte) map[uint64]ChainDetails {
type ymlData struct {
SelectorsByEvmChainId map[uint64]chainDetails `yaml:"selectors"`
SelectorsByEvmChainId map[uint64]ChainDetails `yaml:"selectors"`
}

var data ymlData
Expand Down
13 changes: 12 additions & 1 deletion evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package chain_selectors

import (
"math/rand"
"strconv"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -51,9 +52,10 @@ func TestAllChainSelectorsHaveFamilies(t *testing.T) {
for _, ch := range ALL {
family, err := GetSelectorFamily(ch.Selector)
require.NoError(t, err,
"Family not found for selector %d (chain id %d, name %s), please update selector_families.yml with the appropriate chain family for this chain",
"Family not found for selector %d (chain id %d, name %s), please update selector.yml with the appropriate chain family for this chain",
ch.Selector, ch.EvmChainID, ch.Name)
require.NotEmpty(t, family)
require.Equal(t, FamilyEVM, family)
}
}

Expand Down Expand Up @@ -224,3 +226,12 @@ func Test_IsEvm(t *testing.T) {
assert.False(t, isEvm)
})
}

func Test_EVMGetChainDetailsByChainIDAndFamily(t *testing.T) {
for k, v := range evmChainIdToChainSelector {
strChainID := strconv.FormatUint(k, 10)
details, err := GetChainDetailsByChainIDAndFamily(strChainID, FamilyEVM)
assert.NoError(t, err)
assert.Equal(t, v, details)
}
}
2 changes: 1 addition & 1 deletion genchains_evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
chain_selectors "github.com/smartcontractkit/chain-selectors"
)

const filename = "generated_chains.go"
const filename = "generated_chains_evm.go"

type chain struct {
EvmChainID uint64
Expand Down
113 changes: 113 additions & 0 deletions genchains_solana.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//go:build ignore

package main

import (
"bytes"
"fmt"
"go/format"
"html/template"
"os"
"sort"
"strconv"
"strings"
"unicode"

chain_selectors "github.com/smartcontractkit/chain-selectors"
)

const filename = "generated_chains_solana.go"

type chain struct {
ChainID string
Selector uint64
Name string
VarName string
}

var chainTemplate, _ = template.New("").Parse(`// Code generated by go generate please DO NOT EDIT
package chain_selectors
type SolanaChain struct {
ChainID string
Selector uint64
Name string
VarName string
}
var (
{{ range . }}
{{.VarName}} = SolanaChain{ChainID: "{{ .ChainID }}", Selector: {{ .Selector }}, Name: "{{ .Name }}"}{{ end }}
)
var SolanaALL = []SolanaChain{
{{ range . }}{{ .VarName }},
{{ end }}
}
`)

func main() {
src, err := genChainsSourceCode()
if err != nil {
panic(err)
}

formatted, err := format.Source([]byte(src))
if err != nil {
panic(err)
}

existingContent, err := os.ReadFile(filename)
if err != nil {
panic(err)
}

if string(existingContent) == string(formatted) {
fmt.Println("no changes detected")
return
}

err = os.WriteFile(filename, formatted, 0644)
if err != nil {
panic(err)
}
}

func genChainsSourceCode() (string, error) {
var wr = new(bytes.Buffer)
chains := make([]chain, 0)

for ChainID, chainSel := range chain_selectors.SolanaChainIdToChainSelector() {
name, err := chain_selectors.SolanaNameFromChainId(ChainID)
if err != nil {
return "", err
}

chains = append(chains, chain{
ChainID: ChainID,
Selector: chainSel,
Name: name,
VarName: toVarName(name, chainSel),
})
}

sort.Slice(chains, func(i, j int) bool { return chains[i].VarName < chains[j].VarName })
if err := chainTemplate.ExecuteTemplate(wr, "", chains); err != nil {
return "", err
}
return wr.String(), nil
}

func toVarName(name string, chainSel uint64) string {
const unnamed = "TEST"
x := strings.ReplaceAll(name, "-", "_")
x = strings.ToUpper(x)
if len(x) > 0 && unicode.IsDigit(rune(x[0])) {
x = unnamed + "_" + x
}
if len(x) == 0 {
x = unnamed + "_" + strconv.FormatUint(chainSel, 10)
}
return x
}
21 changes: 21 additions & 0 deletions generated_chains_solana.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 38 additions & 3 deletions selectors.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package chain_selectors

import "fmt"
import (
"fmt"
"strconv"
)

const (
FamilyEVM = "evm"
Expand All @@ -11,11 +14,43 @@ const (
)

func GetSelectorFamily(selector uint64) (string, error) {
if _, exist := evmChainIdToChainSelector[selector]; exist {
// check EVM
_, exist := evmChainsBySelector[selector]
if exist {
return FamilyEVM, nil
}
if _, exist := solanaChainIdBySelector[selector]; exist {

// check solana
_, exist = solanaChainIdBySelector[selector]
if exist {
return FamilySolana, nil
}

return "", fmt.Errorf("unknown chain selector %d", selector)
}

func GetChainDetailsByChainIDAndFamily(chainID string, family string) (ChainDetails, error) {
switch family {
case FamilyEVM:
evmChainId, err := strconv.ParseUint(chainID, 10, 64)
if err != nil {
return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family)
}

details, exist := evmChainIdToChainSelector[evmChainId]
if !exist {
return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family)
}

return details, nil
case FamilySolana:
details, exist := solanaSelectorsMap[chainID]
if !exist {
return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family)
}

return details, nil
default:
return ChainDetails{}, fmt.Errorf("family %s is not yet support", family)
}
}
26 changes: 24 additions & 2 deletions solana.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package chain_selectors

import (
_ "embed"
"fmt"

"gopkg.in/yaml.v3"
)

//go:generate go run genchains_solana.go

//go:embed selectors_solana.yml
var solanaSelectorsYml []byte

Expand All @@ -20,9 +23,9 @@ func init() {
}
}

func parseSolanaYml(ymlFile []byte) map[string]chainDetails {
func parseSolanaYml(ymlFile []byte) map[string]ChainDetails {
type ymlData struct {
SelectorsBySolanaChainId map[string]chainDetails `yaml:"selectors"`
SelectorsBySolanaChainId map[string]ChainDetails `yaml:"selectors"`
}

var data ymlData
Expand All @@ -32,3 +35,22 @@ func parseSolanaYml(ymlFile []byte) map[string]chainDetails {
}
return data.SelectorsBySolanaChainId
}

func SolanaChainIdToChainSelector() map[string]uint64 {
copyMap := make(map[string]uint64, len(solanaSelectorsMap))
for k, v := range solanaSelectorsMap {
copyMap[k] = v.ChainSelector
}
return copyMap
}

func SolanaNameFromChainId(chainId string) (string, error) {
details, exist := solanaSelectorsMap[chainId]
if !exist {
return "", fmt.Errorf("chain name not found for chain %v", chainId)
}
if details.ChainName == "" {
return chainId, nil
}
return details.ChainName, nil
}
Loading

0 comments on commit 392f8fb

Please sign in to comment.