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

Post version abstraction follow up #194

Merged
merged 32 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
97fbf5a
multi gas price update in PriceUpdates struct
matYang Oct 2, 2023
5cb65fa
update onchain portion
matYang Oct 3, 2023
8e78369
offchain non-backwards-incompatible changes
matYang Oct 3, 2023
ad5111f
fix tests
matYang Oct 3, 2023
e0561fe
Merge branch 'ccip-develop' into feature/multi-gas-update
matYang Oct 9, 2023
9da3c84
pass tests again
matYang Oct 9, 2023
deb8551
update commit store tests
matYang Oct 9, 2023
90a03d4
update tests
matYang Oct 9, 2023
66ebc5f
Follow up
connorwstein Oct 9, 2023
726ba03
Add price reg 1.0.0 ABI
connorwstein Oct 9, 2023
774e73b
Merge branch 'ccip-develop' into post-versioning-cleanup
connorwstein Oct 10, 2023
1bb71d2
Black box testing
connorwstein Oct 10, 2023
7d5598d
Improve test coverage
connorwstein Oct 11, 2023
dc7c537
Finish price reg test
connorwstein Oct 11, 2023
4f0c930
Merge branch 'ccip-develop' into post-versioning-cleanup
connorwstein Oct 11, 2023
48eaafe
Fix lp test
connorwstein Oct 11, 2023
420cfbe
Merge branch 'post-versioning-cleanup' of github.com:smartcontractkit…
connorwstein Oct 11, 2023
d806fda
Cleanup
connorwstein Oct 11, 2023
828ff5e
Fix lint
connorwstein Oct 11, 2023
40c074c
Merge branch 'ccip-develop' into post-versioning-cleanup
matYang Oct 12, 2023
9eff47a
Port lp test and 2 easy TODOs
connorwstein Oct 12, 2023
840ba66
Improve commit store coverage
connorwstein Oct 12, 2023
3843002
Test ChangeConfig and fix bug
connorwstein Oct 12, 2023
926ce5d
Finish commit store sanity
connorwstein Oct 12, 2023
6acfd78
Few more todos
connorwstein Oct 12, 2023
92d73fb
Merge branch 'ccip-develop' into post-versioning-cleanup
connorwstein Oct 12, 2023
5a24c7a
Comments
connorwstein Oct 13, 2023
a690d7e
Merge branch 'ccip-develop' into post-versioning-cleanup
connorwstein Oct 13, 2023
0548c01
Fmt
connorwstein Oct 13, 2023
ec80b5b
Merge branch 'ccip-develop' into post-versioning-cleanup
connorwstein Oct 13, 2023
8fce785
Fix merge conflicts
connorwstein Oct 13, 2023
24ee1f7
Fix 100
connorwstein Oct 13, 2023
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
25 changes: 8 additions & 17 deletions core/chains/evm/logpoller/orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,16 @@ func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig co

// SelectLogsCreatedAfter finds logs created after some timestamp.
func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) {
minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...)
connorwstein marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

var logs []Log
q := o.q.WithOpts(qopts...)
err = q.Select(&logs, `
err := q.Select(&logs, `
SELECT * FROM evm.logs
WHERE evm_chain_id = $1
AND address = $2
AND event_sig = $3
AND block_number > $4
AND block_number <= $5
ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, minBlock, maxBlock)
AND (block_number + $4) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1)
connorwstein marked this conversation as resolved.
Show resolved Hide resolved
AND block_timestamp > $5
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mateusz-sekara without this we'll be unable to query for CreatedAt logs which were backfilled so I believe its required. You'll see very strange results running the query after a series of restarts/backfills as random logs will be omitted. Came up testing the price reg reader, can discuss further

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spoke offline - including the fix here, then will merge from core when a new release comes out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, confs, after)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -547,23 +542,19 @@ func validateTopicIndex(index int) error {
}

func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) {
minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...)
if err != nil {
return nil, err
}
var logs []Log
q := o.q.WithOpts(qopts...)
topicValuesBytes := concatBytes(topicValues)
// Add 1 since postgresql arrays are 1-indexed.
err = q.Select(&logs, `
err := q.Select(&logs, `
SELECT * FROM evm.logs
WHERE evm.logs.evm_chain_id = $1
AND address = $2
AND event_sig = $3
AND topics[$4] = ANY($5)
AND block_number > $6
AND block_number <= $7
ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, minBlock, maxBlock)
AND (block_number + $6) <= (SELECT COALESCE(block_number, 0) FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1)
AND block_timestamp > $7
ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, confs, after)
if err != nil {
return nil, err
}
Expand Down
36 changes: 21 additions & 15 deletions core/chains/evm/logpoller/orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ func GenLog(chainID *big.Int, logIndex int64, blockNum int64, blockHash string,
}
}

