Skip to content

Commit

Permalink
various fixes
Browse files Browse the repository at this point in the history
* run make gomodtidy
* add GenericDataWordNames to the contract reader
configs.
* use our keyring instead of the one from ocrcommon.
* fix inprocess_test
* set offramp ocr configs
* restructure test slightly
* replay log poller in test
  • Loading branch information
makramkd committed Jul 16, 2024
1 parent e0d3a37 commit 78e622e
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 62 deletions.
6 changes: 1 addition & 5 deletions core/scripts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1097,11 +1097,7 @@ github.com/smartcontractkit/chain-selectors v1.0.18 h1:ackCMDOlWuwULAyBNj9fQeQme
github.com/smartcontractkit/chain-selectors v1.0.18/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716103219-8ce5cf3daa0e h1:+nxnYA9VSU12zHjPxgBpcJhUK3IsJb2L3BMxWY7ZbXI=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716103219-8ce5cf3daa0e/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716113537-c4ab63b630d9/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716125744-c4748dc93ff3/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716131321-c210e1f71bb3/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716140948-e39aca330d3a h1:O1FCLgYwBTn4ArTQUZQ752ETrG6qMJDaSX6XLC+4H8Q=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716140948-e39aca330d3a/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-common v0.1.7-0.20240708180634-24440372521a h1:0HUP3qmHejg7FyFdY+R+8iFg0kNtrvnAxaQ//+fuZfc=
github.com/smartcontractkit/chainlink-common v0.1.7-0.20240708180634-24440372521a/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
Expand Down
5 changes: 5 additions & 0 deletions core/services/ccipcapability/configs/evm/contract_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ func SourceReaderConfig() evmrelaytypes.ChainReaderConfig {
consts.EventNameCCIPSendRequested: {
ChainSpecificName: mustGetEventName(consts.EventNameCCIPSendRequested, onrampABI),
ReadType: evmrelaytypes.Event,
EventDefinitions: &evmrelaytypes.EventDefinitions{
GenericDataWordNames: map[string]uint8{
consts.EventAttributeSequenceNumber: 5,
},
},
},
},
},
Expand Down
18 changes: 9 additions & 9 deletions core/services/ccipcapability/ocrimpls/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,35 @@ package ocrimpls

import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/smartcontractkit/libocr/offchainreporting2/types"
"github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3types"
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"

"github.com/smartcontractkit/chainlink/v2/core/logger"
)

var _ ocr3types.OnchainKeyring[[]byte] = &oc3Keyring[[]byte]{}
var _ ocr3types.OnchainKeyring[[]byte] = &ocr3Keyring[[]byte]{}

