diff --git a/pkg/abi/abi.go b/pkg/abi/abi.go index dce418de..ef0466a4 100644 --- a/pkg/abi/abi.go +++ b/pkg/abi/abi.go @@ -701,7 +701,13 @@ func (e *Entry) SolidityDef() (string, []string, error) { // SolidityDefCtx returns a Solidity-like descriptor of the entry, including its type func (e *Entry) SolidityDefCtx(ctx context.Context) (string, []string, error) { // Everything apart from event and error is a type of function - isFunction := e.Type != Error && e.Type != Event + var fieldType SolFieldType + switch e.Type { + case Error, Event: + fieldType = EventOrErrorField + default: + fieldType = FunctionInput + } allChildStructs := []string{} buff := new(strings.Builder) @@ -713,7 +719,7 @@ func (e *Entry) SolidityDefCtx(ctx context.Context) (string, []string, error) { if i > 0 { buff.WriteString(", ") } - s, childStructs, err := p.SolidityDefCtx(ctx, isFunction) + s, childStructs, err := p.SolidityDefCtx(ctx, fieldType) if err != nil { return "", nil, err } @@ -722,7 +728,7 @@ func (e *Entry) SolidityDefCtx(ctx context.Context) (string, []string, error) { } buff.WriteRune(')') - if isFunction { + if fieldType == FunctionInput { buff.WriteString(" external") if e.StateMutability != "" && // The state mutability nonpayable is reflected in Solidity by not specifying a state mutability modifier at all. @@ -736,7 +742,7 @@ func (e *Entry) SolidityDefCtx(ctx context.Context) (string, []string, error) { if i > 0 { buff.WriteString(", ") } - s, childStructs, err := p.SolidityDefCtx(ctx, isFunction) + s, childStructs, err := p.SolidityDefCtx(ctx, fieldType) if err != nil { return "", nil, err } @@ -782,13 +788,13 @@ func (p *Parameter) SignatureStringCtx(ctx context.Context) (string, error) { return tc.String(), nil } -func (p *Parameter) SolidityDefCtx(ctx context.Context, inFunction bool) (string, []string, error) { +func (p *Parameter) SolidityDefCtx(ctx context.Context, fieldType SolFieldType) (string, []string, error) { // Ensure the type component tree has been parsed tc, err := p.TypeComponentTreeCtx(ctx) if err != nil { return "", nil, err } - solDef, childStructs := tc.SolidityParamDef(inFunction) + solDef, childStructs := tc.SolidityParamDef(fieldType) return solDef, childStructs, nil } diff --git a/pkg/abi/abi_test.go b/pkg/abi/abi_test.go index 853ec61b..87ed8b1b 100644 --- a/pkg/abi/abi_test.go +++ b/pkg/abi/abi_test.go @@ -226,6 +226,11 @@ const sampleABI5 = `[ "internalType": "struct AribtraryWidgets.Widget[]", "name": "widgets", "type": "tuple[]" + }, + { + "name": "account", + "type": "address", + "indexed": true } ], "name": "Invoiced", @@ -1015,7 +1020,7 @@ func TestComplexStructSolidityDef(t *testing.T) { solDef, childStructs, err = abi.Events()["Invoiced"].SolidityDef() assert.NoError(t, err) - assert.Equal(t, "event Invoiced(Customer customer, Widget[] widgets)", solDef) + assert.Equal(t, "event Invoiced(Customer customer, Widget[] widgets, address indexed account)", solDef) assert.Equal(t, []string{ "struct Customer { address owner; bytes32 locator; }", "struct Widget { string description; uint256 price; string[] attributes; }", diff --git a/pkg/abi/typecomponents.go b/pkg/abi/typecomponents.go index 00b1abdc..91ebda60 100644 --- a/pkg/abi/typecomponents.go +++ b/pkg/abi/typecomponents.go @@ -66,7 +66,7 @@ type TypeComponent interface { DecodeABIData(d []byte, offset int) (*ComponentValue, error) DecodeABIDataCtx(ctx context.Context, d []byte, offest int) (*ComponentValue, error) - SolidityParamDef(inFunction bool) (solDef string, structDefs []string) // gives a string that can be used to define this param in solidity + SolidityParamDef(fieldType SolFieldType) (solDef string, structDefs []string) // gives a string that can be used to define this param in solidity SolidityTypeDef() (isRef bool, typeDef string, childStructs []string) SolidityStructDef() (structName string, structs []string) } @@ -187,6 +187,14 @@ const ( BaseTypeString BaseTypeName = "string" ) +type SolFieldType int + +const ( + FunctionInput SolFieldType = iota // input to a function, or a constructor + EventOrErrorField // a field of an event or an error + StructField // a field of a struct +) + // tupleTypeString appears in the same place in the ABI as elementary type strings, but it is not an elementary type. // We treat it separately. const tupleTypeString = "tuple" @@ -371,13 +379,18 @@ func (tc *typeComponent) String() string { } } -func (tc *typeComponent) SolidityParamDef(inFunction bool) (string, []string) { +func (tc *typeComponent) SolidityParamDef(fieldType SolFieldType) (string, []string) { isRef, paramDef, childStructs := tc.SolidityTypeDef() - if isRef && inFunction { - paramDef = fmt.Sprintf("%s memory", paramDef) + if isRef && fieldType == FunctionInput { + paramDef += " memory" } - if tc.parameter != nil && tc.parameter.Name != "" { - paramDef = fmt.Sprintf("%s %s", paramDef, tc.parameter.Name) + if tc.parameter != nil { + if fieldType == EventOrErrorField && tc.parameter.Indexed { + paramDef += " indexed" + } + if tc.parameter.Name != "" { + paramDef = fmt.Sprintf("%s %s", paramDef, tc.parameter.Name) + } } return paramDef, childStructs } diff --git a/pkg/rpcbackend/backend.go b/pkg/rpcbackend/backend.go index 36fd3a5d..ba9f23e0 100644 --- a/pkg/rpcbackend/backend.go +++ b/pkg/rpcbackend/backend.go @@ -19,6 +19,7 @@ package rpcbackend import ( "context" "encoding/json" + "errors" "fmt" "sync/atomic" "time" @@ -91,7 +92,7 @@ type RPCError struct { } func (e *RPCError) Error() error { - return fmt.Errorf(e.Message) + return errors.New(e.Message) } func (e *RPCError) String() string { @@ -208,7 +209,7 @@ func (rc *RPCClient) SyncRequest(ctx context.Context, rpcReq *RPCRequest) (rpcRe rpcMsg = i18n.NewError(ctx, signermsgs.MsgRPCRequestFailed, res.Status()).Error() } log.L(ctx).Errorf("RPC[%s] <-- [%d]: %s", rpcTraceID, res.StatusCode(), errLog) - err := fmt.Errorf(rpcMsg) + err := errors.New(rpcMsg) return rpcRes, err } log.L(ctx).Infof("RPC[%s] <-- %s [%d] OK (%.2fms)", rpcTraceID, rpcReq.Method, res.StatusCode(), float64(time.Since(rpcStartTime))/float64(time.Millisecond))