func GenLogWithTimestamp(chainID *big.Int, logIndex int64, blockNum int64, blockHash string, topic1 []byte, address common.Address, ts time.Time) logpoller.Log {
lg := GenLog(chainID, logIndex, blockNum, blockHash, topic1, address)
lg.BlockTimestamp = ts
return lg
}

func TestLogPoller_Batching(t *testing.T) {
t.Parallel()
th := SetupTH(t, 2, 3, 2)
Expand Down Expand Up @@ -1177,19 +1183,19 @@ func TestSelectLogsCreatedAfter(t *testing.T) {
event := EmitterABI.Events["Log1"].ID
address := utils.RandomAddress()

past := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC)
now := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC)
future := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC)
block1 := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC)
block2 := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC)
block3 := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC)

require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{
GenLog(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address),
GenLog(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address),
GenLog(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address),
GenLog(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address),
GenLogWithTimestamp(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address, block1),
GenLogWithTimestamp(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address, block2),
GenLogWithTimestamp(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address, block2),
GenLogWithTimestamp(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address, block3),
}))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 1, past))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 2, now))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, future))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 1, block1))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 2, block2))
require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, block3))

type expectedLog struct {
block int64
Expand All @@ -1205,7 +1211,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) {
{
name: "picks logs after block 1",
confs: 0,
after: past.Add(-time.Hour),
after: block1.Add(time.Hour),
connorwstein marked this conversation as resolved.
Show resolved Hide resolved
expectedLogs: []expectedLog{
{block: 2, log: 1},
{block: 2, log: 2},
Expand All @@ -1215,7 +1221,7 @@ func TestSelectLogsCreatedAfter(t *testing.T) {
{
name: "skips blocks with not enough confirmations",
confs: 1,
after: past.Add(-time.Hour),
after: block1.Add(time.Hour),
expectedLogs: []expectedLog{
{block: 2, log: 1},
{block: 2, log: 2},
Expand All @@ -1224,21 +1230,21 @@ func TestSelectLogsCreatedAfter(t *testing.T) {
{
name: "limits number of blocks by block_timestamp",
confs: 0,
after: now.Add(-time.Hour),
after: block2.Add(time.Hour),
expectedLogs: []expectedLog{
{block: 3, log: 1},
},
},
{
name: "returns empty dataset for future timestamp",
confs: 0,
after: future,
after: block3,
expectedLogs: []expectedLog{},
},
{
name: "returns empty dataset when too many confirmations are required",
confs: 3,
after: past.Add(-time.Hour),
after: block1.Add(-time.Hour),
expectedLogs: []expectedLog{},
},
}
Expand Down
1,665 changes: 1,665 additions & 0 deletions core/gethwrappers/ccip/generated/price_registry_1_0_0/price_registry.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers"
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

Expand Down Expand Up @@ -94,9 +93,6 @@ func TestNewTokenPools(t *testing.T) {
}
offRamp.On("GetDestinationTokens", mock.Anything).Return(destTokens, nil)

priceReg, _ := testhelpers.NewFakePriceRegistry(t)
priceReg.SetFeeTokens(tc.feeTokens)

c := NewTokenPools(logger.TestLogger(t), mockLp, offRamp, 0, 5)

res, err := c.Get(ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client.
return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType)
}
switch version.String() {
case v1_0_0, v1_1_0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed that during perf tests, but it seems that we lost some visibility into contract interactions. So far we have used observability/contract_wrapper.go to track the usages of different contract methods with prom metrics. This logic is no longer in use (probably should be moved to the reader layer)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to fix it in a separate PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case V1_0_0, V1_1_0:
return NewCommitStoreV1_0_0(lggr, address, ec, lp, estimator)
case v1_2_0:
case V1_2_0:
return NewCommitStoreV1_2_0(lggr, address, ec, lp, estimator)
default:
return nil, errors.Errorf("got unexpected version %v", version.String())
Expand All @@ -108,7 +108,7 @@ func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (f
return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, typ)
}
switch ver.String() {
case v1_0_0, v1_1_0:
case V1_0_0, V1_1_0:
commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI)
return func(report []byte) (*txmgr.TxMeta, error) {
commitReport, err := decodeCommitReportV1_0_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report)
Expand All @@ -117,7 +117,7 @@ func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (f
}
return commitReportToEthTxMeta(commitReport)
}, nil
case v1_2_0:
case V1_2_0:
commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI)
return func(report []byte) (*txmgr.TxMeta, error) {
commitReport, err := decodeCommitReportV1_2_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package ccipdata
package ccipdata_test

import (
"math/big"
Expand All @@ -16,10 +16,11 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers"
ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata"
"github.com/smartcontractkit/chainlink/v2/core/store/models"
)

func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) Closer, numFilter int) {
func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer, numFilter int) {
// Expected filter properties for a closer:
// - Should be the same filter set registered that is unregistered
// - Should be registered to the address specified
Expand All @@ -44,25 +45,25 @@ func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser f
}

func TestCommitFilters(t *testing.T) {
assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer {
c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil)
assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer {
c, err := ccipdata.NewCommitStoreV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil)
require.NoError(t, err)
return c
}, 1)
assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer {
c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil)
assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) ccipdata.Closer {
c, err := ccipdata.NewCommitStoreV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil)
require.NoError(t, err)
return c
}, 1)
}

