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

RMN home reader test #14789

Merged
merged 29 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
5 changes: 5 additions & 0 deletions .changeset/silver-pens-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#internal: Adding test for rmn home reader
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,36 @@ package integrationhelpers

import (
"context"
"crypto/ed25519"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
"sort"
"testing"
"time"

mapset "github.com/deckarep/golang-set/v2"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-ccip/pkg/consts"
ccipreader "github.com/smartcontractkit/chainlink-ccip/pkg/reader"
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/stretchr/testify/require"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
configsevm "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/headtracker"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest"
Expand Down Expand Up @@ -80,15 +87,16 @@ const (
)

type TestUniverse struct {
Transactor *bind.TransactOpts
Backend *backends.SimulatedBackend
CapReg *kcr.CapabilitiesRegistry
CCIPHome *ccip_home.CCIPHome
TestingT *testing.T
LogPoller logpoller.LogPoller
HeadTracker logpoller.HeadTracker
SimClient client.Client
HomeChainReader ccipreader.HomeChain
Transactor *bind.TransactOpts
Backend *backends.SimulatedBackend
CapReg *kcr.CapabilitiesRegistry
CCIPHome *ccip_home.CCIPHome
TestingT *testing.T
LogPoller logpoller.LogPoller
HeadTracker logpoller.HeadTracker
SimClient client.Client
HomeChainReader ccipreader.HomeChain
HomeContractReader types.ContractReader
}

func NewTestUniverse(ctx context.Context, t *testing.T, lggr logger.Logger) TestUniverse {
Expand Down Expand Up @@ -128,17 +136,19 @@ func NewTestUniverse(ctx context.Context, t *testing.T, lggr logger.Logger) Test
require.NoError(t, lp.Start(ctx))
t.Cleanup(func() { require.NoError(t, lp.Close()) })

hcr := NewHomeChainReader(t, lp, headTracker, cl, ccAddress)
cr := NewReader(t, lp, headTracker, cl, ccAddress, configsevm.HomeChainReaderConfigRaw)
hcr := NewHomeChainReader(t, cr, ccAddress)
return TestUniverse{
Transactor: transactor,
Backend: backend,
CapReg: capReg,
CCIPHome: cc,
TestingT: t,
SimClient: cl,
LogPoller: lp,
HeadTracker: headTracker,
HomeChainReader: hcr,
Transactor: transactor,
Backend: backend,
CapReg: capReg,
CCIPHome: cc,
TestingT: t,
SimClient: cl,
LogPoller: lp,
HeadTracker: headTracker,
HomeChainReader: hcr,
HomeContractReader: cr,
}
}

Expand Down Expand Up @@ -227,9 +237,7 @@ func (t *TestUniverse) AddCapability(p2pIDs [][32]byte) {
}
}

