Skip to content

Commit

Permalink
Add NetworkByChainID function to return network and blockchain for re…
Browse files Browse the repository at this point in the history
…gistered ChainID (#460)

* Add NetworkByChainID function to return network and blockchain for registered ChainID
  • Loading branch information
olomix committed Feb 1, 2024
1 parent dbeb810 commit 56c19c5
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.19.2
go-version: 1.21.6
- uses: golangci/golangci-lint-action@v3
with:
version: v1.50.0
version: v1.55.2
6 changes: 3 additions & 3 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
strategy:
matrix:
containers:
- 1.17.13-bullseye
- 1.18.10-bullseye
- 1.19.5-bullseye
- 1.20.0-bullseye
- 1.19.13-bullseye
- 1.20.13-bullseye
- 1.21.6-bookworm
runs-on: ubuntu-20.04
container: golang:${{matrix.containers}}
steps:
Expand Down
74 changes: 55 additions & 19 deletions chain.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,36 @@
package core

import (
"errors"
"fmt"
"sync"

"github.com/iden3/go-iden3-core/v2/w3c"
)

// ChainID is alias for int32 that represents ChainID
type ChainID int32

// ChainIDs Object containing chain IDs for various blockchains and networks.
var chainIDs = map[string]ChainID{
"eth:main": 1,
"eth:goerli": 5,
"eth:sepolia": 11155111,
"polygon:main": 137,
"polygon:mumbai": 80001,
"zkevm:main": 1101,
"zkevm:test": 1442,
type chainIDKey struct {
blockchain Blockchain
networkID NetworkID
}

var ErrChainIDNotRegistered = errors.New("chainID is not registered")

var chainIDsLock sync.RWMutex

// chainIDs Object containing chain IDs for various blockchains and networks.
// It can be modified using RegisterChainID public function. So it is guarded
// by chainIDsLock mutex.
var chainIDs = map[chainIDKey]ChainID{
{Ethereum, Main}: 1,
{Ethereum, Goerli}: 5,
{Ethereum, Sepolia}: 11155111,
{Polygon, Main}: 137,
{Polygon, Mumbai}: 80001,
{ZkEVM, Main}: 1101,
{ZkEVM, Test}: 1442,
}

// ChainIDfromDID returns chain name from w3c.DID
Expand All @@ -38,25 +51,27 @@ func ChainIDfromDID(did w3c.DID) (ChainID, error) {
return 0, err
}

chainID, ok := chainIDs[fmt.Sprintf("%s:%s", blockchain, networkID)]
if !ok {
return 0, fmt.Errorf("chainID not found for %s:%s", blockchain, networkID)
}

return chainID, nil
return GetChainID(blockchain, networkID)
}

// RegisterChainID registers chainID for blockchain and network
func RegisterChainID(blockchain Blockchain, network NetworkID, chainID int) error {
k := fmt.Sprintf("%s:%s", blockchain, network)
chainIDsLock.Lock()
defer chainIDsLock.Unlock()

k := chainIDKey{
blockchain: blockchain,
networkID: network,
}
existingChainID, ok := chainIDs[k]
if ok && existingChainID == ChainID(chainID) {
return nil
}

for _, v := range chainIDs {
if v == ChainID(chainID) {
return fmt.Errorf(`can't register chain id %d for '%s' because it's already registered for another chain id`, chainID, k)
return fmt.Errorf(`can't register chain id %d for '%v:%v' because it's already registered for another chain id`,
chainID, k.blockchain, k.networkID)
}
}

Expand All @@ -67,10 +82,31 @@ func RegisterChainID(blockchain Blockchain, network NetworkID, chainID int) erro

// GetChainID returns chainID for blockchain and network
func GetChainID(blockchain Blockchain, network NetworkID) (ChainID, error) {
k := fmt.Sprintf("%s:%s", blockchain, network)
chainIDsLock.RLock()
defer chainIDsLock.RUnlock()

k := chainIDKey{
blockchain: blockchain,
networkID: network,
}
if _, ok := chainIDs[k]; !ok {
return 0, fmt.Errorf("chainID not registered for %s:%s", blockchain, network)
return 0, fmt.Errorf("%w for %s:%s", ErrChainIDNotRegistered, blockchain,
network)
}

return chainIDs[k], nil
}

// NetworkByChainID returns blockchain and networkID for registered chain ID.
// Or ErrChainIDNotRegistered error if chainID is not registered.
func NetworkByChainID(chainID ChainID) (Blockchain, NetworkID, error) {
chainIDsLock.RLock()
defer chainIDsLock.RUnlock()

for k, v := range chainIDs {
if v == chainID {
return k.blockchain, k.networkID, nil
}
}
return NoChain, NoNetwork, ErrChainIDNotRegistered
}
16 changes: 16 additions & 0 deletions chain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package core

import (
"testing"

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

func TestNetworkByChainID(t *testing.T) {
chainID, err := GetChainID(Ethereum, Main)
require.NoError(t, err)
blockchain, networkID, err := NetworkByChainID(chainID)
require.NoError(t, err)
require.Equal(t, Ethereum, blockchain)
require.Equal(t, Main, networkID)
}
4 changes: 2 additions & 2 deletions did_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,8 @@ func TestCustomDIDRegistration_Negative(t *testing.T) {
Network: Main,
NetworkFlag: 0b0001_0001,
},
opts: []RegistrationOptions{WithChainID(101), WithDIDMethodByte(0b10000000)},
err: "can't register chain id 101 for 'eth:main' because it's already registered for another chain id",
opts: []RegistrationOptions{WithChainID(137), WithDIDMethodByte(0b10000000)},
err: "can't register chain id 137 for 'eth:main' because it's already registered for another chain id",
},
{
Description: "register new network and chain with existing networkFlag for existing existing did method",
Expand Down

0 comments on commit 56c19c5

Please sign in to comment.