aboutsummaryrefslogtreecommitdiffstats
path: root/accounts
diff options
context:
space:
mode:
authorJeremy McNevin <jeremy.mcnevin@optum.com>2019-01-29 02:47:24 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-03-14 18:51:10 +0800
commit7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5 (patch)
tree369ae6c285b715391299e913a57146d235ffb658 /accounts
parent6c312a24b6041385c33eca066ff5604af315a41e (diff)
downloadgo-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar.gz
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar.bz2
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar.lz
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar.xz
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.tar.zst
go-tangerine-7640c9c933cb7a60303f3424e7a6c4a0ab5a7af5.zip
bind: Static byte arrays should be right-padded
Per https://solidity.readthedocs.io/en/v0.5.3/abi-spec.html: "bytes<M>: enc(X) is the sequence of bytes in X padded with trailing zero-bytes to a length of 32 bytes"
Diffstat (limited to 'accounts')
-rw-r--r--accounts/abi/bind/topics.go8
-rw-r--r--accounts/abi/bind/topics_test.go103
2 files changed, 109 insertions, 2 deletions
diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go
index 600dfcda9..af9c272cd 100644
--- a/accounts/abi/bind/topics.go
+++ b/accounts/abi/bind/topics.go
@@ -83,8 +83,10 @@ func makeTopics(query ...[]interface{}) ([][]common.Hash, error) {
val := reflect.ValueOf(rule)
switch {
+
+ // static byte array
case val.Kind() == reflect.Array && reflect.TypeOf(rule).Elem().Kind() == reflect.Uint8:
- reflect.Copy(reflect.ValueOf(topic[common.HashLength-val.Len():]), val)
+ reflect.Copy(reflect.ValueOf(topic[:val.Len()]), val)
default:
return nil, fmt.Errorf("unsupported indexed type: %T", rule)
@@ -175,8 +177,10 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er
default:
// Ran out of custom types, try the crazies
switch {
+
+ // static byte array
case arg.Type.T == abi.FixedBytesTy:
- reflect.Copy(field, reflect.ValueOf(topics[0][common.HashLength-arg.Type.Size:]))
+ reflect.Copy(field, reflect.ValueOf(topics[0][:arg.Type.Size]))
default:
return fmt.Errorf("unsupported indexed type: %v", arg.Type)
diff --git a/accounts/abi/bind/topics_test.go b/accounts/abi/bind/topics_test.go
new file mode 100644
index 000000000..c2bbd5af8
--- /dev/null
+++ b/accounts/abi/bind/topics_test.go
@@ -0,0 +1,103 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package bind
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/ethereum/go-ethereum/common"
+)
+
+func Test_makeTopics(t *testing.T) {
+ type args struct {
+ query [][]interface{}
+ }
+ tests := []struct {
+ name string
+ args args
+ want [][]common.Hash
+ wantErr bool
+ }{
+ {
+ "support fixed byte types, right padded to 32 bytes",
+ args{[][]interface{}{{[5]byte{1, 2, 3, 4, 5}}}},
+ [][]common.Hash{{common.Hash{1, 2, 3, 4, 5}}},
+ false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := makeTopics(tt.args.query...)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("makeTopics() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("makeTopics() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func Test_parseTopics(t *testing.T) {
+ type bytesStruct struct {
+ StaticBytes [5]byte
+ }
+ bytesType, _ := abi.NewType("bytes5", nil)
+ type args struct {
+ createObj func() interface{}
+ resultObj func() interface{}
+ fields abi.Arguments
+ topics []common.Hash
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "support fixed byte types, right padded to 32 bytes",
+ args: args{
+ createObj: func() interface{} { return &bytesStruct{} },
+ resultObj: func() interface{} { return &bytesStruct{StaticBytes: [5]byte{1, 2, 3, 4, 5}} },
+ fields: abi.Arguments{abi.Argument{
+ Name: "staticBytes",
+ Type: bytesType,
+ Indexed: true,
+ }},
+ topics: []common.Hash{
+ {1, 2, 3, 4, 5},
+ },
+ },
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ createObj := tt.args.createObj()
+ if err := parseTopics(createObj, tt.args.fields, tt.args.topics); (err != nil) != tt.wantErr {
+ t.Errorf("parseTopics() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ resultObj := tt.args.resultObj()
+ if !reflect.DeepEqual(createObj, resultObj) {
+ t.Errorf("parseTopics() = %v, want %v", createObj, resultObj)
+ }
+ })
+ }
+}