type oc3Keyring[RI any] struct {
type ocr3Keyring[RI any] struct {
core types.OnchainKeyring
lggr logger.Logger
}

func NewOnchainKeyring[RI any](keyring types.OnchainKeyring, lggr logger.Logger) *oc3Keyring[RI] {
return &oc3Keyring[RI]{
func NewOnchainKeyring[RI any](keyring types.OnchainKeyring, lggr logger.Logger) *ocr3Keyring[RI] {
return &ocr3Keyring[RI]{
core: keyring,
lggr: lggr.Named("OCR3Keyring"),
}
}

func (w *oc3Keyring[RI]) PublicKey() types.OnchainPublicKey {
func (w *ocr3Keyring[RI]) PublicKey() types.OnchainPublicKey {
return w.core.PublicKey()
}

func (w *oc3Keyring[RI]) MaxSignatureLength() int {
func (w *ocr3Keyring[RI]) MaxSignatureLength() int {
return w.core.MaxSignatureLength()
}

func (w *oc3Keyring[RI]) Sign(configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI]) (signature []byte, err error) {
func (w *ocr3Keyring[RI]) Sign(configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI]) (signature []byte, err error) {
epoch, round := uint64ToUint32AndUint8(seqNr)
rCtx := types.ReportContext{
ReportTimestamp: types.ReportTimestamp{
Expand All @@ -45,7 +45,7 @@ func (w *oc3Keyring[RI]) Sign(configDigest types.ConfigDigest, seqNr uint64, r o
return w.core.Sign(rCtx, r.Report)
}

func (w *oc3Keyring[RI]) Verify(key types.OnchainPublicKey, configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI], signature []byte) bool {
func (w *ocr3Keyring[RI]) Verify(key types.OnchainPublicKey, configDigest types.ConfigDigest, seqNr uint64, r ocr3types.ReportWithInfo[RI], signature []byte) bool {
epoch, round := uint64ToUint32AndUint8(seqNr)
rCtx := types.ReportContext{
ReportTimestamp: types.ReportTimestamp{
Expand Down
2 changes: 1 addition & 1 deletion core/services/ccipcapability/oraclecreator/inprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func (i *inprocessOracleCreator) CreatePluginOracle(pluginType cctypes.PluginTyp
if !ok {
return nil, fmt.Errorf("no OCR key bundle found for chain family %s, forgot to create one?", destChainFamily)
}
onchainKeyring := ocrcommon.NewOCR3OnchainKeyringAdapter(keybundle)
onchainKeyring := ocrimpls.NewOnchainKeyring[[]byte](keybundle, i.lggr)

// build the contract transmitter
// assume that we are using the first account in the keybundle as the from account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func TestOracleCreator_CreateBootstrap(t *testing.T) {
logger.TestLogger(t),
&mockEndpointGen{},
[]commontypes.BootstrapperLocator{},
nil,
)

chainSelector := chainsel.GETH_TESTNET.Selector
Expand Down
79 changes: 77 additions & 2 deletions core/services/ocr3/plugins/ccip_integration_tests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func (h *homeChain) AddDON(
t *testing.T,
ccipCapabilityID [32]byte,
chainSelector uint64,
OfframpAddress []byte,
uni onchainUniverse,
f uint8,
bootstrapP2PID [32]byte,
p2pIDs [][32]byte,
Expand Down Expand Up @@ -396,7 +396,7 @@ func (h *homeChain) AddDON(
ChainSelector: chainSelector,
F: f,
OffchainConfigVersion: offchainConfigVersion,
OfframpAddress: OfframpAddress,
OfframpAddress: uni.offramp.Address().Bytes(),
BootstrapP2PIds: [][32]byte{bootstrapP2PID},
P2pIds: p2pIDs,
Signers: signersBytes,
Expand All @@ -411,6 +411,9 @@ func (h *homeChain) AddDON(
// Trim first four bytes to remove function selector.
encodedConfigs := encodedCall[4:]

// commit so that we have an empty block to filter events from
h.backend.Commit()

_, err = h.capabilityRegistry.AddDON(h.owner, p2pIDs, []kcr.CapabilitiesRegistryCapabilityConfiguration{
{
CapabilityId: ccipCapabilityID,
Expand All @@ -419,6 +422,70 @@ func (h *homeChain) AddDON(
}, false, false, f)
require.NoError(t, err)
h.backend.Commit()

endBlock := h.backend.Blockchain().CurrentBlock().Number.Uint64()
iter, err := h.capabilityRegistry.FilterConfigSet(&bind.FilterOpts{
Start: h.backend.Blockchain().CurrentBlock().Number.Uint64() - 1,
End: &endBlock,
})
require.NoError(t, err, "failed to filter config set events")
var donID uint32
for iter.Next() {
donID = iter.Event.DonId
break
}
require.NotZero(t, donID, "failed to get donID from config set event")

var signerAddresses []common.Address
for _, signer := range signers {
signerAddresses = append(signerAddresses, common.BytesToAddress(signer))
}

var transmitterAddresses []common.Address
for _, transmitter := range transmitters {
transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(transmitter)))
}

// get the config digest from the ccip config contract and set config on the offramp.
var offrampOCR3Configs []evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs
for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} {
ocrConfig, err := h.ccipConfig.GetOCRConfig(&bind.CallOpts{

Check failure on line 452 in core/services/ocr3/plugins/ccip_integration_tests/helpers.go

View workflow job for this annotation

GitHub Actions / lint

shadow: declaration of "err" shadows declaration at line 355 (govet)
Context: testutils.Context(t),
}, donID, uint8(pluginType))
require.NoError(t, err, "failed to get OCR3 config from ccip config contract")
require.Len(t, ocrConfig, 1, "expected exactly one OCR3 config")
offrampOCR3Configs = append(offrampOCR3Configs, evm_2_evm_multi_offramp.MultiOCR3BaseOCRConfigArgs{
ConfigDigest: ocrConfig[0].ConfigDigest,
OcrPluginType: uint8(pluginType),
F: f,
IsSignatureVerificationEnabled: pluginType == cctypes.PluginTypeCCIPCommit,
Signers: signerAddresses,
Transmitters: transmitterAddresses,
})
}

uni.backend.Commit()

_, err = uni.offramp.SetOCR3Configs(uni.owner, offrampOCR3Configs)
require.NoError(t, err, "failed to set ocr3 configs on offramp")
uni.backend.Commit()

for _, pluginType := range []cctypes.PluginType{cctypes.PluginTypeCCIPCommit, cctypes.PluginTypeCCIPExec} {
ocrConfig, err := uni.offramp.LatestConfigDetails(&bind.CallOpts{
Context: testutils.Context(t),
}, uint8(pluginType))
require.NoError(t, err, "failed to get latest commit OCR3 config")
require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String())
require.Equalf(t, offrampOCR3Configs[pluginType].F, ocrConfig.ConfigInfo.F, "%s OCR3 config F mismatch", pluginType.String())
require.Equalf(t, offrampOCR3Configs[pluginType].IsSignatureVerificationEnabled, ocrConfig.ConfigInfo.IsSignatureVerificationEnabled, "%s OCR3 config signature verification mismatch", pluginType.String())
if pluginType == cctypes.PluginTypeCCIPCommit {
// only commit will set signers, exec doesn't need them.
require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String())
}
require.Equalf(t, offrampOCR3Configs[pluginType].Transmitters, ocrConfig.Transmitters, "%s OCR3 config transmitters mismatch", pluginType.String())
}

t.Logf("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses)
}

func connectUniverses(
Expand Down Expand Up @@ -473,6 +540,14 @@ func setupUniverseBasics(t *testing.T, uni onchainUniverse) {
require.NoErrorf(t, err, "failed to apply price registry updates on chain id %d", uni.chainID)
uni.backend.Commit()

_, err = uni.priceRegistry.ApplyAuthorizedCallerUpdates(owner, price_registry.AuthorizedCallersAuthorizedCallerArgs{
AddedCallers: []common.Address{
uni.offramp.Address(),
},
})
require.NoError(t, err, "failed to authorize offramp on price registry")
uni.backend.Commit()

//=============================================================================
// Authorize OnRamp & OffRamp on NonceManager
// Otherwise the onramp will not be able to call the nonceManager to get next Nonce
Expand Down
116 changes: 81 additions & 35 deletions core/services/ocr3/plugins/ccip_integration_tests/ocr3_node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ccip_integration_tests

import (
"fmt"
"math/big"
"testing"
"time"

Expand Down Expand Up @@ -74,7 +75,7 @@ func TestIntegration_OCR3Nodes(t *testing.T) {
}

// Start committing periodically in the background for all the chains
tick := time.NewTicker(100 * time.Millisecond)
tick := time.NewTicker(900 * time.Millisecond)
defer tick.Stop()
commitBlocksBackground(t, universes, tick)

Expand All @@ -100,71 +101,116 @@ func TestIntegration_OCR3Nodes(t *testing.T) {
t.Logf("homechain_configs %+v", cfgs)
require.Len(t, cfgs, numChains)

t.Log("creating ocr3 jobs")
for i := 0; i < len(nodes); i++ {
err := nodes[i].app.Start(ctx)
require.NoError(t, err)
tApp := apps[i]
t.Cleanup(func() {
require.NoError(t, tApp.Stop())
})

jb := mustGetJobSpec(t, bootstrapP2PID, bootstrapPort, nodes[i].peerID, nodes[i].keybundle.ID())
require.NoErrorf(t, tApp.AddJobV2(ctx, &jb), "Wasn't able to create ccip job for node %d", i)
}

// Create a DON for each chain
for _, uni := range universes {
// Add nodes and give them the capability
t.Log("AddingDON for universe: ", uni.chainID)
chainSelector := getSelector(uni.chainID)
homeChainUni.AddDON(t,
homeChainUni.AddDON(
t,
ccipCapabilityID,
chainSelector,
uni.offramp.Address().Bytes(),
uni,
1, // f
bootstrapP2PID,
p2pIDs,
oracles[uni.chainID],
)
}

t.Log("creating ocr3 jobs")
for i := 0; i < len(nodes); i++ {
err := nodes[i].app.Start(ctx)
require.NoError(t, err)
tApp := apps[i]
t.Cleanup(func() {
require.NoError(t, tApp.Stop())
})

jb := mustGetJobSpec(t, bootstrapP2PID, bootstrapPort, nodes[i].peerID, nodes[i].keybundle.ID())
require.NoErrorf(t, tApp.AddJobV2(ctx, &jb), "Wasn't able to create ccip job for node %d", i)
}

var messageIDs map[uint64] /* sourceChain */ map[uint64] /* destChain */ [32]byte = make(map[uint64]map[uint64][32]byte)

Check failure on line 134 in core/services/ocr3/plugins/ccip_integration_tests/ocr3_node_test.go

View workflow job for this annotation

GitHub Actions / lint

var-declaration: should omit type map[uint64]map[uint64][32]byte from declaration of var messageIDs; it will be inferred from the right-hand side (revive)
var replayBlocks map[uint64] /* chainID */ uint64 = make(map[uint64]uint64)

Check failure on line 135 in core/services/ocr3/plugins/ccip_integration_tests/ocr3_node_test.go

View workflow job for this annotation

GitHub Actions / lint

var-declaration: should omit type map[uint64]uint64 from declaration of var replayBlocks; it will be inferred from the right-hand side (revive)
pingPongs := initializePingPongContracts(t, universes)
for chainID, universe := range universes {
for chainID, uni := range universes {
var replayBlock uint64
for otherChain, pingPong := range pingPongs[chainID] {
t.Log("PingPong From: ", chainID, " To: ", otherChain)
_, err2 := pingPong.StartPingPong(universe.owner)

uni.backend.Commit()

_, err2 := pingPong.StartPingPong(uni.owner)
require.NoError(t, err2)
universe.backend.Commit()
uni.backend.Commit()

logIter, err3 := universe.onramp.FilterCCIPSendRequested(&bind.FilterOpts{Start: 0}, nil)
endBlock := uni.backend.Blockchain().CurrentBlock().Number.Uint64()
logIter, err3 := uni.onramp.FilterCCIPSendRequested(&bind.FilterOpts{
Start: endBlock - 1,
End: &endBlock,
}, []uint64{getSelector(otherChain)})
require.NoError(t, err3)
// Iterate until latest event
var count int
for logIter.Next() {
count++
}
require.Equal(t, 1, count, "expected 1 CCIPSendRequested log only")

log := logIter.Event
require.Equal(t, getSelector(otherChain), log.DestChainSelector)
require.Equal(t, pingPong.Address(), log.Message.Sender)
chainPingPongAddr := pingPongs[otherChain][chainID].Address().Bytes()
// With chain agnostic addresses we need to pad the address to the correct length if the receiver is zero prefixed

// Receiver address is abi-encoded if destination is EVM.
paddedAddr := common.LeftPadBytes(chainPingPongAddr, len(log.Message.Receiver))
require.Equal(t, paddedAddr, log.Message.Receiver)
sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted)
subscipriton, err := universe.offramp.WatchCommitReportAccepted(&bind.WatchOpts{}, sink)
require.NoError(t, err)

for {
select {
case <-time.After(5 * time.Second):
t.Log("Timed out waiting for commit report")
case <-subscipriton.Err():
t.Log("Error waiting for commit report")
case report := <-sink:
t.Log("Received commit report: ", report)
break
}
_, ok := messageIDs[chainID]
if !ok {
messageIDs[chainID] = make(map[uint64][32]byte)
}
messageIDs[chainID][otherChain] = log.Message.Header.MessageId

// replay block should be the earliest block that has a ccip message.
if replayBlock == 0 {
replayBlock = endBlock
}
}
}

// replay the log poller on all the chains so that the logs are in the db.
// otherwise the plugins won't pick them up.
for _, node := range nodes {
for chainID, replayBlock := range replayBlocks {
require.NoError(t, node.app.ReplayFromBlock(big.NewInt(int64(chainID)), replayBlock, false), "failed to replay logs")
}
}

for _, uni := range universes {
waitForCommit(t, uni)
}
}

func waitForCommit(t *testing.T, uni onchainUniverse) {
sink := make(chan *evm_2_evm_multi_offramp.EVM2EVMMultiOffRampCommitReportAccepted)
subscipriton, err := uni.offramp.WatchCommitReportAccepted(&bind.WatchOpts{}, sink)
require.NoError(t, err)

for {
select {
case <-time.After(5 * time.Second):
t.Log("Timed out waiting for commit report")
case <-subscipriton.Err():
t.Log("Error waiting for commit report")
case report := <-sink:
t.Logf("Received commit report: %+v", report)
if len(report.Report.MerkleRoots) > 0 {
t.Log("Received commit report with merkle roots")
} else {
t.Log("Received commit report without merkle roots")
}
return
}
}
}
6 changes: 1 addition & 5 deletions integration-tests/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1423,11 +1423,7 @@ github.com/smartcontractkit/chain-selectors v1.0.18 h1:ackCMDOlWuwULAyBNj9fQeQme
github.com/smartcontractkit/chain-selectors v1.0.18/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE=
github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8=
github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716103219-8ce5cf3daa0e h1:+nxnYA9VSU12zHjPxgBpcJhUK3IsJb2L3BMxWY7ZbXI=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716103219-8ce5cf3daa0e/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716113537-c4ab63b630d9/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716125744-c4748dc93ff3/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716131321-c210e1f71bb3/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716140948-e39aca330d3a h1:O1FCLgYwBTn4ArTQUZQ752ETrG6qMJDaSX6XLC+4H8Q=
github.com/smartcontractkit/chainlink-ccip v0.0.0-20240716140948-e39aca330d3a/go.mod h1:gyODeD1uMobe5VWRwVRiEXzL9wUzFTI80VvyCNLqWcw=
github.com/smartcontractkit/chainlink-common v0.1.7-0.20240708180634-24440372521a h1:0HUP3qmHejg7FyFdY+R+8iFg0kNtrvnAxaQ//+fuZfc=
github.com/smartcontractkit/chainlink-common v0.1.7-0.20240708180634-24440372521a/go.mod h1:fh9eBbrReCmv31bfz52ENCAMa7nTKQbdhb2B3+S2VGo=
Expand Down
Loading

0 comments on commit 78e622e

Please sign in to comment.