Skip to content

Commit

Permalink
offchain - json address encoding fix (cherry picking from release) (#590
Browse files Browse the repository at this point in the history
)
  • Loading branch information
dimkouv authored Mar 7, 2024
1 parent 1beda3a commit bebb0b5
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
12 changes: 9 additions & 3 deletions core/services/ocr2/plugins/ccip/ccipcommit/ocr2.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"encoding/hex"
"fmt"
"math/big"
"slices"
"sort"
"time"

mapset "github.com/deckarep/golang-set/v2"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"

Expand Down Expand Up @@ -435,6 +435,9 @@ func validateObservations(ctx context.Context, lggr logger.Logger, destTokens []
lggr.Warnw("Skipping observation due to token count mismatch", "expecting", len(destTokens), "got", len(obs.TokenPricesUSD))
continue
}

destTokensSet := mapset.NewSet[cciptypes.Address](destTokens...)

// If any of the observed token prices is reported as nil, or not supported on dest chain, the observation is faulty, skip the observation.
// Printing all faulty prices instead of short-circuiting to make log more informative.
skipObservation := false
Expand All @@ -443,8 +446,11 @@ func validateObservations(ctx context.Context, lggr logger.Logger, destTokens []
lggr.Warnw("Nil value in observed TokenPricesUSD", "token", token)
skipObservation = true
}
if !slices.Contains(destTokens, token) {
lggr.Warnw("Unsupported token in observed TokenPricesUSD", "token", token)

if !destTokensSet.Contains(token) {
lggr.Warnw("Unsupported token in observed TokenPricesUSD",
"token", token,
"destTokens", destTokensSet.String())
skipObservation = true
}
}
Expand Down
23 changes: 17 additions & 6 deletions core/services/ocr2/plugins/ccip/cciptypes/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,30 @@ import (

type Address string

// TODO: make JSON marshal/unmarshal non-evm specific.
// Make sure we have casing compatibility with old versions.
func (a *Address) UnmarshalJSON(bytes []byte) error {
vStr := strings.Trim(string(bytes), `"`)
func (a *Address) UnmarshalJSON(b []byte) error {
vStr := strings.Trim(string(b), `"`)
if !common.IsHexAddress(vStr) {
return fmt.Errorf("invalid address: %s", vStr)
}
*a = Address(common.HexToAddress(vStr).String())
return nil
}

func (a *Address) MarshalJSON() ([]byte, error) {
return []byte(`"` + strings.ToLower(string(*a)) + `"`), nil
func (a Address) MarshalJSON() ([]byte, error) {
return []byte(`"` + strings.ToLower(string(a)) + `"`), nil
}

func (a Address) MarshalText() (text []byte, err error) {
return []byte(strings.ToLower(string(a))), nil
}

func (a *Address) UnmarshalText(text []byte) error {
vStr := string(text)
if !common.IsHexAddress(vStr) {
return fmt.Errorf("invalid address: %s", vStr)
}
*a = Address(common.HexToAddress(vStr).String())
return nil
}

type Hash [32]byte
Expand Down
45 changes: 23 additions & 22 deletions core/services/ocr2/plugins/ccip/cciptypes/models_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package cciptypes

import (
"encoding/json"
"fmt"
"strings"
"testing"

"github.com/ethereum/go-ethereum/common"
json2 "github.com/goccy/go-json"
"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
)

func TestHash_String(t *testing.T) {
Expand Down Expand Up @@ -44,26 +41,30 @@ func TestHash_String(t *testing.T) {
}

func TestAddress_JSON(t *testing.T) {
addr1 := utils.RandomAddress()

addrArr := []Address{Address(addr1.String())}
evmAddrArr := []common.Address{addr1}
addrLower := "0xe8bade28e08b469b4eeec35b9e48b2ce49fb3fc9"
addrEIP55 := "0xE8BAde28E08B469B4EeeC35b9E48B2Ce49FB3FC9"

b, err := json.Marshal(addrArr)
assert.NoError(t, err)
assert.Equal(t, fmt.Sprintf(`["%s"]`, strings.ToLower(addr1.String())), string(b))
t.Run("arrays", func(t *testing.T) {
addrArr := []Address{Address(addrLower), Address(addrEIP55)}
b, err := json2.Marshal(addrArr)
assert.NoError(t, err)
assert.Equal(t, fmt.Sprintf(`["%s","%s"]`, addrLower, addrLower), string(b))

b2, err := json.Marshal(evmAddrArr)
assert.NoError(t, err)
assert.Equal(t, string(b), string(b2), "marshal should produce the same result for common.Address and cciptypes.Address")
evmAddrArr := []common.Address{common.HexToAddress(addrLower), common.HexToAddress(addrEIP55)}
bEvm, err := json2.Marshal(evmAddrArr)
assert.NoError(t, err)
assert.Equal(t, b, bEvm)
})

var unmarshalledAddr []Address
err = json.Unmarshal(b, &unmarshalledAddr)
assert.NoError(t, err)
assert.Equal(t, addrArr[0], unmarshalledAddr[0])
t.Run("maps", func(t *testing.T) {
m := map[Address]int{Address(addrEIP55): 14}
b, err := json2.Marshal(m)
assert.NoError(t, err)
assert.Equal(t, fmt.Sprintf(`{"%s":14}`, addrLower), string(b), "should be lower when marshalled")

var unmarshalledEvmAddr []common.Address
err = json.Unmarshal(b, &unmarshalledEvmAddr)
assert.NoError(t, err)
assert.Equal(t, evmAddrArr[0], unmarshalledEvmAddr[0])
m2 := map[Address]int{}
err = json2.Unmarshal(b, &m2)
assert.NoError(t, err)
assert.Equal(t, m, m2, "should be eip55 when unmarshalled")
})
}
8 changes: 4 additions & 4 deletions core/services/ocr2/plugins/ccip/observations.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package ccip

import (
"encoding/json"
"math/big"

json2 "github.com/goccy/go-json"
"github.com/smartcontractkit/libocr/commontypes"

"github.com/smartcontractkit/libocr/offchainreporting2plus/types"
Expand All @@ -22,7 +22,7 @@ type CommitObservation struct {
}

func (o CommitObservation) Marshal() ([]byte, error) {
return json.Marshal(&o)
return json2.Marshal(&o)
}

// ExecutionObservation stores messages as a map pointing from a sequence number (uint) to the message payload (MsgData)
Expand Down Expand Up @@ -64,7 +64,7 @@ func NewObservedMessage(seqNr uint64, tokenData [][]byte) ObservedMessage {
}

func (o ExecutionObservation) Marshal() ([]byte, error) {
return json.Marshal(&o)
return json2.Marshal(&o)
}

// GetParsableObservations checks the given observations for formatting and value errors.
Expand All @@ -80,7 +80,7 @@ func GetParsableObservations[O CommitObservation | ExecutionObservation](l logge
continue
}
var ob O
err := json.Unmarshal(ao.Observation, &ob)
err := json2.Unmarshal(ao.Observation, &ob)
if err != nil {
l.Errorw("Received unmarshallable observation", "err", err, "observation", string(ao.Observation), "observer", ao.Observer)
continue
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-webauthn/webauthn v0.9.4
github.com/goccy/go-json v0.10.2
github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b
github.com/google/uuid v1.4.0
github.com/gorilla/securecookie v1.1.2
Expand Down Expand Up @@ -194,7 +195,6 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/go-webauthn/x v0.1.5 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/uuid v4.3.1+incompatible // indirect
Expand Down

0 comments on commit bebb0b5

Please sign in to comment.