Skip to content

Commit

Permalink
👌 Applied suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
nagdahimanshu committed Jan 19, 2024
1 parent 6a8df0c commit 9ffb3a8
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 84 deletions.
132 changes: 72 additions & 60 deletions pkg/chain/chain_constants.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package chain

import "fmt"

// L2ChainIDs manages L2 network chainIDs.
type L2ChainIDs struct {
optimism uint64
Expand All @@ -13,6 +15,7 @@ type L2ChainIDs struct {
baseSepolia uint64
zoraGoerli uint64
zoraMainnet uint64
liskSepolia uint64
}

var l2NetworkChainIDs = L2ChainIDs{
Expand All @@ -27,96 +30,105 @@ var l2NetworkChainIDs = L2ChainIDs{
baseMainnet: 8453,
zoraGoerli: 999,
zoraMainnet: 7777777,
liskSepolia: 4202,
}

// L1Contracts returns L1 network contracts adresses.
type L1Contracts struct {
type NetworkType = string

const (
L1 = NetworkType("L1")
L2 = NetworkType("L2")
)

// Contracts has information of the L1 & L2 contracts addresses.
type Contracts struct {
stateCommitmentChain string
optimismPortal string
l2OutputOracle string
networkType NetworkType
}

// GetContractAddressesByChainID returns contract addresses by chainID.
func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts {
contractAddresses := map[uint64]map[string]L1Contracts{
func GetContractAddressesByChainID(chainID uint64) (Contracts, error) {
contractAddresses := map[uint64]Contracts{
l2NetworkChainIDs.optimism: {
"l1": {
stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19",
optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed",
l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27",
},
stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19",
optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed",
l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27",
networkType: L1,
},
l2NetworkChainIDs.optimismGoerli: {
"l1": {
stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378",
optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383",
l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0",
},
stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378",
optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383",
l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0",
networkType: L1,
},
l2NetworkChainIDs.optimismSepolia: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC",
l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC",
l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F",
networkType: L1,
},
l2NetworkChainIDs.optimismHardhatLocal: {
"l1": {
stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
optimismPortal: "0x0000000000000000000000000000000000000000",
l2OutputOracle: "0x0000000000000000000000000000000000000000",
},
stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
optimismPortal: "0x0000000000000000000000000000000000000000",
l2OutputOracle: "0x0000000000000000000000000000000000000000",
networkType: L1,
},
l2NetworkChainIDs.optimismHardhatDevnet: {
"l1": {
stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
optimismPortal: "0x0000000000000000000000000000000000000000",
l2OutputOracle: "0x0000000000000000000000000000000000000000",
},
stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
optimismPortal: "0x0000000000000000000000000000000000000000",
l2OutputOracle: "0x0000000000000000000000000000000000000000",
networkType: L1,
},
l2NetworkChainIDs.optimismBedrockAlphaTestnet: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8",
l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8",
l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6",
networkType: L1,
},
l2NetworkChainIDs.baseGoerli: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA",
l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA",
l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298",
networkType: L1,
},
l2NetworkChainIDs.baseSepolia: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85",
l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85",
l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254",
networkType: L1,
},
l2NetworkChainIDs.baseMainnet: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e",
l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e",
l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0",
networkType: L1,
},
l2NetworkChainIDs.zoraGoerli: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe",
l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe",
l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00",
networkType: L1,
},
l2NetworkChainIDs.zoraMainnet: {
"l1": {
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054",
l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c",
},
stateCommitmentChain: "0x0000000000000000000000000000000000000000",
optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054",
l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c",
networkType: L1,
},
l2NetworkChainIDs.liskSepolia: {
optimismPortal: "0xe3d90F21490686Ec7eF37BE788E02dfC12787264",
l2OutputOracle: "0xA0E35F56C318DE1bD5D9ca6A94Fe7e37C5663348",
networkType: L1,
},
}

return contractAddresses[chainID]
filteredContracts := contractAddresses[chainID]

if len(filteredContracts.l2OutputOracle) == 0 {
return filteredContracts, fmt.Errorf("contract information is unavailable for the chain %v", chainID)
}

