Skip to content

Commit

Permalink
Test 1.2 unmarshalling 1.0 observations (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorwstein authored Nov 21, 2023
1 parent f1f0346 commit 5a153f8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
6 changes: 6 additions & 0 deletions core/services/ocr2/plugins/ccip/observations.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata"
)

// Note if a breaking change is introduced to this struct nodes running different versions
// will not be able to unmarshal each other's observations. Do not modify unless you
// know what you are doing.
type CommitObservation struct {
Interval ccipdata.CommitStoreInterval `json:"interval"`
TokenPricesUSD map[common.Address]*big.Int `json:"tokensPerFeeCoin"`
Expand All @@ -25,6 +28,9 @@ func (o CommitObservation) Marshal() ([]byte, error) {
// Having it structured this way is critical because:
// * it prevents having duplicated sequence numbers within a single ExecutionObservation (compared to the list representation)
// * prevents malicious actors from passing multiple messages with the same sequence number
// Note if a breaking change is introduced to this struct nodes running different versions
// will not be able to unmarshal each other's observations. Do not modify unless you
// know what you are doing.
type ExecutionObservation struct {
Messages map[uint64]MsgData `json:"messages"`
}
Expand Down
62 changes: 62 additions & 0 deletions core/services/ocr2/plugins/ccip/observations_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package ccip

import (
"encoding/json"
"github.com/ethereum/go-ethereum/common"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0"
"math/big"
"testing"

"github.com/leanovate/gopter"
Expand All @@ -24,6 +28,64 @@ func TestObservationFilter(t *testing.T) {
assert.Equal(t, nonEmpty[0].Interval, obs1.Interval)
}

// After 1.2, the observation struct is version agnostic
// so only need to verify the 1.0->1.2 transition.
type CommitObservationV1_0_0 struct {
Interval commit_store_1_0_0.CommitStoreInterval `json:"interval"`
TokenPricesUSD map[common.Address]*big.Int `json:"tokensPerFeeCoin"`
SourceGasPriceUSD *big.Int `json:"sourceGasPrice"`
}

func TestObservationCompat100_120(t *testing.T) {
v10 := CommitObservationV1_0_0{
Interval: commit_store_1_0_0.CommitStoreInterval{
Min: 1,
Max: 12,
},
TokenPricesUSD: map[common.Address]*big.Int{common.HexToAddress("0x1"): big.NewInt(1)},
SourceGasPriceUSD: big.NewInt(3)}
b10, err := json.Marshal(v10)
require.NoError(t, err)
v12 := CommitObservation{
Interval: ccipdata.CommitStoreInterval{
Min: 1,
Max: 12,
},
TokenPricesUSD: map[common.Address]*big.Int{common.HexToAddress("0x1"): big.NewInt(1)},
SourceGasPriceUSD: big.NewInt(3),
}
b12, err := json.Marshal(v12)
require.NoError(t, err)
// Assert identical json.
assert.Equal(t, b10, b12)
}

func TestCommitObservationJsonDeserialization(t *testing.T) {
expectedObservation := CommitObservation{
Interval: ccipdata.CommitStoreInterval{
Min: 1,
Max: 12,
},
TokenPricesUSD: map[common.Address]*big.Int{common.HexToAddress("0x1"): big.NewInt(1)},
SourceGasPriceUSD: big.NewInt(3),
}

json := `{
"interval": {
"Min":1,
"Max":12
},
"tokensPerFeeCoin": {
"0x0000000000000000000000000000000000000001": 1
},
"sourceGasPrice": 3
}`

observations := getParsableObservations[CommitObservation](logger.TestLogger(t), []types.AttributedObservation{{Observation: []byte(json)}})
assert.Equal(t, 1, len(observations))
assert.Equal(t, expectedObservation, observations[0])
}

func TestExecutionObservationJsonDeserialization(t *testing.T) {
expectedObservation := ExecutionObservation{Messages: map[uint64]MsgData{
2: {TokenData: tokenData("c")},
Expand Down

0 comments on commit 5a153f8

Please sign in to comment.