Skip to content

Commit

Permalink
Merge branch 'develop' into CM-470-implement-gateway-handler-and-http…
Browse files Browse the repository at this point in the history
…-client
  • Loading branch information
jinhoonbang committed Sep 30, 2024
2 parents 27bfa02 + 41443fa commit 2a3ee6a
Show file tree
Hide file tree
Showing 51 changed files with 3,300 additions and 238 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilly-crews-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": minor
---

#added log-event-trigger LOOPP capability, using ChainReader
5 changes: 5 additions & 0 deletions .changeset/honest-cameras-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

Implementing evm specific token data encoder for CCIP #internal
8 changes: 8 additions & 0 deletions .changeset/moody-rules-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"chainlink": patch
---

- register polling subscription to avoid subscription leaking when rpc client gets closed.
- add a temporary special treatment for SubscribeNewHead before we replace it with SubscribeToHeads. Add a goroutine that forwards new head from poller to caller channel.
- fix a deadlock in poller, by using a new lock for subs slice in rpc client.
#bugfix
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
38 changes: 38 additions & 0 deletions core/capabilities/ccip/ccipevm/tokendata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ccipevm

import (
"context"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"

"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers"
)

type usdcAttestationPayload struct {
Message []byte
Attestation []byte
}

func (m usdcAttestationPayload) AbiString() string {
return `
[{
"components": [
{"name": "message", "type": "bytes"},
{"name": "attestation", "type": "bytes"}
],
"type": "tuple"
}]`
}

type EVMTokenDataEncoder struct{}

func NewEVMTokenDataEncoder() EVMTokenDataEncoder {
return EVMTokenDataEncoder{}
}

func (e EVMTokenDataEncoder) EncodeUSDC(_ context.Context, message cciptypes.Bytes, attestation cciptypes.Bytes) (cciptypes.Bytes, error) {
return abihelpers.EncodeAbiStruct(usdcAttestationPayload{
Message: message,
Attestation: attestation,
})
}
73 changes: 73 additions & 0 deletions core/capabilities/ccip/ccipevm/tokendata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ccipevm

import (
"testing"

"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/stretchr/testify/require"

cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers"
)

func Test_EVMTokenDataEncoder(t *testing.T) {
var empty usdcAttestationPayload
encoder := NewEVMTokenDataEncoder()

//https://testnet.snowtrace.io/tx/0xeeb0ad6b26bacd1570a9361724a36e338f4aacf1170dec64399220b7483b7eed/eventlog?chainid=43113
//https://iris-api-sandbox.circle.com/v1/attestations/0x69fb1b419d648cf6c9512acad303746dc85af3b864af81985c76764aba60bf6b
realMessage, err := cciptypes.NewBytesFromString("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f8000000000000000100000006000000000004ac0d000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d00000000000000000000000009f3b8679c73c2fef8b59b4f3444d4e156fb70aa5000000000000000000000000c08835adf4884e51ff076066706e407506826d9d000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc650000000000000000000000004f32ae7f112c26b109357785e5c66dc5d747fbce00000000000000000000000000000000000000000000000000000000000000640000000000000000000000007a4d8f8c18762d362e64b411d7490fba112811cd0000000000000000")
require.NoError(t, err)
realAttestation, err := cciptypes.NewBytesFromString("0xee466fbd340596aa56e3e40d249869573e4008d84d795b4f2c3cba8649083d08653d38190d0df7e0ee12ae685df2f806d100a03b3716ab1ff2013c7201f1c2d01c9af959b55a4b52dbd0319eed69ce9ace25259830e0b1bff79faf0c9c5d1b5e6d6304e824d657db38f802bcff3e97d0bd30f2ffc62b62381f52c1668ceaa5a73a1b")
require.NoError(t, err)

tt := []struct {
name string
message []byte
attestation []byte
}{
{
name: "empty both fields",
message: nil,
attestation: []byte{},
},
{
name: "empty attestation",
message: []byte("message"),
attestation: nil,
},
{
name: "both attestation and message are set",
message: realMessage,
attestation: realAttestation,
},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
got, err := encoder.EncodeUSDC(tests.Context(t), tc.message, tc.attestation)
require.NoError(t, err)

decoded, err := abihelpers.ABIDecode(empty.AbiString(), got)
require.NoError(t, err)

converted := abi.ConvertType(decoded[0], &empty)
casted, ok := converted.(*usdcAttestationPayload)
require.True(t, ok)

if tc.message == nil {
require.Empty(t, casted.Message)
} else {
require.Equal(t, tc.message, casted.Message)
}

if tc.attestation == nil {
require.Empty(t, casted.Attestation)
} else {
require.Equal(t, tc.attestation, casted.Attestation)
}
})
}
}
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
28 changes: 25 additions & 3 deletions core/capabilities/ccip/oraclecreator/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"

"github.com/smartcontractkit/chainlink-ccip/execute/tokendata"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccipevm"
evmconfig "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/configs/evm"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ocrimpls"
Expand All @@ -33,6 +32,7 @@ import (
"github.com/smartcontractkit/chainlink-ccip/pluginconfig"

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

"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
Expand Down 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 All @@ -238,7 +242,7 @@ func (i *pluginOracleCreator) createFactoryAndTransmitter(
ccipevm.NewExecutePluginCodecV1(),
ccipevm.NewMessageHasherV1(),
i.homeChainReader,
&tokendata.NoopTokenDataObserver{},
ccipevm.NewEVMTokenDataEncoder(),
ccipevm.NewGasEstimateProvider(),
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
Loading

0 comments on commit 2a3ee6a

Please sign in to comment.