Skip to content

Commit

Permalink
[NONEVM-864] Add aptos chain selector (#68)
Browse files Browse the repository at this point in the history
* Add aptos chain selectors
  • Loading branch information
jlaveracll authored Nov 8, 2024
1 parent 0492aa6 commit 9500e1e
Show file tree
Hide file tree
Showing 8 changed files with 304 additions and 2 deletions.
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

0 comments on commit 9500e1e

Please sign in to comment.