Skip to content

Commit

Permalink
Merge branch 'develop' into BCFR-945-improve-contract-reader-logs
Browse files Browse the repository at this point in the history
  • Loading branch information
silaslenihan committed Sep 30, 2024
2 parents 0ef90eb + d435981 commit 8783ee8
Show file tree
Hide file tree
Showing 36 changed files with 619 additions and 201 deletions.
5 changes: 5 additions & 0 deletions .changeset/nervous-books-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#internal Updated QueryKey to be able to do advanced queries on contract event data words
5 changes: 5 additions & 0 deletions .changeset/tidy-apricots-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#added Pass the home chain selector to the commit plugin factory
10 changes: 10 additions & 0 deletions contracts/.changeset/tall-donkeys-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@chainlink/contracts': minor
---

#internal Updated ChainReaderTester to include dynamic and static nested structs in TestStruct


PR issue: BCFR-44

Solidity Review issue: BCFR-957
74 changes: 61 additions & 13 deletions contracts/src/v0.8/shared/test/helpers/ChainReaderTester.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,41 @@ struct TestStruct {
address Account;
address[] Accounts;
int192 BigField;
MidLevelTestStruct NestedStruct;
MidLevelDynamicTestStruct NestedDynamicStruct;
MidLevelStaticTestStruct NestedStaticStruct;
}