return filteredContracts, nil
}
21 changes: 12 additions & 9 deletions pkg/chain/chain_constants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ import (

func TestGetContractAddressesByChainID_AvailableChainID(t *testing.T) {
const availableChainID uint64 = 10
contractAddresses := GetContractAddressesByChainID(availableChainID)
contractAddressesExpected := map[string]L1Contracts{
"l1": {
stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19",
optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed",
l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27",
}}
contractAddresses, err := GetContractAddressesByChainID(availableChainID)

contractAddressesExpected := Contracts{
stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19",
optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed",
l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27",
networkType: "L1",
}

assert.NoError(t, err)
assert.Equal(t, contractAddressesExpected, contractAddresses)
}

func TestGetContractAddressesByChainID_UnavailableChainID(t *testing.T) {
const unavailableChainID uint64 = 5
contractAddresses := GetContractAddressesByChainID(unavailableChainID)
contractAddresses, err := GetContractAddressesByChainID(unavailableChainID)

assert.Equal(t, 0, len(contractAddresses))
assert.Error(t, err)
assert.Equal(t, 0, len(contractAddresses.l2OutputOracle))
}
45 changes: 32 additions & 13 deletions pkg/chain/contracts.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package chain

import (
"context"
"fmt"
"math/big"

"github.com/LiskHQ/op-fault-detector/pkg/log"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
Expand All @@ -14,34 +15,52 @@ import (
// OracleAccessor binds oracle contract to an instance for querying data.
type OracleAccessor struct {
contractInstance *bindings.L2OutputOracle
log log.Logger
}

type ConfigOptions struct {
L1RPCEndpoint string
ChainID uint64
L2OutputOracleContractAddress string
}

// getL1OracleContractAddressByChainID returns L1 oracle contract address by chainID.
func getL1OracleContractAddressByChainID(chainID uint64) string {
ContractAddresses := GetContractAddressesByChainID(chainID)
address := ContractAddresses["l1"].l2OutputOracle
return address
func getL1OracleContractAddressByChainID(chainID uint64) (string, error) {
ContractAddresses, err := GetContractAddressesByChainID(chainID)
if err != nil {
return "", err
}

address := ContractAddresses.l2OutputOracle
return address, nil
}

// NewOracleContract returns [OracleAccessor] with contract instance.
func NewOracleContract(url string, chainID uint64, logger log.Logger) (*OracleAccessor, error) {
client, err := ethclient.Dial(url)

func NewOracleContract(ctx context.Context, opts ConfigOptions) (*OracleAccessor, error) {
client, err := ethclient.DialContext(ctx, opts.L1RPCEndpoint)
if err != nil {
return nil, err
}

oracleContractAddress := getL1OracleContractAddressByChainID(chainID)
contractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client)
oracleContractAddress, err := getL1OracleContractAddressByChainID(opts.ChainID)

// Verify if oracle contract address is available in the chain constants
// If not available, use l2OutputContractAddress from the config options
if err != nil {
if len(opts.L2OutputOracleContractAddress) > 0 {
oracleContractAddress = opts.L2OutputOracleContractAddress
} else {
return nil, fmt.Errorf("L2 output oracle contract address is not available")
}
}

oracleContractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client)

if err != nil {
return nil, err
}

return &OracleAccessor{
contractInstance: contractInstance,
log: logger,
contractInstance: oracleContractInstance,
}, nil
}

Expand Down
6 changes: 4 additions & 2 deletions pkg/chain/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import (

func TestGetL1OracleContractAddressByChainID_AvailableChainID(t *testing.T) {
const availableChainID uint64 = 10
var contractAddress = getL1OracleContractAddressByChainID(availableChainID)
var contractAddress, err = getL1OracleContractAddressByChainID(availableChainID)
var oracleContractAddressExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27"

assert.NoError(t, err)
assert.Equal(t, oracleContractAddressExpected, contractAddress)
}

func TestGetL1OracleContractAddressByChainID_UnavailableChainID(t *testing.T) {
const unavailableChainID uint64 = 5
contractAddress := getL1OracleContractAddressByChainID(unavailableChainID)
contractAddress, err := getL1OracleContractAddressByChainID(unavailableChainID)

assert.Error(t, err)
assert.Equal(t, 0, len(contractAddress))
}

0 comments on commit 9ffb3a8

Please sign in to comment.