| 
									
										
										
										
											2019-07-22 12:17:27 +03:00
										 |  |  | // Copyright 2019 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | // 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 ( | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/accounts/abi" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2020-04-09 10:54:57 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-14 11:47:22 +01:00
										 |  |  | func TestMakeTopics(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 	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, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-04-09 10:54:57 +02:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			"support common hash types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{{common.Hash{1, 2, 3, 4, 5}}}}, | 
					
						
							|  |  |  | 			[][]common.Hash{{common.Hash{1, 2, 3, 4, 5}}}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support address types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{{common.Address{1, 2, 3, 4, 5}}}}, | 
					
						
							|  |  |  | 			[][]common.Hash{{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5}}}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support *big.Int types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{{big.NewInt(1).Lsh(big.NewInt(2), 254)}}}, | 
					
						
							|  |  |  | 			[][]common.Hash{{common.Hash{128}}}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support boolean types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{ | 
					
						
							|  |  |  | 				{true}, | 
					
						
							|  |  |  | 				{false}, | 
					
						
							|  |  |  | 			}}, | 
					
						
							|  |  |  | 			[][]common.Hash{ | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}, | 
					
						
							|  |  |  | 				{common.Hash{0}}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support int/uint(8/16/32/64) types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{ | 
					
						
							|  |  |  | 				{int8(-2)}, | 
					
						
							|  |  |  | 				{int16(-3)}, | 
					
						
							|  |  |  | 				{int32(-4)}, | 
					
						
							|  |  |  | 				{int64(-5)}, | 
					
						
							|  |  |  | 				{int8(1)}, | 
					
						
							|  |  |  | 				{int16(256)}, | 
					
						
							|  |  |  | 				{int32(65536)}, | 
					
						
							|  |  |  | 				{int64(4294967296)}, | 
					
						
							|  |  |  | 				{uint8(1)}, | 
					
						
							|  |  |  | 				{uint16(256)}, | 
					
						
							|  |  |  | 				{uint32(65536)}, | 
					
						
							|  |  |  | 				{uint64(4294967296)}, | 
					
						
							|  |  |  | 			}}, | 
					
						
							|  |  |  | 			[][]common.Hash{ | 
					
						
							|  |  |  | 				{common.Hash{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254}}, | 
					
						
							|  |  |  | 				{common.Hash{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253}}, | 
					
						
							|  |  |  | 				{common.Hash{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 252}}, | 
					
						
							|  |  |  | 				{common.Hash{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 251}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}}, | 
					
						
							|  |  |  | 				{common.Hash{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support string types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{{"hello world"}}}, | 
					
						
							|  |  |  | 			[][]common.Hash{{crypto.Keccak256Hash([]byte("hello world"))}}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"support byte slice types in topics", | 
					
						
							|  |  |  | 			args{[][]interface{}{{[]byte{1, 2, 3}}}}, | 
					
						
							|  |  |  | 			[][]common.Hash{{crypto.Keccak256Hash([]byte{1, 2, 3})}}, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	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) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | type args struct { | 
					
						
							|  |  |  | 	createObj func() interface{} | 
					
						
							|  |  |  | 	resultObj func() interface{} | 
					
						
							|  |  |  | 	resultMap func() map[string]interface{} | 
					
						
							|  |  |  | 	fields    abi.Arguments | 
					
						
							|  |  |  | 	topics    []common.Hash | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type bytesStruct struct { | 
					
						
							|  |  |  | 	StaticBytes [5]byte | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type int8Struct struct { | 
					
						
							|  |  |  | 	Int8Value int8 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | type int256Struct struct { | 
					
						
							|  |  |  | 	Int256Value *big.Int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type topicTest struct { | 
					
						
							|  |  |  | 	name    string | 
					
						
							|  |  |  | 	args    args | 
					
						
							|  |  |  | 	wantErr bool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setupTopicsTests() []topicTest { | 
					
						
							| 
									
										
										
										
											2019-10-31 21:17:51 +08:00
										 |  |  | 	bytesType, _ := abi.NewType("bytes5", "", nil) | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 	int8Type, _ := abi.NewType("int8", "", nil) | 
					
						
							|  |  |  | 	int256Type, _ := abi.NewType("int256", "", nil) | 
					
						
							| 
									
										
										
										
											2020-04-08 12:00:10 +02:00
										 |  |  | 	tupleType, _ := abi.NewType("tuple(int256,int8)", "", nil) | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tests := []topicTest{ | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			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}} }, | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 				resultMap: func() map[string]interface{} { | 
					
						
							|  |  |  | 					return map[string]interface{}{"staticBytes": [5]byte{1, 2, 3, 4, 5}} | 
					
						
							|  |  |  | 				}, | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 				fields: abi.Arguments{abi.Argument{ | 
					
						
							|  |  |  | 					Name:    "staticBytes", | 
					
						
							|  |  |  | 					Type:    bytesType, | 
					
						
							|  |  |  | 					Indexed: true, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				topics: []common.Hash{ | 
					
						
							|  |  |  | 					{1, 2, 3, 4, 5}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "int8 with negative value", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							|  |  |  | 				createObj: func() interface{} { return &int8Struct{} }, | 
					
						
							|  |  |  | 				resultObj: func() interface{} { return &int8Struct{Int8Value: -1} }, | 
					
						
							|  |  |  | 				resultMap: func() map[string]interface{} { | 
					
						
							|  |  |  | 					return map[string]interface{}{"int8Value": int8(-1)} | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				fields: abi.Arguments{abi.Argument{ | 
					
						
							|  |  |  | 					Name:    "int8Value", | 
					
						
							|  |  |  | 					Type:    int8Type, | 
					
						
							|  |  |  | 					Indexed: true, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				topics: []common.Hash{ | 
					
						
							|  |  |  | 					{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 
					
						
							|  |  |  | 						255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			name: "int256 with negative value", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							|  |  |  | 				createObj: func() interface{} { return &int256Struct{} }, | 
					
						
							|  |  |  | 				resultObj: func() interface{} { return &int256Struct{Int256Value: big.NewInt(-1)} }, | 
					
						
							|  |  |  | 				resultMap: func() map[string]interface{} { | 
					
						
							|  |  |  | 					return map[string]interface{}{"int256Value": big.NewInt(-1)} | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				fields: abi.Arguments{abi.Argument{ | 
					
						
							|  |  |  | 					Name:    "int256Value", | 
					
						
							|  |  |  | 					Type:    int256Type, | 
					
						
							|  |  |  | 					Indexed: true, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				topics: []common.Hash{ | 
					
						
							|  |  |  | 					{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 
					
						
							|  |  |  | 						255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: false, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2020-04-08 12:00:10 +02:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			name: "tuple(int256, int8)", | 
					
						
							|  |  |  | 			args: args{ | 
					
						
							|  |  |  | 				createObj: func() interface{} { return nil }, | 
					
						
							|  |  |  | 				resultObj: func() interface{} { return nil }, | 
					
						
							|  |  |  | 				resultMap: func() map[string]interface{} { return make(map[string]interface{}) }, | 
					
						
							|  |  |  | 				fields: abi.Arguments{abi.Argument{ | 
					
						
							|  |  |  | 					Name:    "tupletype", | 
					
						
							|  |  |  | 					Type:    tupleType, | 
					
						
							|  |  |  | 					Indexed: true, | 
					
						
							|  |  |  | 				}}, | 
					
						
							|  |  |  | 				topics: []common.Hash{}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			wantErr: true, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return tests | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestParseTopics(t *testing.T) { | 
					
						
							|  |  |  | 	tests := setupTopicsTests() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-28 12:47:24 -06:00
										 |  |  | 	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) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-12-18 19:16:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestParseTopicsIntoMap(t *testing.T) { | 
					
						
							|  |  |  | 	tests := setupTopicsTests() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, tt := range tests { | 
					
						
							|  |  |  | 		t.Run(tt.name, func(t *testing.T) { | 
					
						
							|  |  |  | 			outMap := make(map[string]interface{}) | 
					
						
							|  |  |  | 			if err := parseTopicsIntoMap(outMap, tt.args.fields, tt.args.topics); (err != nil) != tt.wantErr { | 
					
						
							|  |  |  | 				t.Errorf("parseTopicsIntoMap() error = %v, wantErr %v", err, tt.wantErr) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			resultMap := tt.args.resultMap() | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(outMap, resultMap) { | 
					
						
							|  |  |  | 				t.Errorf("parseTopicsIntoMap() = %v, want %v", outMap, resultMap) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |