Skip to content

Commit

Permalink
Automatically upper case nested tuple's field names in go (#13320)
Browse files Browse the repository at this point in the history
  • Loading branch information
nolag authored Jun 4, 2024
1 parent a63569c commit a57c2a5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
11 changes: 10 additions & 1 deletion core/services/relay/evm/types/codec_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ func (entry *codecEntry) EncodingPrefix() []byte {
return tmp
}

func (entry *codecEntry) Init() error {
func (entry *codecEntry) Init() (err error) {
// Since reflection panics if errors occur, best to recover in case of any unknown errors
defer func() {
if r := recover(); r != nil {
entry.checkedType = nil
entry.nativeType = nil
err = fmt.Errorf("%w: %v", commontypes.ErrInvalidConfig, r)
}
}()
if entry.checkedType != nil {
return nil
}
Expand Down Expand Up @@ -234,6 +242,7 @@ func createTupleType(curType *abi.Type, converter func(reflect.Type) reflect.Typ
checkedFields := make([]reflect.StructField, len(curType.TupleElems))
for i, elm := range curType.TupleElems {
name := curType.TupleRawNames[i]
name = strings.ToUpper(name[:1]) + name[1:]
nativeFields[i].Name = name
checkedFields[i].Name = name
nativeArgType, checkedArgType, err := getNativeAndCheckedTypes(elm)
Expand Down
37 changes: 37 additions & 0 deletions core/services/relay/evm/types/codec_entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,43 @@ func TestCodecEntry(t *testing.T) {
assertHaveSameStructureAndNames(t, iNative.Type(), entry.CheckedType())
})

t.Run("nested tuple member names are capitalized", func(t *testing.T) {
type1, err := abi.NewType("uint16", "", []abi.ArgumentMarshaling{})
require.NoError(t, err)
tupleType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{
{Name: "field3", Type: "uint24"},
{Name: "field4", Type: "int24"},
})
require.NoError(t, err)
args := abi.Arguments{
{Name: "field1", Type: type1},
{Name: "field2", Type: tupleType},
}
entry := NewCodecEntry(args, nil, nil)
require.NoError(t, entry.Init())

checked := reflect.New(entry.CheckedType())
iChecked := reflect.Indirect(checked)
f1 := uint16(2)
iChecked.FieldByName("Field1").Set(reflect.ValueOf(&f1))
f2 := iChecked.FieldByName("Field2")
f2.Set(reflect.New(f2.Type().Elem()))
f2 = reflect.Indirect(f2)
f3 := big.NewInt( /*2^24 - 1*/ 16777215)
setAndVerifyLimit(t, (*uint24)(f3), f3, f2.FieldByName("Field3"))
f4 := big.NewInt( /*2^23 - 1*/ 8388607)
setAndVerifyLimit(t, (*int24)(f4), f4, f2.FieldByName("Field4"))

native, err := entry.ToNative(checked)
require.NoError(t, err)
iNative := reflect.Indirect(native)
require.Equal(t, iNative.Field(0).Interface(), iChecked.Field(0).Interface())
nF2 := reflect.Indirect(iNative.Field(1))
assert.Equal(t, nF2.Field(0).Interface(), f3)
assert.Equal(t, nF2.Field(1).Interface(), f4)
assertHaveSameStructureAndNames(t, iNative.Type(), entry.CheckedType())
})

t.Run("unwrapped types", func(t *testing.T) {
// This exists to allow you to decode single returned values without naming the parameter
wrappedTuple, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{
Expand Down

0 comments on commit a57c2a5

Please sign in to comment.