Skip to content

Commit

Permalink
Fix decoding unnamed params, the return type was right, but names wer…
Browse files Browse the repository at this point in the history
…en't populated for the arg itself. (#13512)
  • Loading branch information
nolag authored Jun 12, 2024
1 parent 63fbee9 commit 2db7369
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
27 changes: 27 additions & 0 deletions core/services/relay/evm/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,33 @@ func TestCodec(t *testing.T) {

anyN := 10
c := tester.GetCodec(t)
t.Run("Decode works with multiple unnamed return values", func(t *testing.T) {
encode := &struct {
F0 int32
F1 int32
}{F0: 1, F1: 2}
codecName := "my_codec"
evmEncoderConfig := `[{"Name":"","Type":"int32"},{"Name":"","Type":"int32"}]`

codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{
codecName: {TypeABI: evmEncoderConfig},
}}
c, err := evm.NewCodec(codecConfig)
require.NoError(t, err)

result, err := c.Encode(testutils.Context(t), encode, codecName)
require.NoError(t, err)

decode := &struct {
F0 int32
F1 int32
}{}
err = c.Decode(testutils.Context(t), result, decode, codecName)
require.NoError(t, err)
require.Equal(t, encode.F0, decode.F0)
require.Equal(t, encode.F1, decode.F1)
})

t.Run("GetMaxEncodingSize delegates to GetMaxSize", func(t *testing.T) {
actual, err := c.GetMaxEncodingSize(testutils.Context(t), anyN, sizeItemType)
assert.NoError(t, err)
Expand Down
8 changes: 7 additions & 1 deletion core/services/relay/evm/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ type decoder struct {

var _ commontypes.Decoder = &decoder{}

func (m *decoder) Decode(_ context.Context, raw []byte, into any, itemType string) error {
func (m *decoder) Decode(_ context.Context, raw []byte, into any, itemType string) (err error) {
defer func() {
// unexpected, but reflection can panic
if r := recover(); r != nil {
err = fmt.Errorf("%w: %v", commontypes.ErrInvalidType, r)
}
}()
info, ok := m.Definitions[itemType]
if !ok {
return fmt.Errorf("%w: cannot find definition for %s", commontypes.ErrInvalidType, itemType)
Expand Down
2 changes: 2 additions & 0 deletions core/services/relay/evm/types/codec_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,13 @@ func (entry *codecEntry) Init() (err error) {
}
for {
name = name + "_X"
arg.Name = name
if !seenNames[name] {
break
}
}
}
args[i] = arg
seenNames[name] = true
native[i] = reflect.StructField{Name: name, Type: nativeArg}
checked[i] = reflect.StructField{Name: name, Type: checkedArg}
Expand Down
7 changes: 7 additions & 0 deletions core/services/relay/evm/types/codec_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,15 @@ func TestCodecEntry(t *testing.T) {
assert.NoError(t, entry.Init())
ct := entry.CheckedType()
require.Equal(t, 2, ct.NumField())
args := entry.Args()
require.Equal(t, 2, len(args))
f0 := ct.Field(0)
assert.Equal(t, "F0", f0.Name)
assert.Equal(t, "F0", args[0].Name)
assert.Equal(t, reflect.TypeOf((*int64)(nil)), f0.Type)
f1 := ct.Field(1)
assert.Equal(t, "F1", f1.Name)
assert.Equal(t, "F1", args[1].Name)
assert.Equal(t, reflect.TypeOf((*int32)(nil)), f1.Type)
})

Expand All @@ -237,11 +241,14 @@ func TestCodecEntry(t *testing.T) {
assert.NoError(t, entry.Init())
ct := entry.CheckedType()
require.Equal(t, 2, ct.NumField())
args := entry.Args()
require.Equal(t, 2, len(args))
f0 := ct.Field(0)
assert.Equal(t, "F1", f0.Name)
assert.Equal(t, reflect.TypeOf((*int64)(nil)), f0.Type)
f1 := ct.Field(1)
assert.Equal(t, "F1_X", f1.Name)
assert.Equal(t, "F1_X", args[1].Name)
assert.Equal(t, reflect.TypeOf((*int32)(nil)), f1.Type)
})

Expand Down

0 comments on commit 2db7369

Please sign in to comment.