struct MidLevelTestStruct {
struct MidLevelDynamicTestStruct {
bytes2 FixedBytes;
InnerTestStruct Inner;
InnerDynamicTestStruct Inner;
}

struct InnerTestStruct {
struct InnerDynamicTestStruct {
int64 IntVal;
string S;
}

struct MidLevelStaticTestStruct {
bytes2 FixedBytes;
InnerStaticTestStruct Inner;
}

struct InnerStaticTestStruct {
int64 IntVal;
address A;
}

contract ChainReaderTester {
event Triggered(
int32 indexed field,
uint8 oracleId,
MidLevelDynamicTestStruct nestedDynamicStruct,
MidLevelStaticTestStruct nestedStaticStruct,
uint8[32] oracleIds,
address Account,
address[] Accounts,
string differentField,
int192 bigField,
MidLevelTestStruct nestedStruct
int192 bigField
);

event TriggeredEventWithDynamicTopic(string indexed fieldHash, string field);
Expand Down Expand Up @@ -61,9 +73,22 @@ contract ChainReaderTester {
address account,
address[] calldata accounts,
int192 bigField,
MidLevelTestStruct calldata nestedStruct
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
MidLevelStaticTestStruct calldata nestedStaticStruct
) public {
s_seen.push(TestStruct(field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct));
s_seen.push(
TestStruct(
field,
differentField,
oracleId,
oracleIds,
account,
accounts,
bigField,
nestedDynamicStruct,
nestedStaticStruct
)
);
}

function setAlterablePrimitiveValue(uint64 value) public {
Expand All @@ -78,9 +103,21 @@ contract ChainReaderTester {
address account,
address[] calldata accounts,
int192 bigField,
MidLevelTestStruct calldata nestedStruct
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
MidLevelStaticTestStruct calldata nestedStaticStruct
) public pure returns (TestStruct memory) {
return TestStruct(field, differentField, oracleId, oracleIds, account, accounts, bigField, nestedStruct);
return
TestStruct(
field,
differentField,
oracleId,
oracleIds,
account,
accounts,
bigField,
nestedDynamicStruct,
nestedStaticStruct
);
}

function getElementAtIndex(uint256 i) public view returns (TestStruct memory) {
Expand Down Expand Up @@ -110,14 +147,25 @@ contract ChainReaderTester {
function triggerEvent(
int32 field,
uint8 oracleId,
MidLevelDynamicTestStruct calldata nestedDynamicStruct,
MidLevelStaticTestStruct calldata nestedStaticStruct,
uint8[32] calldata oracleIds,
address account,
address[] calldata accounts,
string calldata differentField,
int192 bigField,
MidLevelTestStruct calldata nestedStruct
int192 bigField
) public {
emit Triggered(field, oracleId, oracleIds, account, accounts, differentField, bigField, nestedStruct);
emit Triggered(
field,
oracleId,
nestedDynamicStruct,
nestedStaticStruct,
oracleIds,
account,
accounts,
differentField,
bigField
);
}

function triggerEventWithDynamicTopic(string calldata field) public {
Expand Down
12 changes: 12 additions & 0 deletions core/capabilities/ccip/configs/evm/contract_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ var (
nonceManagerABI = evmtypes.MustGetABI(nonce_manager.NonceManagerABI)
priceFeedABI = evmtypes.MustGetABI(aggregator_v3_interface.AggregatorV3InterfaceABI)
rmnRemoteABI = evmtypes.MustGetABI(rmn_remote.RMNRemoteABI)
rmnHomeABI = evmtypes.MustGetABI(rmnHomeString)
)

// TODO: replace with generated ABI when the contract will be defined
var rmnHomeString = "[{\"inputs\":[],\"name\":\"getAllConfigs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"num\",\"type\":\"uint256\"}],\"name\":\"store\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"

// MustSourceReaderConfig returns a ChainReaderConfig that can be used to read from the onramp.
// The configuration is marshaled into JSON so that it can be passed to the relayer NewContractReader() method.
func MustSourceReaderConfig() []byte {
Expand Down Expand Up @@ -249,6 +253,14 @@ var HomeChainReaderConfigRaw = evmrelaytypes.ChainReaderConfig{
},
},
},
consts.ContractNameRMNHome: {
ContractABI: rmnHomeString,
Configs: map[string]*evmrelaytypes.ChainReaderDefinition{
consts.MethodNameGetAllConfigs: {
ChainSpecificName: mustGetMethodName("getAllConfigs", rmnHomeABI),
},
},
},
},
}

Expand Down
16 changes: 16 additions & 0 deletions core/capabilities/ccip/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ccip
import (
"context"
"fmt"
"strconv"
"time"

"github.com/smartcontractkit/chainlink-common/pkg/loop"
Expand All @@ -23,7 +24,11 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/types"
"github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"

chainsel "github.com/smartcontractkit/chain-selectors"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"

"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/config"
kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
Expand Down Expand Up @@ -162,6 +167,16 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services
ccipConfigBinding,
)

// get the chain selector for the home chain
homeChainChainID, err := strconv.ParseUint(d.capabilityConfig.ExternalRegistry().RelayID().ChainID, 10, 64)
if err != nil {
return nil, fmt.Errorf("failed to parse chain ID %s: %w", d.capabilityConfig.ExternalRegistry().RelayID().ChainID, err)
}
homeChainChainSelector, err := chainsel.SelectorFromChainId(homeChainChainID)
if err != nil {
return nil, fmt.Errorf("failed to get chain selector from chain ID %d", homeChainChainID)
}

// if bootstrappers are provided we assume that the node is a plugin oracle.
// the reason for this is that bootstrap oracles do not need to be aware
// of other bootstrap oracles. however, plugin oracles, at least initially,
Expand All @@ -182,6 +197,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) (services
d.monitoringEndpointGen,
bootstrapperLocators,
hcr,
cciptypes.ChainSelector(homeChainChainSelector),
)
} else {
oracleCreator = oraclecreator.NewBootstrapOracleCreator(
Expand Down
24 changes: 23 additions & 1 deletion core/capabilities/ccip/oraclecreator/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type pluginOracleCreator struct {
monitoringEndpointGen telemetry.MonitoringEndpointGenerator
bootstrapperLocators []commontypes.BootstrapperLocator
homeChainReader ccipreaderpkg.HomeChain
homeChainSelector cciptypes.ChainSelector
}

func NewPluginOracleCreator(
Expand All @@ -83,6 +84,7 @@ func NewPluginOracleCreator(
monitoringEndpointGen telemetry.MonitoringEndpointGenerator,
bootstrapperLocators []commontypes.BootstrapperLocator,
homeChainReader ccipreaderpkg.HomeChain,
homeChainSelector cciptypes.ChainSelector,
) cctypes.OracleCreator {
return &pluginOracleCreator{
ocrKeyBundles: ocrKeyBundles,
Expand All @@ -98,6 +100,7 @@ func NewPluginOracleCreator(
monitoringEndpointGen: monitoringEndpointGen,
bootstrapperLocators: bootstrapperLocators,
homeChainReader: homeChainReader,
homeChainSelector: homeChainSelector,
}
}

Expand Down Expand Up @@ -220,6 +223,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter(
ccipevm.NewCommitPluginCodecV1(),
ccipevm.NewMessageHasherV1(),
i.homeChainReader,
i.homeChainSelector,
contractReaders,
chainWriters,
)
Expand Down Expand Up @@ -273,6 +277,11 @@ func (i *pluginOracleCreator) createReadersAndWriters(
execBatchGasLimit = ofc.exec().BatchGasLimit
}

homeChainID, err := i.getChainID(i.homeChainSelector)
if err != nil {
return nil, nil, err
}

contractReaders := make(map[cciptypes.ChainSelector]types.ContractReader)
chainWriters := make(map[cciptypes.ChainSelector]types.ChainWriter)
for _, chain := range i.chains.Slice() {
Expand All @@ -281,7 +290,7 @@ func (i *pluginOracleCreator) createReadersAndWriters(
return nil, nil, err1
}

chainReaderConfig := getChainReaderConfig(chain.ID().Uint64(), destChainID, ofc, chainSelector)
chainReaderConfig := getChainReaderConfig(chain.ID().Uint64(), destChainID, homeChainID, ofc, chainSelector)
cr, err1 := createChainReader(i.lggr, chain, chainReaderConfig, pluginType)
if err1 != nil {
return nil, nil, err1
Expand Down Expand Up @@ -348,9 +357,18 @@ func (i *pluginOracleCreator) getChainSelector(chainID uint64) (cciptypes.ChainS
return cciptypes.ChainSelector(chainSelector), nil
}

func (i *pluginOracleCreator) getChainID(chainSelector cciptypes.ChainSelector) (uint64, error) {
chainID, err := chainsel.ChainIdFromSelector(uint64(chainSelector))
if err != nil {
return 0, fmt.Errorf("failed to get chain ID from chain selector %d: %w", chainSelector, err)
}
return chainID, nil
}

func getChainReaderConfig(
chainID uint64,
destChainID uint64,
homeChainID uint64,
ofc offChainConfig,
chainSelector cciptypes.ChainSelector,
) evmrelaytypes.ChainReaderConfig {
Expand All @@ -364,6 +382,10 @@ func getChainReaderConfig(
if !ofc.commitEmpty() && ofc.commit().PriceFeedChainSelector == chainSelector {
chainReaderConfig = evmconfig.MergeReaderConfigs(chainReaderConfig, evmconfig.FeedReaderConfig)
}

if chainID == homeChainID {
chainReaderConfig = evmconfig.MergeReaderConfigs(chainReaderConfig, evmconfig.HomeChainReaderConfigRaw)
}
return chainReaderConfig
}

Expand Down
21 changes: 21 additions & 0 deletions core/capabilities/encoder_factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package capabilities

import (
"fmt"

"github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/values"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
)

func NewEncoder(name string, config *values.Map, lggr logger.Logger) (types.Encoder, error) {
switch name {
case "EVM":
return evm.NewEVMEncoder(config)
// TODO: add a "no-op" encoder for users who only want to use dynamic ones?
// https://smartcontract-it.atlassian.net/browse/CAPPL-88
default:
return nil, fmt.Errorf("encoder %s not supported", name)
}
}
3 changes: 1 addition & 2 deletions core/capabilities/integration_tests/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key"
p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm"
"github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/mercury/v3/reportcodec"
"github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight"
)
Expand Down Expand Up @@ -153,7 +152,7 @@ func createDons(ctx context.Context, t *testing.T, lggr logger.Logger, reportsSi
requestTimeout := 10 * time.Minute
cfg := ocr3.Config{
Logger: lggr,
EncoderFactory: evm.NewEVMEncoder,
EncoderFactory: capabilities.NewEncoder,
AggregatorFactory: capabilities.NewAggregator,
RequestTimeout: &requestTimeout,
}
Expand Down
2 changes: 1 addition & 1 deletion core/chains/evm/logpoller/orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ func TestORM_DataWords(t *testing.T) {
},
}))

wordFilter := func(wordIdx uint8, word1, word2 uint64) []query.Expression {
wordFilter := func(wordIdx int, word1, word2 uint64) []query.Expression {
return []query.Expression{
logpoller.NewAddressFilter(addr),
logpoller.NewEventSigFilter(eventSig),
Expand Down
4 changes: 2 additions & 2 deletions core/chains/evm/logpoller/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,11 +504,11 @@ type HashedValueComparator struct {
}

type eventByWordFilter struct {
WordIndex uint8
WordIndex int
HashedValueComparers []HashedValueComparator
}

func NewEventByWordFilter(wordIndex uint8, valueComparers []HashedValueComparator) query.Expression {
func NewEventByWordFilter(wordIndex int, valueComparers []HashedValueComparator) query.Expression {
return query.Expression{Primitive: &eventByWordFilter{
WordIndex: wordIndex,
HashedValueComparers: valueComparers,
Expand Down
Loading

0 comments on commit 8783ee8

Please sign in to comment.