func TestCommitOffchainConfig_Encoding(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test mostly for testing the validate function? Maybe it could be more succinct and include V1_0_0

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah just validate. Leaving broader test cleanup out of scope for now

tests := map[string]struct {
want CommitOffchainConfigV1_2_0
want ccipdata.CommitOffchainConfigV1_2_0
expectErr bool
}{
"encodes and decodes config with all fields set": {
want: CommitOffchainConfigV1_2_0{
want: ccipdata.CommitOffchainConfigV1_2_0{
SourceFinalityDepth: 3,
DestFinalityDepth: 3,
GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour),
Expand All @@ -75,7 +76,7 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) {
},
},
"fails decoding when all fields present but with 0 values": {
want: CommitOffchainConfigV1_2_0{
want: ccipdata.CommitOffchainConfigV1_2_0{
SourceFinalityDepth: 0,
DestFinalityDepth: 0,
GasPriceHeartBeat: models.MustMakeDuration(0),
Expand All @@ -89,11 +90,11 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) {
expectErr: true,
},
"fails decoding when all fields are missing": {
want: CommitOffchainConfigV1_2_0{},
want: ccipdata.CommitOffchainConfigV1_2_0{},
expectErr: true,
},
"fails decoding when some fields are missing": {
want: CommitOffchainConfigV1_2_0{
want: ccipdata.CommitOffchainConfigV1_2_0{
SourceFinalityDepth: 3,
GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour),
DAGasPriceDeviationPPB: 5e7,
Expand All @@ -109,7 +110,7 @@ func TestCommitOffchainConfig_Encoding(t *testing.T) {
t.Run(name, func(t *testing.T) {
encode, err := ccipconfig.EncodeOffchainConfig(tc.want)
require.NoError(t, err)
got, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfigV1_2_0](encode)
got, err := ccipconfig.DecodeOffchainConfig[ccipdata.CommitOffchainConfigV1_2_0](encode)

if tc.expectErr {
require.ErrorContains(t, err, "must set")
Expand All @@ -128,19 +129,19 @@ func randomAddress() common.Address {
func TestCommitOnchainConfig(t *testing.T) {
tests := []struct {
name string
want CommitOnchainConfig
want ccipdata.CommitOnchainConfig
expectErr bool
}{
{
name: "encodes and decodes config with all fields set",
want: CommitOnchainConfig{
want: ccipdata.CommitOnchainConfig{
PriceRegistry: randomAddress(),
},
expectErr: false,
},
{
name: "encodes and fails decoding config with missing fields",
want: CommitOnchainConfig{},
want: ccipdata.CommitOnchainConfig{},
expectErr: true,
},
}
Expand All @@ -149,7 +150,7 @@ func TestCommitOnchainConfig(t *testing.T) {
encoded, err := abihelpers.EncodeAbiStruct(tt.want)
require.NoError(t, err)

decoded, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](encoded)
decoded, err := abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](encoded)
if tt.expectErr {
require.ErrorContains(t, err, "must set")
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/rand"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand All @@ -14,6 +15,10 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/utils"
)

func randomAddress() common.Address {
connorwstein marked this conversation as resolved.
Show resolved Hide resolved
return common.BigToAddress(big.NewInt(rand.Int63()))
}

func TestCommitReportEncodingV1_0_0(t *testing.T) {
report := CommitStoreReport{
TokenPrices: []TokenPrice{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ func NewOffRampReader(lggr logger.Logger, addr common.Address, destClient client
return nil, err
}
switch version.String() {
case v1_0_0, v1_1_0:
case V1_0_0, V1_1_0:
return NewOffRampV1_0_0(lggr, addr, destClient, lp, estimator)
case v1_2_0:
case V1_2_0:
return NewOffRampV1_2_0(lggr, addr, destClient, lp, estimator)
default:
return nil, errors.Errorf("unsupported offramp version %v", version.String())
Expand All @@ -178,7 +178,7 @@ func ExecReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (fun
return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, typ)
}
switch ver.String() {
case v1_0_0, v1_1_0, v1_2_0:
case V1_0_0, V1_1_0, V1_2_0:
// ABI remains the same across all offramp versions.
offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI)
return func(report []byte) (*txmgr.TxMeta, error) {
Expand Down
Loading