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

[NONEVM-864] Add aptos chain selector #68

Merged
merged 6 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
71 changes: 71 additions & 0 deletions aptos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package chain_selectors

import (
_ "embed"
"fmt"

"gopkg.in/yaml.v3"
)

//go:generate go run genchains_aptos.go

//go:embed selectors_aptos.yml
var aptosSelectorsYml []byte

var (
aptosSelectorsMap = parseAptosYml(aptosSelectorsYml)
aptosChainIdBySelector = make(map[uint64]uint64)
)

func init() {
for k, v := range aptosSelectorsMap {
aptosChainIdBySelector[v.ChainSelector] = k
}
}

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

var data ymlData
err := yaml.Unmarshal(ymlFile, &data)
if err != nil {
panic(err)
}

validateAptosChainID(data.SelectorsByAptosChainId)
return data.SelectorsByAptosChainId
}

func validateAptosChainID(data map[uint64]ChainDetails) {
// TODO: https://smartcontract-it.atlassian.net/browse/NONEVM-890
}

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

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

func AptosChainIdFromSelector(selector uint64) (uint64, error) {
chainId, exist := aptosChainIdBySelector[selector]
if !exist {
return 0, fmt.Errorf("chain id not found for selector %d", selector)
}

return chainId, nil
}
71 changes: 71 additions & 0 deletions aptos_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package chain_selectors

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_AptosYmlAreValid(t *testing.T) {
tests := []struct {
name string
chainSelector uint64
chainsId uint64
expectErr bool
}{
{
name: "aptos-mainnet",
chainSelector: 124615329519749607,
chainsId: 1,
expectErr: false,
},
{
name: "aptos-testnet",
chainSelector: 6302590918974934319,
chainsId: 2,
expectErr: false,
},
{
name: "non-existing",
chainSelector: 81923186267,
chainsId: 471,
expectErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
name, err1 := AptosNameFromChainId(test.chainsId)
if test.expectErr {
require.Error(t, err1)
return
}
require.NoError(t, err1)
assert.Equal(t, test.name, name)
})
}
}

func Test_AptosChainSelectors(t *testing.T) {
for selector, chainId := range aptosChainIdBySelector {
family, err := GetSelectorFamily(selector)
require.NoError(t, err,
"selector %v should be returned as aptos family, but received %v",
selector, err)
require.NotEmpty(t, family)
require.Equal(t, FamilyAptos, family)

id, err := AptosChainIdFromSelector(selector)
require.Nil(t, err)
require.Equal(t, chainId, id)
}
}

func Test_AptosGetChainDetailsByChainIDAndFamily(t *testing.T) {
for k, v := range aptosSelectorsMap {
details, err := GetChainDetailsByChainIDAndFamily(fmt.Sprint(k), FamilyAptos)
assert.NoError(t, err)
assert.Equal(t, v, details)
}
}
114 changes: 114 additions & 0 deletions genchains_aptos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//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_aptos.go"

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

var chainTemplate, _ = template.New("").Parse(`// Code generated by go generate please DO NOT EDIT
package chain_selectors

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

var (
{{ range . }}
{{.VarName}} = AptosChain{ChainID: {{ .ChainID }}, Selector: {{ .Selector }}, Name: "{{ .Name }}"}{{ end }}
)

var AptosALL = []AptosChain{
{{ 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("aptos: no changes detected")
return
}
fmt.Println("aptos: updating generations")

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.AptosChainIdToChainSelector() {
name, err := chain_selectors.AptosNameFromChainId(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
}
3 changes: 2 additions & 1 deletion genchains_evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ func main() {
}

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

err = os.WriteFile(filename, formatted, 0644)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion genchains_solana.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ func main() {
}

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

err = os.WriteFile(filename, formatted, 0644)
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions generated_chains_aptos.go

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

18 changes: 18 additions & 0 deletions selectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ func GetSelectorFamily(selector uint64) (string, error) {
return FamilySolana, nil
}

// check aptos
_, exist = aptosChainIdBySelector[selector]
if exist {
return FamilyAptos, nil
}

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

Expand All @@ -49,6 +55,18 @@ func GetChainDetailsByChainIDAndFamily(chainID string, family string) (ChainDeta
return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family)
}

return details, nil
case FamilyAptos:
aptosChainId, err := strconv.ParseUint(chainID, 10, 64)
if err != nil {
return ChainDetails{}, fmt.Errorf("invalid chain id %s for %s", chainID, family)
}

details, exist := aptosSelectorsMap[aptosChainId]
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)
Expand Down
7 changes: 7 additions & 0 deletions selectors_aptos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
selectors:
1:
name: aptos-mainnet
selector: 4741433654826277614
2:
name: aptos-testnet
selector: 743186221051783445
Loading