func NewHomeChainReader(t *testing.T, logPoller logpoller.LogPoller, headTracker logpoller.HeadTracker, client client.Client, ccAddress common.Address) ccipreader.HomeChain {
cr := NewReader(t, logPoller, headTracker, client, ccAddress, configsevm.HomeChainReaderConfigRaw)

func NewHomeChainReader(t *testing.T, cr types.ContractReader, ccAddress common.Address) ccipreader.HomeChain {
hcr := ccipreader.NewHomeChainReader(cr, logger.TestLogger(t), 50*time.Millisecond, types.BoundContract{
Address: ccAddress.String(),
Name: consts.ContractNameCCIPConfig,
Expand Down Expand Up @@ -365,3 +373,60 @@ func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg
},
}
}

func GenerateRMNHomeConfigs(
peerID string,
offchainPK string,
offchainCfg string,
chainSelector uint64,
minObservers uint64,
observerBitmap *big.Int) (rmn_home.RMNHomeStaticConfig, rmn_home.RMNHomeDynamicConfig) {
peerIDByte, _ := hex.DecodeString(peerID)
var peerIDBytes [32]byte
copy(peerIDBytes[:], peerIDByte)

offchainPublicKey, _ := hex.DecodeString(offchainPK)
0xnogo marked this conversation as resolved.
Show resolved Hide resolved
var offchainPublicKeyBytes [32]byte
copy(offchainPublicKeyBytes[:], offchainPublicKey)

staticConfig := rmn_home.RMNHomeStaticConfig{
Nodes: []rmn_home.RMNHomeNode{
{
PeerId: peerIDBytes,
OffchainPublicKey: offchainPublicKeyBytes,
},
},
OffchainConfig: []byte(offchainCfg),
}

dynamicConfig := rmn_home.RMNHomeDynamicConfig{
SourceChains: []rmn_home.RMNHomeSourceChain{
{
ChainSelector: chainSelector,
MinObservers: minObservers,
ObserverNodesBitmap: observerBitmap,
},
},
OffchainConfig: []byte(offchainCfg),
}
return staticConfig, dynamicConfig
}

func GenerateExpectedRMNHomeNodesInfo(staticConfig rmn_home.RMNHomeStaticConfig, chainID int) []ccipreader.HomeNodeInfo {
expectedCandidateNodesInfo := make([]ccipreader.HomeNodeInfo, 0)

supportedCandidateSourceChains := mapset.NewSet(cciptypes.ChainSelector(chainID))

var counter uint32
for _, n := range staticConfig.Nodes {
pk := ed25519.PublicKey(n.OffchainPublicKey[:])
expectedCandidateNodesInfo = append(expectedCandidateNodesInfo, ccipreader.HomeNodeInfo{
ID: ccipreader.NodeID(counter),
PeerID: n.PeerId,
SupportedSourceChains: supportedCandidateSourceChains,
OffchainPublicKey: &pk,
})
counter++
}
return expectedCandidateNodesInfo
}
172 changes: 172 additions & 0 deletions core/capabilities/ccip/ccip_integration_tests/rmn/rmn_home_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package rmn

import (
"bytes"
"math/big"
"slices"
"testing"
"time"

"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers"

"github.com/smartcontractkit/chainlink-ccip/pkg/consts"
"github.com/smartcontractkit/chainlink-common/pkg/types"

"github.com/stretchr/testify/require"

"github.com/ethereum/go-ethereum/accounts/abi/bind"

readerpkg "github.com/smartcontractkit/chainlink-ccip/pkg/reader"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home"
)

func TestRMNHomeReader_GetRMNNodesInfo(t *testing.T) {
ctx := testutils.Context(t)
lggr := logger.TestLogger(t)
uni := integrationhelpers.NewTestUniverse(ctx, t, lggr)
zeroBytes := [32]byte{0}

const (
chainID1 = 1
minObservers1 = 1
observerBitmap1 = 1

chainID2 = 2
minObservers2 = 0
observerBitmap2 = 1
)

//================================Deploy and configure RMNHome===============================
rmnHomeAddress, _, rmnHome, err := rmn_home.DeployRMNHome(uni.Transactor, uni.Backend)
require.NoError(t, err)
uni.Backend.Commit()

staticConfig, dynamicConfig := integrationhelpers.GenerateRMNHomeConfigs(
"PeerID1",
"DummyPublicKey1",
"This is a sample offchain configuration in the static config",
chainID1,
minObservers1,
big.NewInt(observerBitmap1),
)

_, err = rmnHome.SetCandidate(uni.Transactor, staticConfig, dynamicConfig, zeroBytes)
require.NoError(t, err)
uni.Backend.Commit()

configDigest, err := rmnHome.GetCandidateDigest(&bind.CallOpts{})
require.NoError(t, err)

_, err = rmnHome.PromoteCandidateAndRevokeActive(uni.Transactor, configDigest, zeroBytes)
require.NoError(t, err)
uni.Backend.Commit()

rmnHomeBoundContract := types.BoundContract{
Address: rmnHomeAddress.String(),
Name: consts.ContractNameRMNHome,
}

err = uni.HomeContractReader.Bind(testutils.Context(t), []types.BoundContract{rmnHomeBoundContract})
require.NoError(t, err)

rmnHomeReader := readerpkg.NewRMNHomePoller(uni.HomeContractReader, rmnHomeBoundContract, lggr, 1*time.Millisecond)
0xnogo marked this conversation as resolved.
Show resolved Hide resolved

err = rmnHomeReader.Start(testutils.Context(t))
require.NoError(t, err)

t.Cleanup(func() {
err1 := rmnHomeReader.Close()
require.NoError(t, err1)
})

//================================Test RMNHome Reader===============================
expectedNodesInfo := integrationhelpers.GenerateExpectedRMNHomeNodesInfo(staticConfig, chainID1)

require.Eventually(
t,
assertRMNHomeNodesInfo(t, rmnHomeReader, configDigest, expectedNodesInfo, nil),
5*time.Second,
1*time.Millisecond,
)

// Add a new candidate config
staticConfig2, dynamicConfig2 := integrationhelpers.GenerateRMNHomeConfigs(
"PeerID2",
"DummyPublicKey2",
"This is a sample offchain configuration in the static config 2",
chainID2,
minObservers2,
big.NewInt(observerBitmap2),
)

_, err = rmnHome.SetCandidate(uni.Transactor, staticConfig2, dynamicConfig2, zeroBytes)
require.NoError(t, err)
uni.Backend.Commit()

candidateConfigDigest, err := rmnHome.GetCandidateDigest(&bind.CallOpts{})
require.NoError(t, err)

expectedCandidateNodesInfo := integrationhelpers.GenerateExpectedRMNHomeNodesInfo(staticConfig2, chainID2)

require.Eventually(
t,
assertRMNHomeNodesInfo(t, rmnHomeReader, candidateConfigDigest, expectedCandidateNodesInfo, nil),
5*time.Second,
1*time.Millisecond,
0xnogo marked this conversation as resolved.
Show resolved Hide resolved
)

// Promote the candidate config
_, err = rmnHome.PromoteCandidateAndRevokeActive(uni.Transactor, candidateConfigDigest, configDigest)
require.NoError(t, err)
uni.Backend.Commit()

require.Eventually(
t,
assertRMNHomeNodesInfo(t, rmnHomeReader, candidateConfigDigest, expectedCandidateNodesInfo, &configDigest),
5*time.Second,
100*time.Millisecond,
)
}

func assertRMNHomeNodesInfo(
t *testing.T,
rmnHomeReader readerpkg.RMNHome,
configDigest [32]byte,
expectedNodesInfo []readerpkg.HomeNodeInfo,
prevConfigDigest *[32]byte,
) func() bool {
return func() bool {
nodesInfo, err := rmnHomeReader.GetRMNNodesInfo(configDigest)
if err != nil {
t.Logf("Error getting RMN nodes info: %v", err)
return false
}

equal := slices.EqualFunc(expectedNodesInfo, nodesInfo, func(a, b readerpkg.HomeNodeInfo) bool {
return a.ID == b.ID &&
a.PeerID == b.PeerID &&
bytes.Equal(*a.OffchainPublicKey, *b.OffchainPublicKey) &&
a.SupportedSourceChains.Equal(b.SupportedSourceChains)
})

if !equal {
t.Logf("Expected nodes info doesn't match actual nodes info")
t.Logf("Expected: %+v", expectedNodesInfo)
t.Logf("Actual: %+v", nodesInfo)
return false
}

if prevConfigDigest != nil {
isPrevConfigStillSet := rmnHomeReader.IsRMNHomeConfigDigestSet(*prevConfigDigest)
if isPrevConfigStillSet {
t.Logf("Previous config is still set")
return false
}
}

return true
}
}
2 changes: 1 addition & 1 deletion core/scripts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ require (
github.com/shirou/gopsutil/v3 v3.24.3 // indirect
github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect
github.com/smartcontractkit/chain-selectors v1.0.27 // indirect
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7 // indirect
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927 // indirect
github.com/smartcontractkit/chainlink-cosmos v0.5.1 // indirect
github.com/smartcontractkit/chainlink-data-streams v0.1.0 // indirect
github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions core/scripts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1072,8 +1072,8 @@ github.com/smartcontractkit/chain-selectors v1.0.27 h1:VE/ftX9Aae4gnw67yR1raKi+3
github.com/smartcontractkit/chain-selectors v1.0.27/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v0.8.0 h1:hFz2EHU06bkEfhcqhK8JdjKTWpDOr0XJ6xL9oELDoUg=
github.com/smartcontractkit/chainlink-automation v0.8.0/go.mod h1:ObdjDfgGIaiE48Bb3yYcx1CeGBm392WlEw92U83LlUA=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7 h1:aMG3BllvgeL/vsqkebuAhWoIWOnitKnN1VxibdzGnYo=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7/go.mod h1:H4BTXnZBhwRdsAFjqWZpB1/f3IZnuB/Ql7pXPmokzXg=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927 h1:IlLJGhS05lbB8DQHIVkGxnqUWV+D2KWEObD+eqAg6YY=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927/go.mod h1:lnuRhxDI2l8JxmoesWBRwhk2Fx1T6I571VZmGncNbW0=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2 h1:WERgv6CtOMVLCa0d1YhO3BrP94TwDT+QSVKvH5PZ5Xw=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko=
github.com/smartcontractkit/chainlink-cosmos v0.5.1 h1:2xeZWh+4/w7xalTdAu8jqgFuxZ291aYTEwZhlQEv/BY=
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ require (
github.com/shopspring/decimal v1.4.0
github.com/smartcontractkit/chain-selectors v1.0.27
github.com/smartcontractkit/chainlink-automation v0.8.0
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2
github.com/smartcontractkit/chainlink-cosmos v0.5.1
github.com/smartcontractkit/chainlink-data-streams v0.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1055,8 +1055,8 @@ github.com/smartcontractkit/chain-selectors v1.0.27 h1:VE/ftX9Aae4gnw67yR1raKi+3
github.com/smartcontractkit/chain-selectors v1.0.27/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v0.8.0 h1:hFz2EHU06bkEfhcqhK8JdjKTWpDOr0XJ6xL9oELDoUg=
github.com/smartcontractkit/chainlink-automation v0.8.0/go.mod h1:ObdjDfgGIaiE48Bb3yYcx1CeGBm392WlEw92U83LlUA=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7 h1:aMG3BllvgeL/vsqkebuAhWoIWOnitKnN1VxibdzGnYo=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7/go.mod h1:H4BTXnZBhwRdsAFjqWZpB1/f3IZnuB/Ql7pXPmokzXg=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927 h1:IlLJGhS05lbB8DQHIVkGxnqUWV+D2KWEObD+eqAg6YY=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927/go.mod h1:lnuRhxDI2l8JxmoesWBRwhk2Fx1T6I571VZmGncNbW0=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2 h1:WERgv6CtOMVLCa0d1YhO3BrP94TwDT+QSVKvH5PZ5Xw=
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2/go.mod h1:tsGgeEJc5SUSlfVGSX0wR0EkRU3pM58D6SKF97V68ko=
github.com/smartcontractkit/chainlink-cosmos v0.5.1 h1:2xeZWh+4/w7xalTdAu8jqgFuxZ291aYTEwZhlQEv/BY=
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ require (
github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86
github.com/smartcontractkit/chain-selectors v1.0.27
github.com/smartcontractkit/chainlink-automation v0.8.0
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241014104242-9227e5c976a7
github.com/smartcontractkit/chainlink-ccip v0.0.0-20241017101312-c4c6665a8927
github.com/smartcontractkit/chainlink-common v0.3.1-0.20241016173514-b7b7f6310ac2
github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.0
github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.11-0.20241011153842-b2804aed25b4
Expand Down
Loading
Loading