Skip to content

Commit

Permalink
Ccip-3398 populate state initial PR (#14391)
Browse files Browse the repository at this point in the history
* initial draft

* individual snapshot

* change interface name

* changes

* add all destchainselectors

* rmn details

* more changes

* omitempty

* add onRamp reader

* changes

* format errors

* add Feequoter

* change approach direct go-binding reference

* fix import cycle

* moduler

* fix panic

* add interface for snapshot

* more changes

* rename

* fix lint

* more review comments

* fix rmnremote version

* one more fix

---------

Co-authored-by: Oliver Townsend <[email protected]>
  • Loading branch information
AnieeG and ogtownsend authored Sep 20, 2024
1 parent 10f7aab commit 674605e
Show file tree
Hide file tree
Showing 12 changed files with 579 additions and 98 deletions.
2 changes: 1 addition & 1 deletion integration-tests/deployment/ccip/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func DeployChainContracts(
chain.Selector,
)
return ContractDeploy[*rmn_remote.RMNRemote]{
rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0), err2,
rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_6_0_dev), err2,
}
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/deployment/ccip/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestDeployCCIPContracts(t *testing.T) {
require.NoError(t, err)
state, err := LoadOnchainState(e, ab)
require.NoError(t, err)
snap, err := state.Snapshot(e.AllChainSelectors())
snap, err := state.View(e.AllChainSelectors())
require.NoError(t, err)

// Assert expect every deployed address to be in the address book.
Expand Down
172 changes: 76 additions & 96 deletions integration-tests/deployment/ccip/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ import (

"github.com/smartcontractkit/chainlink/integration-tests/deployment"

owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_5"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_6"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/maybe_revert_message_receiver"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677"

owner_wrappers "github.com/smartcontractkit/ccip-owner-contracts/tools/gethwrappers"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
Expand All @@ -25,8 +33,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/aggregator_v3_interface"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677"
)

type CCIPChainState struct {
Expand Down Expand Up @@ -61,6 +67,58 @@ type CCIPChainState struct {
TestRouter *router.Router
}

func (c CCIPChainState) GenerateView() (view.ChainView, error) {
chainView := view.NewChain()
if c.Router != nil {
routerView, err := v1_2.GenerateRouterView(c.Router)
if err != nil {
return chainView, err
}
chainView.Router[c.Router.Address().Hex()] = routerView
}
if c.TokenAdminRegistry != nil {
taView, err := v1_5.GenerateTokenAdminRegistryView(c.TokenAdminRegistry)
if err != nil {
return chainView, err
}
chainView.TokenAdminRegistry[c.TokenAdminRegistry.Address().Hex()] = taView
}
if c.NonceManager != nil {
nmView, err := v1_6.GenerateNonceManagerView(c.NonceManager)
if err != nil {
return chainView, err
}
chainView.NonceManager[c.NonceManager.Address().Hex()] = nmView
}
if c.RMNRemote != nil {
rmnView, err := v1_6.GenerateRMNRemoteView(c.RMNRemote)
if err != nil {
return chainView, err
}
chainView.RMN[c.RMNRemote.Address().Hex()] = rmnView
}
if c.FeeQuoter != nil && c.Router != nil && c.TokenAdminRegistry != nil {
fqView, err := v1_6.GenerateFeeQuoterView(c.FeeQuoter, c.Router, c.TokenAdminRegistry)
if err != nil {
return chainView, err
}
chainView.FeeQuoter[c.FeeQuoter.Address().Hex()] = fqView
}

if c.OnRamp != nil && c.Router != nil && c.TokenAdminRegistry != nil {
onRampView, err := v1_6.GenerateOnRampView(
c.OnRamp,
c.Router,
c.TokenAdminRegistry,
)
if err != nil {
return chainView, err
}
chainView.OnRamp[c.OnRamp.Address().Hex()] = onRampView
}
return chainView, nil
}

// Onchain state always derivable from an address book.
// Offchain state always derivable from a list of nodeIds.
// Note can translate this into Go struct needed for MCMS/Docs/UI.
Expand All @@ -71,115 +129,37 @@ type CCIPOnChainState struct {
Chains map[uint64]CCIPChainState
}

type CCIPSnapShot struct {
Chains map[string]Chain `json:"chains"`
}

type Contract struct {
TypeAndVersion string `json:"typeAndVersion"`
Address common.Address `json:"address"`
}

type TokenAdminRegistryView struct {
Contract
Tokens []common.Address `json:"tokens"`
}

type NonceManagerView struct {
Contract
AuthorizedCallers []common.Address `json:"authorizedCallers"`
}

type Chain struct {
// TODO: this will have to be versioned for getting state during upgrades.
TokenAdminRegistry TokenAdminRegistryView `json:"tokenAdminRegistry"`
NonceManager NonceManagerView `json:"nonceManager"`
}

func (s CCIPOnChainState) Snapshot(chains []uint64) (CCIPSnapShot, error) {
snapshot := CCIPSnapShot{
Chains: make(map[string]Chain),
}
func (s CCIPOnChainState) View(chains []uint64) (view.CCIPView, error) {
ccipView := view.NewCCIPView()
for _, chainSelector := range chains {
// TODO: Need a utility for this
chainid, err := chainsel.ChainIdFromSelector(chainSelector)
if err != nil {
return snapshot, err
return ccipView, err
}
chainName, err := chainsel.NameFromChainId(chainid)
if err != nil {
return snapshot, err
return ccipView, err
}
if _, ok := s.Chains[chainSelector]; !ok {
return snapshot, fmt.Errorf("chain not supported %d", chainSelector)
return ccipView, fmt.Errorf("chain not supported %d", chainSelector)
}
var c Chain
ta := s.Chains[chainSelector].TokenAdminRegistry
if ta != nil {
tokens, err := ta.GetAllConfiguredTokens(nil, 0, 10)
if err != nil {
return snapshot, err
}
tv, err := ta.TypeAndVersion(nil)
if err != nil {
return snapshot, err
}
c.TokenAdminRegistry = TokenAdminRegistryView{
Contract: Contract{
TypeAndVersion: tv,
Address: ta.Address(),
},
Tokens: tokens,
}
}
nm := s.Chains[chainSelector].NonceManager
if nm != nil {
authorizedCallers, err := nm.GetAllAuthorizedCallers(nil)
if err != nil {
return snapshot, err
}
tv, err := nm.TypeAndVersion(nil)
if err != nil {
return snapshot, err
}
c.NonceManager = NonceManagerView{
Contract: Contract{
TypeAndVersion: tv,
Address: nm.Address(),
},
// TODO: these can be resolved using an address book
AuthorizedCallers: authorizedCallers,
}
}
if nm != nil {
authorizedCallers, err := nm.GetAllAuthorizedCallers(nil)
if err != nil {
return snapshot, err
}
tv, err := nm.TypeAndVersion(nil)
if err != nil {
return snapshot, err
}
c.NonceManager = NonceManagerView{
Contract: Contract{
TypeAndVersion: tv,
Address: nm.Address(),
},
// TODO: these can be resolved using an address book
AuthorizedCallers: authorizedCallers,
}
chainState := s.Chains[chainSelector]
chainView, err := chainState.GenerateView()
if err != nil {
return ccipView, err
}
snapshot.Chains[chainName] = c
ccipView.Chains[chainName] = chainView
}
return snapshot, nil
return ccipView, nil
}

func SnapshotState(e deployment.Environment, ab deployment.AddressBook) (CCIPSnapShot, error) {
func StateView(e deployment.Environment, ab deployment.AddressBook) (view.CCIPView, error) {
state, err := LoadOnchainState(e, ab)
if err != nil {
return CCIPSnapShot{}, err
return view.CCIPView{}, err
}
return state.Snapshot(e.AllChainSelectors())
return state.View(e.AllChainSelectors())
}

func LoadOnchainState(e deployment.Environment, ab deployment.AddressBook) (CCIPOnChainState, error) {
Expand Down Expand Up @@ -242,7 +222,7 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type
return state, err
}
state.ArmProxy = armProxy
case deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_0_0).String():
case deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_6_0_dev).String():
rmnRemote, err := rmn_remote.NewRMNRemote(common.HexToAddress(address), chain.Client)
if err != nil {
return state, err
Expand Down
27 changes: 27 additions & 0 deletions integration-tests/deployment/ccip/view/chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package view

import (
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_2"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_5"
"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/v1_6"
)

type ChainView struct {
TokenAdminRegistry map[string]v1_5.TokenAdminRegistryView `json:"tokenAdminRegistry,omitempty"`
FeeQuoter map[string]v1_6.FeeQuoterView `json:"feeQuoter,omitempty"`
NonceManager map[string]v1_6.NonceManagerView `json:"nonceManager,omitempty"`
Router map[string]v1_2.RouterView `json:"router,omitempty"`
RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"`
OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"`
}

func NewChain() ChainView {
return ChainView{
TokenAdminRegistry: make(map[string]v1_5.TokenAdminRegistryView),
NonceManager: make(map[string]v1_6.NonceManagerView),
Router: make(map[string]v1_2.RouterView),
RMN: make(map[string]v1_6.RMNRemoteView),
OnRamp: make(map[string]v1_6.OnRampView),
FeeQuoter: make(map[string]v1_6.FeeQuoterView),
}
}
11 changes: 11 additions & 0 deletions integration-tests/deployment/ccip/view/state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package view

type CCIPView struct {
Chains map[string]ChainView `json:"chains,omitempty"`
}

func NewCCIPView() CCIPView {
return CCIPView{
Chains: make(map[string]ChainView),
}
}
33 changes: 33 additions & 0 deletions integration-tests/deployment/ccip/view/types/contract_state.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package types

import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)

type ContractMetaData struct {
TypeAndVersion string `json:"typeAndVersion,omitempty"`
Address common.Address `json:"address,omitempty"`
Owner common.Address `json:"owner,omitempty"`
}

func NewContractMetaData(tv Meta, addr common.Address) (ContractMetaData, error) {
tvStr, err := tv.TypeAndVersion(nil)
if err != nil {
return ContractMetaData{}, err
}
owner, err := tv.Owner(nil)
if err != nil {
return ContractMetaData{}, err
}
return ContractMetaData{
TypeAndVersion: tvStr,
Address: addr,
Owner: owner,
}, nil
}

type Meta interface {
TypeAndVersion(opts *bind.CallOpts) (string, error)
Owner(opts *bind.CallOpts) (common.Address, error)
}
56 changes: 56 additions & 0 deletions integration-tests/deployment/ccip/view/v1_2/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package v1_2

import (
"fmt"

"github.com/ethereum/go-ethereum/common"

"github.com/smartcontractkit/chainlink/integration-tests/deployment/ccip/view/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"
)

type RouterView struct {
types.ContractMetaData
WrappedNative common.Address `json:"wrappedNative,omitempty"`
ARMProxy common.Address `json:"armProxy,omitempty"`
OnRamps map[uint64]common.Address `json:"onRamps,omitempty"` // Map of DestinationChainSelectors to OnRamp Addresses
OffRamps map[uint64]common.Address `json:"offRamps,omitempty"` // Map of SourceChainSelectors to a list of OffRamp Addresses
}

func GenerateRouterView(r *router.Router) (RouterView, error) {
meta, err := types.NewContractMetaData(r, r.Address())
if err != nil {
return RouterView{}, fmt.Errorf("view error to get router metadata: %w", err)
}
wrappedNative, err := r.GetWrappedNative(nil)
if err != nil {
return RouterView{}, fmt.Errorf("view error to get router wrapped native: %w", err)
}
armProxy, err := r.GetArmProxy(nil)
if err != nil {
return RouterView{}, fmt.Errorf("view error to get router arm proxy: %w", err)
}
onRamps := make(map[uint64]common.Address)
offRamps := make(map[uint64]common.Address)
offRampList, err := r.GetOffRamps(nil)
if err != nil {
return RouterView{}, fmt.Errorf("view error to get router offRamps: %w", err)
}
for _, offRamp := range offRampList {
offRamps[offRamp.SourceChainSelector] = offRamp.OffRamp
}
for selector := range offRamps {
onRamp, err := r.GetOnRamp(nil, selector)
if err != nil {
return RouterView{}, fmt.Errorf("view error to get router onRamp: %w", err)
}
onRamps[selector] = onRamp
}
return RouterView{
ContractMetaData: meta,
WrappedNative: wrappedNative,
ARMProxy: armProxy,
OnRamps: onRamps,
OffRamps: offRamps,
}, nil
}
Loading

0 comments on commit 674605e

Please sign in to comment.