From 159ea38c871ac4512ed2f87a586a69e6a9544542 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 001/280] accounts/abi: improve abi test coverage (#16044) --- accounts/abi/numbers.go | 36 +++++++++---------- accounts/abi/reflect.go | 20 +++++------ accounts/abi/type.go | 2 +- accounts/abi/type_test.go | 69 +++++++++++++++++++------------------ accounts/abi/unpack_test.go | 17 +++++++++ 5 files changed, 82 insertions(+), 62 deletions(-) diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go index d389db33b7..663ee6a99d 100644 --- a/accounts/abi/numbers.go +++ b/accounts/abi/numbers.go @@ -24,29 +24,29 @@ import ( ) var ( - big_t = reflect.TypeOf(&big.Int{}) - derefbig_t = reflect.TypeOf(big.Int{}) - uint8_t = reflect.TypeOf(uint8(0)) - uint16_t = reflect.TypeOf(uint16(0)) - uint32_t = reflect.TypeOf(uint32(0)) - uint64_t = reflect.TypeOf(uint64(0)) - int_t = reflect.TypeOf(int(0)) - int8_t = reflect.TypeOf(int8(0)) - int16_t = reflect.TypeOf(int16(0)) - int32_t = reflect.TypeOf(int32(0)) - int64_t = reflect.TypeOf(int64(0)) - address_t = reflect.TypeOf(common.Address{}) - int_ts = reflect.TypeOf([]int(nil)) - int8_ts = reflect.TypeOf([]int8(nil)) - int16_ts = reflect.TypeOf([]int16(nil)) - int32_ts = reflect.TypeOf([]int32(nil)) - int64_ts = reflect.TypeOf([]int64(nil)) + bigT = reflect.TypeOf(&big.Int{}) + derefbigT = reflect.TypeOf(big.Int{}) + uint8T = reflect.TypeOf(uint8(0)) + uint16T = reflect.TypeOf(uint16(0)) + uint32T = reflect.TypeOf(uint32(0)) + uint64T = reflect.TypeOf(uint64(0)) + intT = reflect.TypeOf(int(0)) + int8T = reflect.TypeOf(int8(0)) + int16T = reflect.TypeOf(int16(0)) + int32T = reflect.TypeOf(int32(0)) + int64T = reflect.TypeOf(int64(0)) + addressT = reflect.TypeOf(common.Address{}) + intTS = reflect.TypeOf([]int(nil)) + int8TS = reflect.TypeOf([]int8(nil)) + int16TS = reflect.TypeOf([]int16(nil)) + int32TS = reflect.TypeOf([]int32(nil)) + int64TS = reflect.TypeOf([]int64(nil)) ) // checks whether the given reflect value is signed. This also works for slices with a number type func isSigned(v reflect.Value) bool { switch v.Type() { - case int_ts, int8_ts, int16_ts, int32_ts, int64_ts, int_t, int8_t, int16_t, int32_t, int64_t: + case intTS, int8TS, int16TS, int32TS, int64TS, intT, int8T, int16T, int32T, int64T: return true } return false diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index b2755adf65..186cf307f2 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -25,7 +25,7 @@ import ( // indirect recursively dereferences the value until it either gets the value // or finds a big.Int func indirect(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbig_t { + if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { return indirect(v.Elem()) } return v @@ -37,26 +37,26 @@ func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) switch size { case 8: if unsigned { - return reflect.Uint8, uint8_t + return reflect.Uint8, uint8T } - return reflect.Int8, int8_t + return reflect.Int8, int8T case 16: if unsigned { - return reflect.Uint16, uint16_t + return reflect.Uint16, uint16T } - return reflect.Int16, int16_t + return reflect.Int16, int16T case 32: if unsigned { - return reflect.Uint32, uint32_t + return reflect.Uint32, uint32T } - return reflect.Int32, int32_t + return reflect.Int32, int32T case 64: if unsigned { - return reflect.Uint64, uint64_t + return reflect.Uint64, uint64T } - return reflect.Int64, int64_t + return reflect.Int64, int64T } - return reflect.Ptr, big_t + return reflect.Ptr, bigT } // mustArrayToBytesSlice creates a new byte slice with the exact same size as value diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 355ac3ac77..e127c8e374 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -140,7 +140,7 @@ func NewType(t string) (typ Type, err error) { typ.Type = reflect.TypeOf(bool(false)) case "address": typ.Kind = reflect.Array - typ.Type = address_t + typ.Type = addressT typ.Size = 20 typ.T = AddressTy case "string": diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index cb9787854c..a8c84430d7 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -46,36 +46,36 @@ func TestTypeRegexp(t *testing.T) { {"bool[2][2][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, {"bool[][][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, {"bool[][2][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, - {"int8", Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}}, - {"int16", Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}}, - {"int32", Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}}, - {"int64", Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}}, - {"int256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}}, - {"int8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, - {"int8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, - {"int16[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, - {"int16[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, - {"int32[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, - {"int32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, - {"int64[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, - {"int64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, - {"int256[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, - {"int256[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, - {"uint8", Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}}, - {"uint16", Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}}, - {"uint32", Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}}, - {"uint64", Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}}, - {"uint256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}}, - {"uint8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, - {"uint8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, - {"uint16[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, - {"uint16[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, - {"uint32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, - {"uint32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, - {"uint64[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, - {"uint64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, - {"uint256[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, - {"uint256[2]", Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, + {"int8", Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, + {"int16", Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, + {"int32", Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, + {"int64", Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, + {"int256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, + {"int8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, + {"int8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, + {"int16[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, + {"int16[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, + {"int32[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, + {"int32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, + {"int64[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, + {"int64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, + {"int256[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, + {"int256[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, + {"uint8", Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, + {"uint16", Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, + {"uint32", Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, + {"uint64", Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, + {"uint256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, + {"uint8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, + {"uint8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, + {"uint16[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, + {"uint16[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, + {"uint32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, + {"uint32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, + {"uint64[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, + {"uint64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, + {"uint256[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, + {"uint256[2]", Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, {"bytes32", Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, {"bytes[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Kind: reflect.Slice, Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, {"bytes[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), Kind: reflect.Slice, stringKind: "bytes"}, stringKind: "bytes[2]"}}, @@ -84,9 +84,9 @@ func TestTypeRegexp(t *testing.T) { {"string", Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, {"string[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, {"string[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, - {"address", Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}}, - {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, - {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, + {"address", Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, + {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, + {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, // TODO when fixed types are implemented properly // {"fixed", Type{}}, // {"fixed128x128", Type{}}, @@ -252,6 +252,9 @@ func TestTypeCheck(t *testing.T) { {"bytes20", common.Address{}, ""}, {"address", [20]byte{}, ""}, {"address", common.Address{}, ""}, + {"bytes32[]]", "", "invalid arg type in abi"}, + {"invalidType", "", "unsupported arg type: invalidType"}, + {"invalidSlice[]", "", "unsupported arg type: invalidSlice"}, } { typ, err := NewType(test.typ) if err != nil && len(test.err) == 0 { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 5e39d0d0fb..cf85c4511e 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -56,6 +56,23 @@ var unpackTests = []unpackTest{ enc: "0000000000000000000000000000000000000000000000000000000000000001", want: true, }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000000000000000000", + want: false, + }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000001000000000001", + want: false, + err: "abi: improperly encoded boolean value", + }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000000000000000003", + want: false, + err: "abi: improperly encoded boolean value", + }, { def: `[{"type": "uint32"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", From 18a5493575431fe45e76662da4f93e85be921ff8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 002/280] accounts: add function UnmarshalJSON to parse URL (#16154) --- accounts/url.go | 16 ++++++++++++++++ accounts/usbwallet/hub.go | 2 +- accounts/usbwallet/wallet.go | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/accounts/url.go b/accounts/url.go index d5c9c645c7..c61d651116 100644 --- a/accounts/url.go +++ b/accounts/url.go @@ -74,6 +74,22 @@ func (u URL) MarshalJSON() ([]byte, error) { return json.Marshal(u.String()) } +// UnmarshalJSON parses url. +func (u *URL) UnmarshalJSON(input []byte) error { + var textUrl string + err := json.Unmarshal(input, &textUrl) + if err != nil { + return err + } + url, err := parseURL(textUrl) + if err != nil { + return err + } + u.Scheme = url.Scheme + u.Path = url.Path + return nil +} + // Cmp compares x and y and returns: // // -1 if x < y diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 4594c0a6c2..2ec78d859d 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -127,7 +127,7 @@ func (hub *Hub) refreshWallets() { // breaking the Ledger protocol if that is waiting for user confirmation. This // is a bug acknowledged at Ledger, but it won't be fixed on old devices so we // need to prevent concurrent comms ourselves. The more elegant solution would - // be to ditch enumeration in favor of hutplug events, but that don't work yet + // be to ditch enumeration in favor of hotplug events, but that don't work yet // on Windows so if we need to hack it anyway, this is more elegant for now. hub.commsLock.Lock() if hub.commsPend > 0 { // A confirmation is pending, don't refresh diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 020a193d75..6778c2e015 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -99,7 +99,7 @@ type wallet struct { // // As such, a hardware wallet needs two locks to function correctly. A state // lock can be used to protect the wallet's software-side internal state, which - // must not be held exlusively during hardware communication. A communication + // must not be held exclusively during hardware communication. A communication // lock can be used to achieve exclusive access to the device itself, this one // however should allow "skipping" waiting for operations that might want to // use the device, but can live without too (e.g. account self-derivation). From fbe415c975bb3c003df31bf7a199fb3eb53a961c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 003/280] accounts/usbwallet: remove unused variables in ledger.go (#16446) --- accounts/usbwallet/ledger.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 005a022783..a372b6a215 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -54,11 +54,9 @@ const ( ledgerOpGetConfiguration ledgerOpcode = 0x06 // Returns specific wallet application configuration ledgerP1DirectlyFetchAddress ledgerParam1 = 0x00 // Return address directly from the wallet - ledgerP1ConfirmFetchAddress ledgerParam1 = 0x01 // Require a user confirmation before returning the address ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address - ledgerP2ReturnAddressChainCode ledgerParam2 = 0x01 // Require a user confirmation before returning the address ) // errLedgerReplyInvalidHeader is the error message returned by a Ledger data exchange From 543900aed2129b837ecd7da443a9fdf3b14b20bb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 004/280] accounts: changed if-else blocks to conform with golint (#16654) --- accounts/keystore/keystore_passphrase.go | 3 +-- accounts/keystore/keystore_plain.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index a58d152b1c..0c8e621bfe 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -108,9 +108,8 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er func (ks keyStorePassphrase) JoinPath(filename string) string { if filepath.IsAbs(filename) { return filename - } else { - return filepath.Join(ks.keysDirPath, filename) } + return filepath.Join(ks.keysDirPath, filename) } // EncryptKey encrypts a key using the specified scrypt parameters into a json diff --git a/accounts/keystore/keystore_plain.go b/accounts/keystore/keystore_plain.go index 045a9cc042..15bfe64a7e 100644 --- a/accounts/keystore/keystore_plain.go +++ b/accounts/keystore/keystore_plain.go @@ -56,7 +56,6 @@ func (ks keyStorePlain) StoreKey(filename string, key *Key, auth string) error { func (ks keyStorePlain) JoinPath(filename string) string { if filepath.IsAbs(filename) { return filename - } else { - return filepath.Join(ks.keysDirPath, filename) } + return filepath.Join(ks.keysDirPath, filename) } From 27725104b4255883a89d70dde19b1838bdd79587 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 005/280] accounts/keystore: assign schema as const instead of var (#16985) --- accounts/keystore/keystore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 80ac1102d3..d4ea66f2e4 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -49,7 +49,7 @@ var ( var KeyStoreType = reflect.TypeOf(&KeyStore{}) // KeyStoreScheme is the protocol scheme prefixing account and wallet URLs. -var KeyStoreScheme = "keystore" +const KeyStoreScheme = "keystore" // Maximum time between wallet refreshes (if filesystem notifications don't work). const walletRefreshCycle = 3 * time.Second From 8d2fb8c28090383340b0828a16b59761abf2bb43 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 006/280] accounts/usbwallet: correct comment typo (#17008) --- accounts/usbwallet/ledger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index a372b6a215..063384b1c2 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -303,7 +303,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction for i, component := range derivationPath { binary.BigEndian.PutUint32(path[1+4*i:], component) } - // Create the transaction RLP based on whether legacy or EIP155 signing was requeste + // Create the transaction RLP based on whether legacy or EIP155 signing was requested var ( txrlp []byte err error From e5b484b63b0fd40e8dc8a9d7ebfa89e32d27c50b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 007/280] accounts/usbwallet: correct comment typo (#16998) --- accounts/usbwallet/internal/trezor/trezor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/internal/trezor/trezor.go b/accounts/usbwallet/internal/trezor/trezor.go index 8ae9e726e4..80cc75efc4 100644 --- a/accounts/usbwallet/internal/trezor/trezor.go +++ b/accounts/usbwallet/internal/trezor/trezor.go @@ -36,7 +36,7 @@ func Type(msg proto.Message) uint16 { } // Name returns the friendly message type name of a specific protocol buffer -// type numbers. +// type number. func Name(kind uint16) string { name := MessageType_name[int32(kind)] if len(name) < 12 { From 8577f6913da472466d7cb5c662c265210a7c0d72 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:06 +0800 Subject: [PATCH 008/280] accounts/abi: remove deadcode isSigned (#16990) --- accounts/abi/numbers.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go index 663ee6a99d..e265d3f57c 100644 --- a/accounts/abi/numbers.go +++ b/accounts/abi/numbers.go @@ -30,24 +30,9 @@ var ( uint16T = reflect.TypeOf(uint16(0)) uint32T = reflect.TypeOf(uint32(0)) uint64T = reflect.TypeOf(uint64(0)) - intT = reflect.TypeOf(int(0)) int8T = reflect.TypeOf(int8(0)) int16T = reflect.TypeOf(int16(0)) int32T = reflect.TypeOf(int32(0)) int64T = reflect.TypeOf(int64(0)) addressT = reflect.TypeOf(common.Address{}) - intTS = reflect.TypeOf([]int(nil)) - int8TS = reflect.TypeOf([]int8(nil)) - int16TS = reflect.TypeOf([]int16(nil)) - int32TS = reflect.TypeOf([]int32(nil)) - int64TS = reflect.TypeOf([]int64(nil)) ) - -// checks whether the given reflect value is signed. This also works for slices with a number type -func isSigned(v reflect.Value) bool { - switch v.Type() { - case intTS, int8TS, int16TS, int32TS, int64TS, intT, int8T, int16T, int32T, int64T: - return true - } - return false -} From b9f9de7b74e983d263721e4ce1afa6d1e9020251 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 009/280] accounts: add unit tests for URL (#17182) --- accounts/url.go | 6 +-- accounts/url_test.go | 102 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 accounts/url_test.go diff --git a/accounts/url.go b/accounts/url.go index c61d651116..39b00e5b44 100644 --- a/accounts/url.go +++ b/accounts/url.go @@ -76,12 +76,12 @@ func (u URL) MarshalJSON() ([]byte, error) { // UnmarshalJSON parses url. func (u *URL) UnmarshalJSON(input []byte) error { - var textUrl string - err := json.Unmarshal(input, &textUrl) + var textURL string + err := json.Unmarshal(input, &textURL) if err != nil { return err } - url, err := parseURL(textUrl) + url, err := parseURL(textURL) if err != nil { return err } diff --git a/accounts/url_test.go b/accounts/url_test.go new file mode 100644 index 0000000000..f481a1016d --- /dev/null +++ b/accounts/url_test.go @@ -0,0 +1,102 @@ +// 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 . + +package accounts + +import ( + "testing" +) + +func TestURLParsing(t *testing.T) { + t.Parallel() + url, err := parseURL("https://ethereum.org") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if url.Scheme != "https" { + t.Errorf("expected: %v, got: %v", "https", url.Scheme) + } + if url.Path != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "ethereum.org", url.Path) + } + + for _, u := range []string{"ethereum.org", ""} { + if _, err = parseURL(u); err == nil { + t.Errorf("input %v, expected err, got: nil", u) + } + } +} + +func TestURLString(t *testing.T) { + t.Parallel() + url := URL{Scheme: "https", Path: "ethereum.org"} + if url.String() != "https://ethereum.org" { + t.Errorf("expected: %v, got: %v", "https://ethereum.org", url.String()) + } + + url = URL{Scheme: "", Path: "ethereum.org"} + if url.String() != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "ethereum.org", url.String()) + } +} + +func TestURLMarshalJSON(t *testing.T) { + t.Parallel() + url := URL{Scheme: "https", Path: "ethereum.org"} + json, err := url.MarshalJSON() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if string(json) != "\"https://ethereum.org\"" { + t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json)) + } +} + +func TestURLUnmarshalJSON(t *testing.T) { + t.Parallel() + url := &URL{} + err := url.UnmarshalJSON([]byte("\"https://ethereum.org\"")) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if url.Scheme != "https" { + t.Errorf("expected: %v, got: %v", "https", url.Scheme) + } + if url.Path != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "https", url.Path) + } +} + +func TestURLComparison(t *testing.T) { + t.Parallel() + tests := []struct { + urlA URL + urlB URL + expect int + }{ + {URL{"https", "ethereum.org"}, URL{"https", "ethereum.org"}, 0}, + {URL{"http", "ethereum.org"}, URL{"https", "ethereum.org"}, -1}, + {URL{"https", "ethereum.org/a"}, URL{"https", "ethereum.org"}, 1}, + {URL{"https", "abc.org"}, URL{"https", "ethereum.org"}, -1}, + } + + for i, tt := range tests { + result := tt.urlA.Cmp(tt.urlB) + if result != tt.expect { + t.Errorf("test %d: cmp mismatch: expected: %d, got: %d", i, tt.expect, result) + } + } +} From c5c876a7e76e3d37282bef29a7981ffa41197f22 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 010/280] accounts/abi: refactor Method#Sig() to use index in range iterator directly (#17198) --- accounts/abi/method.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 46beedefb6..d49e555c94 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -47,10 +47,8 @@ type Method struct { // Please note that "int" is substitute for its canonical representation "int256" func (method Method) Sig() string { types := make([]string, len(method.Inputs)) - i := 0 - for _, input := range method.Inputs { + for i, input := range method.Inputs { types[i] = input.Type.String() - i++ } return fmt.Sprintf("%v(%v)", method.Name, strings.Join(types, ",")) } From ed67fd420061a4bc1acd1512311f95975b81a9a3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 011/280] crypto/secp256k1: remove external LGPL dependencies (#17239) --- accounts/keystore/keystore_passphrase.go | 17 +++++++--- crypto/randentropy/rand_entropy.go | 42 ------------------------ 2 files changed, 12 insertions(+), 47 deletions(-) delete mode 100644 crypto/randentropy/rand_entropy.go diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 0c8e621bfe..9d29b7fa97 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -28,18 +28,18 @@ package keystore import ( "bytes" "crypto/aes" - crand "crypto/rand" + "crypto/rand" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" + "io" "os" "path/filepath" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/crypto/randentropy" "github.com/pborman/uuid" "golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/scrypt" @@ -93,7 +93,7 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) // StoreKey generates a key, encrypts with 'auth' and stores in the given directory func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) { - _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, crand.Reader, auth) + _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, rand.Reader, auth) return a.Address, err } @@ -116,7 +116,11 @@ func (ks keyStorePassphrase) JoinPath(filename string) string { // blob that can be decrypted later on. func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { authArray := []byte(auth) - salt := randentropy.GetEntropyCSPRNG(32) + + salt := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, salt); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen) if err != nil { return nil, err @@ -124,7 +128,10 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { encryptKey := derivedKey[:16] keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) - iv := randentropy.GetEntropyCSPRNG(aes.BlockSize) // 16 + iv := make([]byte, aes.BlockSize) // 16 + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv) if err != nil { return nil, err diff --git a/crypto/randentropy/rand_entropy.go b/crypto/randentropy/rand_entropy.go deleted file mode 100644 index 539d3ac894..0000000000 --- a/crypto/randentropy/rand_entropy.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 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 . - -package randentropy - -import ( - crand "crypto/rand" - "io" -) - -var Reader io.Reader = &randEntropy{} - -type randEntropy struct { -} - -func (*randEntropy) Read(bytes []byte) (n int, err error) { - readBytes := GetEntropyCSPRNG(len(bytes)) - copy(bytes, readBytes) - return len(bytes), nil -} - -func GetEntropyCSPRNG(n int) []byte { - mainBuff := make([]byte, n) - _, err := io.ReadFull(crand.Reader, mainBuff) - if err != nil { - panic("reading from crypto/rand failed: " + err.Error()) - } - return mainBuff -} From 165510daefd636b7c930f75eb7a73fc3cdd2cb48 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 012/280] accounts/keystore: rename skipKeyFile to nonKeyFile to better reveal the function purpose (#17290) --- accounts/keystore/file_cache.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index 0ef6e28dc7..08a4ca1c59 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -55,20 +55,20 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er var newLastMod time.Time for _, fi := range files { - // Skip any non-key files from the folder path := filepath.Join(keyDir, fi.Name()) - fiInfo, err := fi.Info() - if err != nil { - log.Warn("scan get FileInfo", "err", err, "path", path) - } - if fiInfo == nil || skipKeyFile(fiInfo) { + // Skip any non-key files from the folder + if nonKeyFile(fi) { log.Trace("Ignoring file on account scan", "path", path) continue } // Gather the set of all and fresly modified files all.Add(path) - modified := fiInfo.ModTime() + info, err := fi.Info() + if err != nil { + return nil, nil, nil, err + } + modified := info.ModTime() if modified.After(fc.lastMod) { mods.Add(path) } @@ -91,15 +91,14 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er return creates, deletes, updates, nil } -// skipKeyFile ignores editor backups, hidden files and folders/symlinks. -func skipKeyFile(fi os.FileInfo) bool { +// nonKeyFile ignores editor backups, hidden files and folders/symlinks. +func nonKeyFile(fi os.DirEntry) bool { // Skip editor backups and UNIX-style hidden files. - name := fi.Name() - if strings.HasSuffix(name, "~") || strings.HasPrefix(name, ".") { + if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") { return true } // Skip misc special files, directories (yes, symlinks too). - if fi.IsDir() || fi.Mode()&os.ModeType != 0 { + if fi.IsDir() || !fi.Type().IsRegular() { return true } return false From eb90b2899f4bb23037d19aa66611aa65ef9219b0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 013/280] backends: increase gaslimit in order to allow tests of large contracts (#17358) --- accounts/abi/bind/backends/simulated.go | 5 +++-- contracts/randomize/randomize_test.go | 2 +- contracts/tests/Inherited_test.go | 9 +++++---- contracts/trc21issuer/trc21issuer_test.go | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index ea79ab4484..15d7edc7e1 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -141,10 +141,11 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. +// // A simulated backend always uses chainID 1337. -func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend { +func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { database := rawdb.NewMemoryDatabase() - genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc, GasLimit: 42000000} + genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} genesis.MustCommit(database) blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}) diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go index 14d229196c..fd117681f1 100644 --- a/contracts/randomize/randomize_test.go +++ b/contracts/randomize/randomize_test.go @@ -73,7 +73,7 @@ func TestRandomize(t *testing.T) { func TestSendTxRandomizeSecretAndOpening(t *testing.T) { genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} - backend := backends.NewSimulatedBackend(genesis) + backend := backends.NewSimulatedBackend(genesis, 42000000) backend.Commit() signer := types.HomesteadSigner{} ctx := context.Background() diff --git a/contracts/tests/Inherited_test.go b/contracts/tests/Inherited_test.go index 94298fc0e3..a60fa6344f 100644 --- a/contracts/tests/Inherited_test.go +++ b/contracts/tests/Inherited_test.go @@ -2,15 +2,16 @@ package tests import ( "fmt" + "math/big" + "os" + "testing" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" - "math/big" - "os" - "testing" ) var ( @@ -27,7 +28,7 @@ func TestPriceFeed(t *testing.T) { // init genesis contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, - }) + }, 42000000) transactOpts := bind.NewKeyedTransactor(mainKey) // deploy payer swap SMC addr, contract, err := DeployMyInherited(transactOpts, contractBackend) diff --git a/contracts/trc21issuer/trc21issuer_test.go b/contracts/trc21issuer/trc21issuer_test.go index a8658b105b..aeebb7b7ad 100644 --- a/contracts/trc21issuer/trc21issuer_test.go +++ b/contracts/trc21issuer/trc21issuer_test.go @@ -33,7 +33,7 @@ func TestFeeTxWithTRC21Token(t *testing.T) { // init genesis contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, - }) + }, 42000000) transactOpts := bind.NewKeyedTransactor(mainKey) // deploy payer swap SMC trc21IssuerAddr, trc21Issuer, err := DeployTRC21Issuer(transactOpts, contractBackend, minApply) From 906551bfbd83edaa6e5fcfc29abbbe930ba2e0de Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 014/280] accounts: fixed typo (#17421) --- accounts/accounts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 157112c8c1..f6dd18ff17 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -95,7 +95,7 @@ type Wallet interface { // or optionally with the aid of any location metadata from the embedded URL field. // // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code o verify the transaction), + // a password to decrypt the account, or a PIN code to verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock @@ -108,7 +108,7 @@ type Wallet interface { // or optionally with the aid of any location metadata from the embedded URL field. // // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code o verify the transaction), + // a password to decrypt the account, or a PIN code to verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing // the needed details via SignTxWithPassphrase, or by other means (e.g. unlock From 002fac8b140604a874a0f41b05d0594cd632485d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 015/280] all: remove the duplicate 'the' in annotations (#17509) --- common/bitutil/compress_test.go | 4 ++-- console/prompter.go | 4 ++-- core/block_validator.go | 2 +- core/state_processor.go | 4 ++-- eth/downloader/queue.go | 2 +- eth/fetcher/fetcher.go | 2 +- node/rpcstack.go | 2 +- p2p/server.go | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go index 84f624f46c..377dbb0ea9 100644 --- a/common/bitutil/compress_test.go +++ b/common/bitutil/compress_test.go @@ -122,7 +122,7 @@ func TestDecodingCycle(t *testing.T) { // TestCompression tests that compression works by returning either the bitset // encoded input, or the actual input if the bitset version is longer. func TestCompression(t *testing.T) { - // Check the the compression returns the bitset encoding is shorter + // Check the compression returns the bitset encoding is shorter in := hexutil.MustDecode("0x4912385c0e7b64000000") out := hexutil.MustDecode("0x80fe4912385c0e7b64") @@ -132,7 +132,7 @@ func TestCompression(t *testing.T) { if data, err := DecompressBytes(out, len(in)); err != nil || !bytes.Equal(data, in) { t.Errorf("decoding mismatch for sparse data: have %x, want %x, error %v", data, in, err) } - // Check the the compression returns the input if the bitset encoding is longer + // Check the compression returns the input if the bitset encoding is longer in = hexutil.MustDecode("0xdf7070533534333636313639343638373532313536346c1bc33339343837313070706336343035336336346c65fefb3930393233383838ac2f65fefb") out = hexutil.MustDecode("0xdf7070533534333636313639343638373532313536346c1bc33339343837313070706336343035336336346c65fefb3930393233383838ac2f65fefb") diff --git a/console/prompter.go b/console/prompter.go index c477b48178..3769d52f67 100644 --- a/console/prompter.go +++ b/console/prompter.go @@ -43,7 +43,7 @@ type UserPrompter interface { // choice to be made, returning that choice. PromptConfirm(prompt string) (bool, error) - // SetHistory sets the the input scrollback history that the prompter will allow + // SetHistory sets the input scrollback history that the prompter will allow // the user to scroll back to. SetHistory(history []string) @@ -149,7 +149,7 @@ func (p *terminalPrompter) PromptConfirm(prompt string) (bool, error) { return false, err } -// SetHistory sets the the input scrollback history that the prompter will allow +// SetHistory sets the input scrollback history that the prompter will allow // the user to scroll back to. func (p *terminalPrompter) SetHistory(history []string) { p.State.ReadHistory(strings.NewReader(strings.Join(history, "\n"))) diff --git a/core/block_validator.go b/core/block_validator.go index e713342d9c..d139b2d8fe 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -51,7 +51,7 @@ func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engin return validator } -// ValidateBody validates the given block's uncles and verifies the the block +// ValidateBody validates the given block's uncles and verifies the block // header's transaction and uncle roots. The headers are assumed to be already // validated at this point. func (v *BlockValidator) ValidateBody(block *types.Block) error { diff --git a/core/state_processor.go b/core/state_processor.go index 2f7980db63..3a503f1c18 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -76,7 +76,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra allLogs []*types.Log gp = new(GasPool).AddGas(block.GasLimit()) ) - // Mutate the the block and state according to any hard-fork specs + // Mutate the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } @@ -148,7 +148,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated allLogs []*types.Log gp = new(GasPool).AddGas(block.GasLimit()) ) - // Mutate the the block and state according to any hard-fork specs + // Mutate the block and state according to any hard-fork specs if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 115a780f92..4815207307 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -665,7 +665,7 @@ func (q *queue) expire(timeout time.Duration, pendPool map[string]*fetchRequest, for _, header := range request.Headers { taskQueue.(*prque.Prque[int64, *types.Header]).Push(header, -int64(header.Number.Uint64())) } - // Add the peer to the expiry report along the the number of failed requests + // Add the peer to the expiry report along the number of failed requests expiries[id] = len(request.Headers) } } diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index f8cf67f23c..0aa0857331 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -216,7 +216,7 @@ func (f *Fetcher) Notify(peer string, hash common.Hash, number uint64, time time } } -// Enqueue tries to fill gaps the the fetcher's future import queue. +// Enqueue tries to fill gaps the fetcher's future import queue. func (f *Fetcher) Enqueue(peer string, block *types.Block) error { op := &inject{ origin: peer, diff --git a/node/rpcstack.go b/node/rpcstack.go index 2de884f4c3..f1792cffc6 100644 --- a/node/rpcstack.go +++ b/node/rpcstack.go @@ -150,7 +150,7 @@ func newGzipHandler(next http.Handler) http.Handler { } // NewWebsocketUpgradeHandler returns a websocket handler that serves an incoming request only if it contains an upgrade -// request to the websocket protocol. If not, serves the the request with the http handler. +// request to the websocket protocol. If not, serves the request with the http handler. func NewWebsocketUpgradeHandler(h http.Handler, ws http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if isWebsocket(r) { diff --git a/p2p/server.go b/p2p/server.go index a2cdb17077..fc5b40a9ab 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -76,7 +76,7 @@ type Config struct { // Disabling is useful for protocol debugging (manual topology). NoDiscovery bool - // DiscoveryV5 specifies whether the the new topic-discovery based V5 discovery + // DiscoveryV5 specifies whether the new topic-discovery based V5 discovery // protocol should be started or not. DiscoveryV5 bool `toml:",omitempty"` From de16c7571f661946041b92fa3742c7062ee68df2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 016/280] accounts/abi: fix unpacking of negative int256 (#17583) --- accounts/abi/unpack.go | 28 +++++++++++++++++++++++++--- accounts/abi/unpack_test.go | 5 +++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index ff2bacebbc..171ca7d4cf 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -26,8 +26,17 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" ) +var ( + maxUint256 = big.NewInt(0).Add( + big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil), + big.NewInt(-1)) + maxInt256 = big.NewInt(0).Add( + big.NewInt(0).Exp(big.NewInt(2), big.NewInt(255), nil), + big.NewInt(-1)) +) + // reads the integer based on its kind -func readInteger(kind reflect.Kind, b []byte) interface{} { +func readInteger(typ byte, kind reflect.Kind, b []byte) interface{} { switch kind { case reflect.Uint8: return b[len(b)-1] @@ -46,7 +55,20 @@ func readInteger(kind reflect.Kind, b []byte) interface{} { case reflect.Int64: return int64(binary.BigEndian.Uint64(b[len(b)-8:])) default: - return new(big.Int).SetBytes(b) + // the only case lefts for integer is int256/uint256. + // big.SetBytes can't tell if a number is negative, positive on itself. + // On EVM, if the returned number > max int256, it is negative. + ret := new(big.Int).SetBytes(b) + if typ == UintTy { + return ret + } + + if ret.Cmp(maxInt256) > 0 { + ret.Add(maxUint256, big.NewInt(0).Neg(ret)) + ret.Add(ret, big.NewInt(1)) + ret.Neg(ret) + } + return ret } } @@ -180,7 +202,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { case StringTy: // variable arrays are written at the end of the return bytes return string(output[begin : begin+end]), nil case IntTy, UintTy: - return readInteger(t.Kind, returnOutput), nil + return readInteger(t.T, t.Kind, returnOutput), nil case BoolTy: return readBool(returnOutput) case AddressTy: diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index cf85c4511e..d18ed50052 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -117,6 +117,11 @@ var unpackTests = []unpackTest{ enc: "0000000000000000000000000000000000000000000000000000000000000001", want: big.NewInt(1), }, + { + def: `[{"type": "int256"}]`, + enc: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + want: big.NewInt(-1), + }, { def: `[{"type": "address"}]`, enc: "0000000000000000000000000100000000000000000000000000000000000000", From 2154607a5f0e3e9535d24bf1414e61db40da320a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 017/280] accounts/keystore: double-check keystore file after creation (#17348) --- accounts/keystore/key.go | 18 +++++++++++----- accounts/keystore/keystore.go | 2 +- accounts/keystore/keystore_passphrase.go | 26 ++++++++++++++++++++++-- accounts/keystore/keystore_plain_test.go | 4 ++-- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index 7bb300fb82..c840d8926e 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -177,26 +177,34 @@ func storeNewKey(ks keyStore, rand io.Reader, auth string) (*Key, accounts.Accou return key, a, err } -func writeKeyFile(file string, content []byte) error { +func writeTemporaryKeyFile(file string, content []byte) (string, error) { // Create the keystore directory with appropriate permissions // in case it is not present yet. const dirPerm = 0700 if err := os.MkdirAll(filepath.Dir(file), dirPerm); err != nil { - return err + return "", err } // Atomic write: create a temporary hidden file first // then move it into place. TempFile assigns mode 0600. f, err := os.CreateTemp(filepath.Dir(file), "."+filepath.Base(file)+".tmp") if err != nil { - return err + return "", err } if _, err := f.Write(content); err != nil { f.Close() os.Remove(f.Name()) - return err + return "", err } f.Close() - return os.Rename(f.Name(), file) + return f.Name(), nil +} + +func writeKeyFile(file string, content []byte) error { + name, err := writeTemporaryKeyFile(file, content) + if err != nil { + return err + } + return os.Rename(name, file) } // keyFileName implements the naming convention for keyfiles: diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index d4ea66f2e4..617e8aa2fc 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -77,7 +77,7 @@ type unlocked struct { // NewKeyStore creates a keystore for the given directory. func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { keydir, _ = filepath.Abs(keydir) - ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP}} + ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP, false}} ks.init(keydir) return ks } diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 9d29b7fa97..93d68c9721 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -72,6 +72,10 @@ type keyStorePassphrase struct { keysDirPath string scryptN int scryptP int + // skipKeyFileVerification disables the security-feature which does + // reads and decrypts any newly created keyfiles. This should be 'false' in all + // cases except tests -- setting this to 'true' is not recommended. + skipKeyFileVerification bool } func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { @@ -93,7 +97,7 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) // StoreKey generates a key, encrypts with 'auth' and stores in the given directory func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) { - _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, rand.Reader, auth) + _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP, false}, rand.Reader, auth) return a.Address, err } @@ -102,7 +106,25 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er if err != nil { return err } - return writeKeyFile(filename, keyjson) + // Write into temporary file + tmpName, err := writeTemporaryKeyFile(filename, keyjson) + if err != nil { + return err + } + if !ks.skipKeyFileVerification { + // Verify that we can decrypt the file with the given password. + _, err = ks.GetKey(key.Address, tmpName, auth) + if err != nil { + msg := "an error was encountered when saving and verifying the keystore file. \n" + + "This indicates that the keystore is corrupted. \n" + + "The corrupted file is stored at \n%v\n" + + "Please file a ticket at:\n\n" + + "https://github.com/ethereum/go-ethereum/issues." + + "The error was : %s" + return fmt.Errorf(msg, tmpName, err) + } + } + return os.Rename(tmpName, filename) } func (ks keyStorePassphrase) JoinPath(filename string) string { diff --git a/accounts/keystore/keystore_plain_test.go b/accounts/keystore/keystore_plain_test.go index 69dee3e3dd..a42c75c4ad 100644 --- a/accounts/keystore/keystore_plain_test.go +++ b/accounts/keystore/keystore_plain_test.go @@ -36,7 +36,7 @@ func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { t.Fatal(err) } if encrypted { - ks = &keyStorePassphrase{d, veryLightScryptN, veryLightScryptP} + ks = &keyStorePassphrase{d, veryLightScryptN, veryLightScryptP, true} } else { ks = &keyStorePlain{d} } @@ -190,7 +190,7 @@ func TestV1_1(t *testing.T) { func TestV1_2(t *testing.T) { t.Parallel() - ks := &keyStorePassphrase{"testdata/v1", LightScryptN, LightScryptP} + ks := &keyStorePassphrase{"testdata/v1", LightScryptN, LightScryptP, true} addr := common.HexToAddress("cb61d5a9c4896fb9658090b597ef0e7be6f7b67e") file := "testdata/v1/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e" k, err := ks.GetKey(addr, file, "g") From e2ea9e87b59d42ef92ddee477358d7eab8431e7e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 018/280] accounts/abi: fix panic in MethodById lookup (#17798) --- accounts/abi/abi.go | 3 +++ accounts/abi/abi_test.go | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 0ca97525cd..0c68a0a1ee 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -140,6 +140,9 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { // MethodById looks up a method by the 4-byte id // returns nil if none found func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { + if len(sigdata) < 4 { + return nil, fmt.Errorf("data too short (% bytes) for abi method lookup", len(sigdata)) + } for _, method := range abi.Methods { if bytes.Equal(method.Id(), sigdata[:4]) { return &method, nil diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 968cdb6941..e952c0bc7f 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -716,7 +716,16 @@ func TestABI_MethodById(t *testing.T) { t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, hexutil.Encode(m.Id())) } } - + // Also test empty + if _, err := abi.MethodById([]byte{0x00}); err == nil { + t.Errorf("Expected error, too short to decode data") + } + if _, err := abi.MethodById([]byte{}); err == nil { + t.Errorf("Expected error, too short to decode data") + } + if _, err := abi.MethodById(nil); err == nil { + t.Errorf("Expected error, nil is short to decode data") + } } func TestUnpackRevert(t *testing.T) { From c0acd9c3ad8f734ce6169b684166e1717ac32145 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 019/280] accounts/keystore: encrypt the master seed on disk (#17704) --- accounts/keystore/key.go | 6 +- accounts/keystore/keystore_passphrase.go | 77 ++++++++++++++---------- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index c840d8926e..fb7372c0db 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -64,19 +64,19 @@ type plainKeyJSON struct { type encryptedKeyJSONV3 struct { Address string `json:"address"` - Crypto cryptoJSON `json:"crypto"` + Crypto CryptoJSON `json:"crypto"` Id string `json:"id"` Version int `json:"version"` } type encryptedKeyJSONV1 struct { Address string `json:"address"` - Crypto cryptoJSON `json:"crypto"` + Crypto CryptoJSON `json:"crypto"` Id string `json:"id"` Version string `json:"version"` } -type cryptoJSON struct { +type CryptoJSON struct { Cipher string `json:"cipher"` CipherText string `json:"ciphertext"` CipherParams cipherparamsJSON `json:"cipherparams"` diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 93d68c9721..4577efee52 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -134,29 +134,25 @@ func (ks keyStorePassphrase) JoinPath(filename string) string { return filepath.Join(ks.keysDirPath, filename) } -// EncryptKey encrypts a key using the specified scrypt parameters into a json -// blob that can be decrypted later on. -func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { - authArray := []byte(auth) - +// Encryptdata encrypts the data given as 'data' with the password 'auth'. +func EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) { salt := make([]byte, 32) if _, err := io.ReadFull(rand.Reader, salt); err != nil { panic("reading from crypto/rand failed: " + err.Error()) } - derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen) + derivedKey, err := scrypt.Key(auth, salt, scryptN, scryptR, scryptP, scryptDKLen) if err != nil { - return nil, err + return CryptoJSON{}, err } encryptKey := derivedKey[:16] - keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) iv := make([]byte, aes.BlockSize) // 16 if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic("reading from crypto/rand failed: " + err.Error()) } - cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv) + cipherText, err := aesCTRXOR(encryptKey, data, iv) if err != nil { - return nil, err + return CryptoJSON{}, err } mac := crypto.Keccak256(derivedKey[16:32], cipherText) @@ -166,12 +162,11 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { scryptParamsJSON["p"] = scryptP scryptParamsJSON["dklen"] = scryptDKLen scryptParamsJSON["salt"] = hex.EncodeToString(salt) - cipherParamsJSON := cipherparamsJSON{ IV: hex.EncodeToString(iv), } - cryptoStruct := cryptoJSON{ + cryptoStruct := CryptoJSON{ Cipher: "aes-128-ctr", CipherText: hex.EncodeToString(cipherText), CipherParams: cipherParamsJSON, @@ -179,9 +174,19 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { KDFParams: scryptParamsJSON, MAC: hex.EncodeToString(mac), } + return cryptoStruct, nil +} + +// EncryptKey encrypts a key using the specified scrypt parameters into a json +// blob that can be decrypted later on. +func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { + keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) + cryptoStruct, err := EncryptDataV3(keyBytes, []byte(auth), scryptN, scryptP) + if err != nil { + return nil, err + } encryptedKeyJSONV3 := encryptedKeyJSONV3{ - // hex.EncodeToString(key.Address[:]), - key.Address.String(), + hex.EncodeToString(key.Address[:]), cryptoStruct, key.Id.String(), version, @@ -227,42 +232,48 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { }, nil } -func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { - if keyProtected.Version != version { - return nil, nil, fmt.Errorf("not supported Version: %v", keyProtected.Version) +func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { + if cryptoJson.Cipher != "aes-128-ctr" { + return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher) } - - if keyProtected.Crypto.Cipher != "aes-128-ctr" { - return nil, nil, fmt.Errorf("not supported Cipher: %v", keyProtected.Crypto.Cipher) - } - - keyId = uuid.Parse(keyProtected.Id) - mac, err := hex.DecodeString(keyProtected.Crypto.MAC) + mac, err := hex.DecodeString(cryptoJson.MAC) if err != nil { - return nil, nil, err + return nil, err } - iv, err := hex.DecodeString(keyProtected.Crypto.CipherParams.IV) + iv, err := hex.DecodeString(cryptoJson.CipherParams.IV) if err != nil { - return nil, nil, err + return nil, err } - cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText) + cipherText, err := hex.DecodeString(cryptoJson.CipherText) if err != nil { - return nil, nil, err + return nil, err } - derivedKey, err := getKDFKey(keyProtected.Crypto, auth) + derivedKey, err := getKDFKey(cryptoJson, auth) if err != nil { - return nil, nil, err + return nil, err } calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText) if !bytes.Equal(calculatedMAC, mac) { - return nil, nil, ErrDecrypt + return nil, ErrDecrypt } plainText, err := aesCTRXOR(derivedKey[:16], cipherText, iv) + if err != nil { + return nil, err + } + return plainText, err +} + +func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { + if keyProtected.Version != version { + return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version) + } + keyId = uuid.Parse(keyProtected.Id) + plainText, err := DecryptDataV3(keyProtected.Crypto, auth) if err != nil { return nil, nil, err } @@ -303,7 +314,7 @@ func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byt return plainText, keyId, err } -func getKDFKey(cryptoJSON cryptoJSON, auth string) ([]byte, error) { +func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) { authArray := []byte(auth) salt, err := hex.DecodeString(cryptoJSON.KDFParams["salt"].(string)) if err != nil { From b469d704338170dd4faefa4bb0188d3bd2c645ff Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 020/280] accounts/usbwallet: simplify code using -= operator (#17904) --- accounts/usbwallet/ledger.go | 2 +- accounts/usbwallet/trezor.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 063384b1c2..259bff9a09 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -351,7 +351,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction signer = new(types.HomesteadSigner) } else { signer = types.NewEIP155Signer(chainID) - signature[crypto.RecoveryIDOffset] = signature[crypto.RecoveryIDOffset] - byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2+35) } signed, err := tx.WithSignature(signer, signature) if err != nil { diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 8bc51bb835..cd8f3d4516 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -223,7 +223,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction } else { // Trezor backend does not support typed transactions yet. signer = types.NewEIP155Signer(chainID) - signature[crypto.RecoveryIDOffset] = signature[crypto.RecoveryIDOffset] - byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2+35) } // Inject the final signature into the transaction and sanity check the sender From 25a6b59aca92e73c0d5ddf2b0e4ed99cb83129a1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 021/280] accounts: wallet derivation path comment is mistaken (#17934) --- accounts/hd.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/hd.go b/accounts/hd.go index 277f688e48..6ed6318078 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -30,8 +30,8 @@ import ( var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} // DefaultBaseDerivationPath is the base path from which custom derivation endpoints -// are incremented. As such, the first account will be at m/44'/60'/0'/0, the second -// at m/44'/60'/0'/1, etc. +// are incremented. As such, the first account will be at m/44'/60'/0'/0/0, the second +// at m/44'/60'/0'/0/1, etc. var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0} // DefaultLedgerBaseDerivationPath is the base path from which custom derivation endpoints From f645cbc61d71d2ad7dc93a5737d6b3a75db7d968 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 022/280] accounts/keystore: delete the redundant keystore in filename (#17930) * accounts/keystore: reduce file name length * accounts/keystore: reduce code line width --- accounts/keystore/account_cache.go | 5 ++++- accounts/keystore/key.go | 8 ++++++-- .../keystore/{keystore_passphrase.go => passphrase.go} | 0 .../{keystore_passphrase_test.go => passphrase_test.go} | 0 accounts/keystore/{keystore_plain.go => plain.go} | 0 .../keystore/{keystore_plain_test.go => plain_test.go} | 0 accounts/keystore/presale.go | 8 +++++++- accounts/keystore/{keystore_wallet.go => wallet.go} | 0 8 files changed, 17 insertions(+), 4 deletions(-) rename accounts/keystore/{keystore_passphrase.go => passphrase.go} (100%) rename accounts/keystore/{keystore_passphrase_test.go => passphrase_test.go} (100%) rename accounts/keystore/{keystore_plain.go => plain.go} (100%) rename accounts/keystore/{keystore_plain_test.go => plain_test.go} (100%) rename accounts/keystore/{keystore_wallet.go => wallet.go} (100%) diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index 4c8155e333..22fc9d40df 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -265,7 +265,10 @@ func (ac *accountCache) scanAccounts() error { case (addr == common.Address{}): log.Debug("Failed to decode keystore key", "path", path, "err", "missing or zero address") default: - return &accounts.Account{Address: addr, URL: accounts.URL{Scheme: KeyStoreScheme, Path: path}} + return &accounts.Account{ + Address: addr, + URL: accounts.URL{Scheme: KeyStoreScheme, Path: path}, + } } return nil } diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index fb7372c0db..1fe1dcc6c5 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -169,7 +169,10 @@ func storeNewKey(ks keyStore, rand io.Reader, auth string) (*Key, accounts.Accou if err != nil { return nil, accounts.Account{}, err } - a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))}} + a := accounts.Account{ + Address: key.Address, + URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))}, + } if err := ks.StoreKey(a.URL.Path, key, auth); err != nil { zeroKey(key.PrivateKey) return nil, a, err @@ -223,5 +226,6 @@ func toISO8601(t time.Time) string { } else { tz = fmt.Sprintf("%03d00", offset/3600) } - return fmt.Sprintf("%04d-%02d-%02dT%02d-%02d-%02d.%09d%s", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), tz) + return fmt.Sprintf("%04d-%02d-%02dT%02d-%02d-%02d.%09d%s", + t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), tz) } diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/passphrase.go similarity index 100% rename from accounts/keystore/keystore_passphrase.go rename to accounts/keystore/passphrase.go diff --git a/accounts/keystore/keystore_passphrase_test.go b/accounts/keystore/passphrase_test.go similarity index 100% rename from accounts/keystore/keystore_passphrase_test.go rename to accounts/keystore/passphrase_test.go diff --git a/accounts/keystore/keystore_plain.go b/accounts/keystore/plain.go similarity index 100% rename from accounts/keystore/keystore_plain.go rename to accounts/keystore/plain.go diff --git a/accounts/keystore/keystore_plain_test.go b/accounts/keystore/plain_test.go similarity index 100% rename from accounts/keystore/keystore_plain_test.go rename to accounts/keystore/plain_test.go diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go index b1253374e6..c072361ea1 100644 --- a/accounts/keystore/presale.go +++ b/accounts/keystore/presale.go @@ -38,7 +38,13 @@ func importPreSaleKey(keyStore keyStore, keyJSON []byte, password string) (accou return accounts.Account{}, nil, err } key.Id = uuid.NewRandom() - a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: keyStore.JoinPath(keyFileName(key.Address))}} + a := accounts.Account{ + Address: key.Address, + URL: accounts.URL{ + Scheme: KeyStoreScheme, + Path: keyStore.JoinPath(keyFileName(key.Address)), + }, + } err = keyStore.StoreKey(a.URL.Path, key, password) return a, key, err } diff --git a/accounts/keystore/keystore_wallet.go b/accounts/keystore/wallet.go similarity index 100% rename from accounts/keystore/keystore_wallet.go rename to accounts/keystore/wallet.go From 11519292cd822d2684fbba43f634519c329172be Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 023/280] accounts/abi: add packing for dynamic array and slice types (#18051) --- accounts/abi/argument.go | 19 +++++-------- accounts/abi/pack_test.go | 59 +++++++++++++++++++++++++++++++++++++++ accounts/abi/type.go | 58 ++++++++++++++++++++++++++++++++------ 3 files changed, 115 insertions(+), 21 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 2b3a8bb00c..9730f39d4c 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -244,11 +244,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { // input offset is the bytes offset for packed output inputOffset := 0 for _, abiArg := range abiArgs { - if abiArg.Type.T == ArrayTy { - inputOffset += 32 * abiArg.Type.Size - } else { - inputOffset += 32 - } + inputOffset += getDynamicTypeOffset(abiArg.Type) } var ret []byte for i, a := range args { @@ -258,14 +254,13 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { if err != nil { return nil, err } - // check for a slice type (string, bytes, slice) - if input.Type.requiresLengthPrefix() { - // calculate the offset - offset := inputOffset + len(variableInput) + // check for dynamic types + if isDynamicType(input.Type) { // set the offset - ret = append(ret, packNum(reflect.ValueOf(offset))...) - // Append the packed output to the variable input. The variable input - // will be appended at the end of the input. + ret = append(ret, packNum(reflect.ValueOf(inputOffset))...) + // calculate next offset + inputOffset += len(packed) + // append to variable input variableInput = append(variableInput, packed...) } else { // append the packed value to the input diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index 1c048f0738..e0080ee73c 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -324,6 +324,65 @@ func TestPack(t *testing.T) { "foobar", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"), }, + { + "string[]", + []string{"hello", "foobar"}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 + "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "0000000000000000000000000000000000000000000000000000000000000080" + // offset 128 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 + "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] + "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 + "666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1] + }, + { + "string[2]", + []string{"hello", "foobar"}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset to i = 0 + "0000000000000000000000000000000000000000000000000000000000000080" + // offset to i = 1 + "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 + "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] + "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 + "666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1] + }, + { + "bytes32[][]", + [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 + "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 + "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] + }, + + { + "bytes32[][2]", + [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 + "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] + }, + { + "bytes32[3][2]", + [][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}}, + common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0300000000000000000000000000000000000000000000000000000000000000" + // array[0][2] + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] + }, } { typ, err := NewType(test.typ) if err != nil { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index e127c8e374..b114c16825 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -183,23 +183,39 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { return nil, err } - if t.T == SliceTy || t.T == ArrayTy { - var packed []byte + switch t.T { + case SliceTy, ArrayTy: + var ret []byte + if t.requiresLengthPrefix() { + // append length + ret = append(ret, packNum(reflect.ValueOf(v.Len()))...) + } + + // calculate offset if any + offset := 0 + offsetReq := isDynamicType(*t.Elem) + if offsetReq { + offset = getDynamicTypeOffset(*t.Elem) * v.Len() + } + var tail []byte for i := 0; i < v.Len(); i++ { val, err := t.Elem.pack(v.Index(i)) if err != nil { return nil, err } - packed = append(packed, val...) - } - if t.T == SliceTy { - return packBytesSlice(packed, v.Len()), nil - } else if t.T == ArrayTy { - return packed, nil + if !offsetReq { + ret = append(ret, val...) + continue + } + ret = append(ret, packNum(reflect.ValueOf(offset))...) + offset += len(val) + tail = append(tail, val...) } + return append(ret, tail...), nil + default: + return packElement(t, v), nil } - return packElement(t, v), nil } // requireLengthPrefix returns whether the type requires any sort of length @@ -207,3 +223,27 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { func (t Type) requiresLengthPrefix() bool { return t.T == StringTy || t.T == BytesTy || t.T == SliceTy } + +// isDynamicType returns true if the type is dynamic. +// StringTy, BytesTy, and SliceTy(irrespective of slice element type) are dynamic types +// ArrayTy is considered dynamic if and only if the Array element is a dynamic type. +// This function recursively checks the type for slice and array elements. +func isDynamicType(t Type) bool { + // dynamic types + // array is also a dynamic type if the array type is dynamic + return t.T == StringTy || t.T == BytesTy || t.T == SliceTy || (t.T == ArrayTy && isDynamicType(*t.Elem)) +} + +// getDynamicTypeOffset returns the offset for the type. +// See `isDynamicType` to know which types are considered dynamic. +// If the type t is an array and element type is not a dynamic type, then we consider it a static type and +// return 32 * size of array since length prefix is not required. +// If t is a dynamic type or element type(for slices and arrays) is dynamic, then we simply return 32 as offset. +func getDynamicTypeOffset(t Type) int { + // if it is an array and there are no dynamic types + // then the array is static type + if t.T == ArrayTy && !isDynamicType(*t.Elem) { + return 32 * t.Size + } + return 32 +} From 5e6fa602c9414472a273703de4fc8a40926aaa39 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 024/280] usbwallet: check returned error when decoding hexstr (#18056) * usbwallet: check returned error when decoding hexstr * Update accounts/usbwallet/ledger.go Co-Authored-By: CoreyLin <514971757@qq.com> * usbwallet: check hex decode error --- accounts/usbwallet/ledger.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 259bff9a09..87983c4954 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -258,7 +258,9 @@ func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, er // Decode the hex sting into an Ethereum address and return var address common.Address - hex.Decode(address[:], hexstr) + if _, err = hex.Decode(address[:], hexstr); err != nil { + return common.Address{}, err + } return address, nil } From 0bf459b979a17c1a2ec1724511643cdca13d9f14 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 025/280] accounts/abi: argument type and name were reversed (#17947) argument type and name were reversed --- accounts/abi/event.go | 12 ++++---- accounts/abi/event_test.go | 41 ++++++++++++++++++++++--- accounts/abi/method.go | 6 ++-- accounts/abi/method_test.go | 61 +++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 accounts/abi/method_test.go diff --git a/accounts/abi/event.go b/accounts/abi/event.go index fd337c68a2..b64e62aafc 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -33,15 +33,15 @@ type Event struct { Inputs Arguments } -func (event Event) String() string { - inputs := make([]string, len(event.Inputs)) - for i, input := range event.Inputs { - inputs[i] = fmt.Sprintf("%v %v", input.Name, input.Type) +func (e Event) String() string { + inputs := make([]string, len(e.Inputs)) + for i, input := range e.Inputs { + inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name) if input.Indexed { - inputs[i] = fmt.Sprintf("%v indexed %v", input.Name, input.Type) + inputs[i] = fmt.Sprintf("%v indexed %v", input.Type, input.Name) } } - return fmt.Sprintf("event %v(%v)", event.Name, strings.Join(inputs, ", ")) + return fmt.Sprintf("event %v(%v)", e.Name, strings.Join(inputs, ", ")) } // Id returns the canonical representation of the event's signature used by the diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 73d7c35870..78e5733a91 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -71,12 +71,12 @@ func TestEventId(t *testing.T) { }{ { definition: `[ - { "type" : "event", "name" : "balance", "inputs": [{ "name" : "in", "type": "uint256" }] }, - { "type" : "event", "name" : "check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] } + { "type" : "event", "name" : "Balance", "inputs": [{ "name" : "in", "type": "uint256" }] }, + { "type" : "event", "name" : "Check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] } ]`, expectations: map[string]common.Hash{ - "balance": crypto.Keccak256Hash([]byte("balance(uint256)")), - "check": crypto.Keccak256Hash([]byte("check(address,uint256)")), + "Balance": crypto.Keccak256Hash([]byte("Balance(uint256)")), + "Check": crypto.Keccak256Hash([]byte("Check(address,uint256)")), }, }, } @@ -95,6 +95,39 @@ func TestEventId(t *testing.T) { } } +func TestEventString(t *testing.T) { + var table = []struct { + definition string + expectations map[string]string + }{ + { + definition: `[ + { "type" : "event", "name" : "Balance", "inputs": [{ "name" : "in", "type": "uint256" }] }, + { "type" : "event", "name" : "Check", "inputs": [{ "name" : "t", "type": "address" }, { "name": "b", "type": "uint256" }] }, + { "type" : "event", "name" : "Transfer", "inputs": [{ "name": "from", "type": "address", "indexed": true }, { "name": "to", "type": "address", "indexed": true }, { "name": "value", "type": "uint256" }] } + ]`, + expectations: map[string]string{ + "Balance": "event Balance(uint256 in)", + "Check": "event Check(address t, uint256 b)", + "Transfer": "event Transfer(address indexed from, address indexed to, uint256 value)", + }, + }, + } + + for _, test := range table { + abi, err := JSON(strings.NewReader(test.definition)) + if err != nil { + t.Fatal(err) + } + + for name, event := range abi.Events { + if event.String() != test.expectations[name] { + t.Errorf("expected string to be %s, got %s", test.expectations[name], event.String()) + } + } + } +} + // TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array. func TestEventMultiValueWithArrayUnpack(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` diff --git a/accounts/abi/method.go b/accounts/abi/method.go index d49e555c94..370bac004b 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -56,14 +56,14 @@ func (method Method) Sig() string { func (method Method) String() string { inputs := make([]string, len(method.Inputs)) for i, input := range method.Inputs { - inputs[i] = fmt.Sprintf("%v %v", input.Name, input.Type) + inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name) } outputs := make([]string, len(method.Outputs)) for i, output := range method.Outputs { + outputs[i] = output.Type.String() if len(output.Name) > 0 { - outputs[i] = fmt.Sprintf("%v ", output.Name) + outputs[i] += fmt.Sprintf(" %v", output.Name) } - outputs[i] += output.Type.String() } constant := "" if method.Const { diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go new file mode 100644 index 0000000000..a98f1cd31f --- /dev/null +++ b/accounts/abi/method_test.go @@ -0,0 +1,61 @@ +// Copyright 2016 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 . + +package abi + +import ( + "strings" + "testing" +) + +const methoddata = ` +[ + { "type" : "function", "name" : "balance", "constant" : true }, + { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, + { "type" : "function", "name" : "transfer", "constant" : false, "inputs" : [ { "name" : "from", "type" : "address" }, { "name" : "to", "type" : "address" }, { "name" : "value", "type" : "uint256" } ], "outputs" : [ { "name" : "success", "type" : "bool" } ] } +]` + +func TestMethodString(t *testing.T) { + var table = []struct { + method string + expectation string + }{ + { + method: "balance", + expectation: "function balance() constant returns()", + }, + { + method: "send", + expectation: "function send(uint256 amount) returns()", + }, + { + method: "transfer", + expectation: "function transfer(address from, address to, uint256 value) returns(bool success)", + }, + } + + abi, err := JSON(strings.NewReader(methoddata)) + if err != nil { + t.Fatal(err) + } + + for _, test := range table { + got := abi.Methods[test.method].String() + if got != test.expectation { + t.Errorf("expected string to be %s, got %s", test.expectation, got) + } + } +} From 95d06922b74c14291750b12321d0cff18a3d0d25 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 026/280] accounts/abi: fix slice unpack bug (#18321) --- accounts/abi/unpack.go | 2 +- accounts/abi/unpack_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 171ca7d4cf..5f7c855663 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -152,7 +152,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) // Arrays have packed elements, resulting in longer unpack steps. // Slices have just 32 bytes per element (pointing to the contents). elemSize := 32 - if t.T == ArrayTy { + if t.T == ArrayTy || t.T == SliceTy { elemSize = getFullElemSize(t.Elem) } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index d18ed50052..121ce05dcf 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -191,6 +191,11 @@ var unpackTests = []unpackTest{ enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: [][2]uint8{{1, 2}}, }, + { + def: `[{"type": "uint8[2][]"}]`, + enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: [][2]uint8{{1, 2}, {1, 2}}, + }, { def: `[{"type": "uint16[]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", From 16e444c4f8a5e85973e63898b6cad2b122efb1be Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 027/280] accounts/abi: add support for unpacking returned bytesN arrays (#15242) --- accounts/abi/reflect.go | 15 ++++++++++++ accounts/abi/unpack_test.go | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 186cf307f2..312d2381ba 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -77,6 +77,8 @@ func set(dst, src reflect.Value, output Argument) error { switch { case dstType.AssignableTo(srcType): dst.Set(src) + case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice: + return setSlice(dst, src, output) case dstType.Kind() == reflect.Interface: dst.Set(src) case dstType.Kind() == reflect.Ptr: @@ -87,6 +89,19 @@ func set(dst, src reflect.Value, output Argument) error { return nil } +// setSlice attempts to assign src to dst when slices are not assignable by default +// e.g. src: [][]byte -> dst: [][15]byte +func setSlice(dst, src reflect.Value, output Argument) error { + slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) + for i := 0; i < src.Len(); i++ { + v := src.Index(i) + reflect.Copy(slice.Index(i), v) + } + + dst.Set(slice) + return nil +} + // requireAssignable assures that `dest` is a pointer and it's not an interface. func requireAssignable(dst, src reflect.Value) error { if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 121ce05dcf..9aa0620d7e 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -411,6 +411,55 @@ func TestUnpack(t *testing.T) { } } +func TestUnpackSetDynamicArrayOutput(t *testing.T) { + abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`)) + if err != nil { + t.Fatal(err) + } + + var ( + marshalledReturn32 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783132333435363738393000000000000000000000000000000000000000003078303938373635343332310000000000000000000000000000000000000000") + marshalledReturn15 = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000230783031323334350000000000000000000000000000000000000000000000003078393837363534000000000000000000000000000000000000000000000000") + + out32 [][32]byte + out15 [][15]byte + ) + + // test 32 + err = abi.Unpack(&out32, "testDynamicFixedBytes32", marshalledReturn32) + if err != nil { + t.Fatal(err) + } + if len(out32) != 2 { + t.Fatalf("expected array with 2 values, got %d", len(out32)) + } + expected := common.Hex2Bytes("3078313233343536373839300000000000000000000000000000000000000000") + if !bytes.Equal(out32[0][:], expected) { + t.Errorf("expected %x, got %x\n", expected, out32[0]) + } + expected = common.Hex2Bytes("3078303938373635343332310000000000000000000000000000000000000000") + if !bytes.Equal(out32[1][:], expected) { + t.Errorf("expected %x, got %x\n", expected, out32[1]) + } + + // test 15 + err = abi.Unpack(&out15, "testDynamicFixedBytes32", marshalledReturn15) + if err != nil { + t.Fatal(err) + } + if len(out15) != 2 { + t.Fatalf("expected array with 2 values, got %d", len(out15)) + } + expected = common.Hex2Bytes("307830313233343500000000000000") + if !bytes.Equal(out15[0][:], expected) { + t.Errorf("expected %x, got %x\n", expected, out15[0]) + } + expected = common.Hex2Bytes("307839383736353400000000000000") + if !bytes.Equal(out15[1][:], expected) { + t.Errorf("expected %x, got %x\n", expected, out15[1]) + } +} + type methodMultiOutput struct { Int *big.Int String string From bb54f11c13b66aba23d1552e7f52fefca4cce7ae Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 028/280] accounts/abi: brings out the msg defined at require statement in SC function (#17328) --- accounts/abi/abi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 0c68a0a1ee..ddb6f4f00b 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -85,7 +85,7 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) (err error) { // we need to decide whether we're calling a method or an event if method, ok := abi.Methods[name]; ok { if len(output)%32 != 0 { - return errors.New("abi: improperly formatted output") + return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(output), output) } return method.Outputs.Unpack(v, output) } else if event, ok := abi.Events[name]; ok { From 9ec0b75eafb4c203375e18b415b97df0cc5cb8a0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 029/280] accounts/abi: fix string array unpack bug (#18364) --- accounts/abi/argument.go | 2 +- accounts/abi/unpack.go | 7 +++++++ accounts/abi/unpack_test.go | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 9730f39d4c..9e536b2c57 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -203,7 +203,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { virtualArgs := 0 for index, arg := range arguments.NonIndexed() { marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) - if arg.Type.T == ArrayTy { + if arg.Type.T == ArrayTy && (*arg.Type.Elem).T != StringTy { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. // This means that we need to add two 'virtual' arguments when diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 5f7c855663..27d3af3ee3 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -196,8 +196,15 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { switch t.T { case SliceTy: + if (*t.Elem).T == StringTy { + return forEachUnpack(t, output[begin:], 0, end) + } return forEachUnpack(t, output, begin, end) case ArrayTy: + if (*t.Elem).T == StringTy { + offset := int64(binary.BigEndian.Uint64(returnOutput[len(returnOutput)-8:])) + return forEachUnpack(t, output[offset:], 0, t.Size) + } return forEachUnpack(t, output, index, t.Size) case StringTy: // variable arrays are written at the end of the return bytes return string(output[begin : begin+end]), nil diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 9aa0620d7e..92b960f5e4 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -241,6 +241,16 @@ var unpackTests = []unpackTest{ enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, }, + { + def: `[{"type": "string[4]"}]`, + enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000548656c6c6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b476f2d657468657265756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000", + want: [4]string{"Hello", "World", "Go-ethereum", "Ethereum"}, + }, + { + def: `[{"type": "string[]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b676f2d657468657265756d000000000000000000000000000000000000000000", + want: []string{"Ethereum", "go-ethereum"}, + }, { def: `[{"type": "int8[]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", @@ -563,6 +573,36 @@ func TestMultiReturnWithArray(t *testing.T) { } } +func TestMultiReturnWithStringArray(t *testing.T) { + const definition = `[{"name" : "multi", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]` + abi, err := JSON(strings.NewReader(definition)) + if err != nil { + t.Fatal(err) + } + buff := new(bytes.Buffer) + buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000005c1b78ea0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000001a055690d9db80000000000000000000000000000ab1257528b3782fb40d7ed5f72e624b744dffb2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001048656c6c6f2c20457468657265756d2100000000000000000000000000000000")) + temp, _ := big.NewInt(0).SetString("30000000000000000000", 10) + ret1, ret1Exp := new([3]*big.Int), [3]*big.Int{big.NewInt(1545304298), big.NewInt(6), temp} + ret2, ret2Exp := new(common.Address), common.HexToAddress("ab1257528b3782fb40d7ed5f72e624b744dffb2f") + ret3, ret3Exp := new([2]string), [2]string{"Ethereum", "Hello, Ethereum!"} + ret4, ret4Exp := new(bool), false + if err := abi.Unpack(&[]interface{}{ret1, ret2, ret3, ret4}, "multi", buff.Bytes()); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(*ret1, ret1Exp) { + t.Error("big.Int array result", *ret1, "!= Expected", ret1Exp) + } + if !reflect.DeepEqual(*ret2, ret2Exp) { + t.Error("address result", *ret2, "!= Expected", ret2Exp) + } + if !reflect.DeepEqual(*ret3, ret3Exp) { + t.Error("string array result", *ret3, "!= Expected", ret3Exp) + } + if !reflect.DeepEqual(*ret4, ret4Exp) { + t.Error("bool result", *ret4, "!= Expected", ret4Exp) + } +} + func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { // Similar to TestMultiReturnWithArray, but with a special case in mind: // values of nested static arrays count towards the size as well, and any element following From 48de514dd93cd5631fa36c5fa3db0ab3b93ad6fa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 030/280] accounts/abi/bind: add optional block number for calls (#17942) --- accounts/abi/bind/base.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index ebdd9b6cc3..1364000f85 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -40,10 +40,10 @@ type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, erro // CallOpts is the collection of options to fine tune a contract call request. type CallOpts struct { - Pending bool // Whether to operate on the pending state or the last known one - From common.Address // Optional the sender address, otherwise the first account is used - - Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) + Pending bool // Whether to operate on the pending state or the last known one + From common.Address // Optional the sender address, otherwise the first account is used + BlockNumber *big.Int // Optional the block number on which the call should be performed + Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } // TransactOpts is the collection of authorization data required to create a @@ -156,10 +156,10 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, } } } else { - output, err = c.caller.CallContract(ctx, msg, nil) + output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) if err == nil && len(output) == 0 { // Make sure we have a contract to operate on, and bail out otherwise. - if code, err = c.caller.CodeAt(ctx, c.address, nil); err != nil { + if code, err = c.caller.CodeAt(ctx, c.address, opts.BlockNumber); err != nil { return err } else if len(code) == 0 { return ErrNoCode From 930ec9ba86a2ef195dd64dce580df7da841317e3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 031/280] accounts/abi: allow abi tags when unpacking structs (#16648) --- accounts/abi/argument.go | 44 +++++++-------- accounts/abi/event_test.go | 81 ++++++++++++++++++++++++++- accounts/abi/reflect.go | 110 +++++++++++++++++++++++++++++++++---- 3 files changed, 198 insertions(+), 37 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 9e536b2c57..071dc121af 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -123,9 +123,14 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa if err := requireUnpackKind(value, typ, kind, arguments); err != nil { return err } - // If the output interface is a struct, make sure names don't collide + + // If the interface is a struct, get of abi->struct_field mapping + + var abi2struct map[string]string if kind == reflect.Struct { - if err := requireUniqueStructFieldNames(arguments); err != nil { + var err error + abi2struct, err = mapAbiToStructFields(arguments, value) + if err != nil { return err } } @@ -135,9 +140,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa switch kind { case reflect.Struct: - err := unpackStruct(value, reflectValue, arg) - if err != nil { - return err + if structField, ok := abi2struct[arg.Name]; ok { + if err := set(value.FieldByName(structField), reflectValue, arg); err != nil { + return err + } } case reflect.Slice, reflect.Array: if value.Len() < i { @@ -163,17 +169,22 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf if len(marshalledValues) != 1 { return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) } + elem := reflect.ValueOf(v).Elem() kind := elem.Kind() reflectValue := reflect.ValueOf(marshalledValues[0]) + var abi2struct map[string]string if kind == reflect.Struct { - //make sure names don't collide - if err := requireUniqueStructFieldNames(arguments); err != nil { + var err error + if abi2struct, err = mapAbiToStructFields(arguments, elem); err != nil { return err } - - return unpackStruct(elem, reflectValue, arguments[0]) + arg := arguments.NonIndexed()[0] + if structField, ok := abi2struct[arg.Name]; ok { + return set(elem.FieldByName(structField), reflectValue, arg) + } + return nil } return set(elem, reflectValue, arguments.NonIndexed()[0]) @@ -283,18 +294,3 @@ func ToCamelCase(input string) string { } return strings.Join(parts, "") } - -// unpackStruct extracts each argument into its corresponding struct field -func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { - name := ToCamelCase(arg.Name) - typ := value.Type() - for j := 0; j < typ.NumField(); j++ { - // TODO read tags: `abi:"fieldName"` - if typ.Field(j).Name == name { - if err := set(value.Field(j), reflectValue, arg); err != nil { - return err - } - } - } - return nil -} diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 78e5733a91..ee77108f80 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -58,12 +58,28 @@ var jsonEventPledge = []byte(`{ "type": "event" }`) +var jsonEventMixedCase = []byte(`{ + "anonymous": false, + "inputs": [{ + "indexed": false, "name": "value", "type": "uint256" + }, { + "indexed": false, "name": "_value", "type": "uint256" + }, { + "indexed": false, "name": "Value", "type": "uint256" + }], + "name": "MixedCase", + "type": "event" + }`) + // 1000000 var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240" // "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd" var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000" +// 1000000,2218516807680,1000001 +var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241" + func TestEventId(t *testing.T) { var table = []struct { definition string @@ -154,6 +170,27 @@ func TestEventTupleUnpack(t *testing.T) { Value *big.Int } + type EventTransferWithTag struct { + // this is valid because `value` is not exportable, + // so value is only unmarshalled into `Value1`. + value *big.Int + Value1 *big.Int `abi:"value"` + } + + type BadEventTransferWithSameFieldAndTag struct { + Value *big.Int + Value1 *big.Int `abi:"value"` + } + + type BadEventTransferWithDuplicatedTag struct { + Value1 *big.Int `abi:"value"` + Value2 *big.Int `abi:"value"` + } + + type BadEventTransferWithEmptyTag struct { + Value *big.Int `abi:""` + } + type EventPledge struct { Who common.Address Wad *big.Int @@ -166,9 +203,16 @@ func TestEventTupleUnpack(t *testing.T) { Currency [3]byte } + type EventMixedCase struct { + Value1 *big.Int `abi:"value"` + Value2 *big.Int `abi:"_value"` + Value3 *big.Int `abi:"Value"` + } + bigint := new(big.Int) bigintExpected := big.NewInt(1000000) bigintExpected2 := big.NewInt(2218516807680) + bigintExpected3 := big.NewInt(1000001) addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268") var testCases = []struct { data string @@ -191,6 +235,34 @@ func TestEventTupleUnpack(t *testing.T) { jsonEventTransfer, "", "Can unpack ERC20 Transfer event into slice", + }, { + transferData1, + &EventTransferWithTag{}, + &EventTransferWithTag{Value1: bigintExpected}, + jsonEventTransfer, + "", + "Can unpack ERC20 Transfer event into structure with abi: tag", + }, { + transferData1, + &BadEventTransferWithDuplicatedTag{}, + &BadEventTransferWithDuplicatedTag{}, + jsonEventTransfer, + "struct: abi tag in 'Value2' already mapped", + "Can not unpack ERC20 Transfer event with duplicated abi tag", + }, { + transferData1, + &BadEventTransferWithSameFieldAndTag{}, + &BadEventTransferWithSameFieldAndTag{}, + jsonEventTransfer, + "abi: multiple variables maps to the same abi field 'value'", + "Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable", + }, { + transferData1, + &BadEventTransferWithEmptyTag{}, + &BadEventTransferWithEmptyTag{}, + jsonEventTransfer, + "struct: abi tag in 'Value' is empty", + "Can not unpack ERC20 Transfer event with an empty tag", }, { pledgeData1, &EventPledge{}, @@ -249,6 +321,13 @@ func TestEventTupleUnpack(t *testing.T) { jsonEventPledge, "abi: cannot unmarshal tuple into map[string]interface {}", "Can not unpack Pledge event into map", + }, { + mixedCaseData1, + &EventMixedCase{}, + &EventMixedCase{Value1: bigintExpected, Value2: bigintExpected2, Value3: bigintExpected3}, + jsonEventMixedCase, + "", + "Can unpack abi variables with mixed case", }} for _, tc := range testCases { @@ -260,7 +339,7 @@ func TestEventTupleUnpack(t *testing.T) { assert.Nil(err, "Should be able to unpack event data.") assert.Equal(tc.expected, tc.dest, tc.name) } else { - assert.EqualError(err, tc.error) + assert.EqualError(err, tc.error, tc.name) } }) } diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 312d2381ba..ac249e8507 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -17,9 +17,9 @@ package abi import ( - "errors" "fmt" "reflect" + "strings" ) // indirect recursively dereferences the value until it either gets the value @@ -127,18 +127,104 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, return nil } -// requireUniqueStructFieldNames makes sure field names don't collide -func requireUniqueStructFieldNames(args Arguments) error { - exists := make(map[string]bool) - for _, arg := range args { - field := ToCamelCase(arg.Name) - if field == "" { - return errors.New("abi: purely underscored output cannot unpack to struct") +// mapAbiToStringField maps abi to struct fields. +// first round: for each Exportable field that contains a `abi:""` tag +// +// and this field name exists in the arguments, pair them together. +// +// second round: for each argument field that has not been already linked, +// +// find what variable is expected to be mapped into, if it exists and has not been +// used, pair them. +func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) { + + typ := value.Type() + + abi2struct := make(map[string]string) + struct2abi := make(map[string]string) + + // first round ~~~ + for i := 0; i < typ.NumField(); i++ { + structFieldName := typ.Field(i).Name + + // skip private struct fields. + if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) { + continue } - if exists[field] { - return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) + + // skip fields that have no abi:"" tag. + var ok bool + var tagName string + if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { + continue } - exists[field] = true + + // check if tag is empty. + if tagName == "" { + return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName) + } + + // check which argument field matches with the abi tag. + found := false + for _, abiField := range args.NonIndexed() { + if abiField.Name == tagName { + if abi2struct[abiField.Name] != "" { + return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName) + } + // pair them + abi2struct[abiField.Name] = structFieldName + struct2abi[structFieldName] = abiField.Name + found = true + } + } + + // check if this tag has been mapped. + if !found { + return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName) + } + } - return nil + + // second round ~~~ + for _, arg := range args { + + abiFieldName := arg.Name + structFieldName := ToCamelCase(abiFieldName) + + if structFieldName == "" { + return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") + } + + // this abi has already been paired, skip it... unless there exists another, yet unassigned + // struct field with the same field name. If so, raise an error: + // abi: [ { "name": "value" } ] + // struct { Value *big.Int , Value1 *big.Int `abi:"value"`} + if abi2struct[abiFieldName] != "" { + if abi2struct[abiFieldName] != structFieldName && + struct2abi[structFieldName] == "" && + value.FieldByName(structFieldName).IsValid() { + return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName) + } + continue + } + + // return an error if this struct field has already been paired. + if struct2abi[structFieldName] != "" { + return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName) + } + + if value.FieldByName(structFieldName).IsValid() { + // pair them + abi2struct[abiFieldName] = structFieldName + struct2abi[structFieldName] = abiFieldName + } else { + // not paired, but annotate as used, to detect cases like + // abi : [ { "name": "value" }, { "name": "_value" } ] + // struct { Value *big.Int } + struct2abi[structFieldName] = abiFieldName + } + + } + + return abi2struct, nil } From 67fe8157148b439e5ac6d387ebf39574c32c5b43 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 032/280] console: squash golint warnings (#16836) --- console/bridge.go | 4 ++-- console/console.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/console/bridge.go b/console/bridge.go index 34f77dcbfb..3f7982b5f6 100644 --- a/console/bridge.go +++ b/console/bridge.go @@ -314,7 +314,7 @@ func (b *bridge) SleepBlocks(call jsre.Call) (goja.Value, error) { } type jsonrpcCall struct { - Id int64 + ID int64 Method string Params []interface{} } @@ -348,7 +348,7 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) { for _, req := range reqs { resp := call.VM.NewObject() resp.Set("jsonrpc", "2.0") - resp.Set("id", req.Id) + resp.Set("id", req.ID) var result json.RawMessage err = b.client.Call(&result, req.Method, req.Params...) diff --git a/console/console.go b/console/console.go index 21d66f5b6a..af28c2e4d5 100644 --- a/console/console.go +++ b/console/console.go @@ -73,6 +73,8 @@ type Console struct { printer io.Writer // Output writer to serialize any display strings to } +// New initializes a JavaScript interpreted runtime environment and sets defaults +// with the config struct. func New(config Config) (*Console, error) { // Handle unset config values gracefully if config.Prompter == nil { From e4adf8e4eb98a7ca724436b50b7ef1af9e020cea Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 033/280] accounts/keystore: fix comment typo (#18395) --- accounts/keystore/wallet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 19dba42ce7..29cf2d0154 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -52,8 +52,8 @@ func (w *keystoreWallet) Status() (string, error) { // is no connection or decryption step necessary to access the list of accounts. func (w *keystoreWallet) Open(passphrase string) error { return nil } -// Close implements accounts.Wallet, but is a noop for plain wallets since is no -// meaningful open operation. +// Close implements accounts.Wallet, but is a noop for plain wallets since there +// is no meaningful open operation. func (w *keystoreWallet) Close() error { return nil } // Accounts implements accounts.Wallet, returning an account list consisting of From a81fe2290372269910eb10690e9e94b380423eb7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 034/280] accounts/keystore: small code simplification (#18394) --- accounts/keystore/wallet.go | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 29cf2d0154..41c270c4fd 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -84,10 +84,7 @@ func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum // able to sign via our shared keystore backend). func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { // Make sure the requested account is contained within - if account.Address != w.account.Address { - return nil, accounts.ErrUnknownAccount - } - if account.URL != (accounts.URL{}) && account.URL != w.account.URL { + if !w.Contains(account) { return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign @@ -100,10 +97,7 @@ func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte // be able to sign via our shared keystore backend). func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { // Make sure the requested account is contained within - if account.Address != w.account.Address { - return nil, accounts.ErrUnknownAccount - } - if account.URL != (accounts.URL{}) && account.URL != w.account.URL { + if !w.Contains(account) { return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign @@ -114,10 +108,7 @@ func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, // given hash with the given account using passphrase as extra authentication. func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { // Make sure the requested account is contained within - if account.Address != w.account.Address { - return nil, accounts.ErrUnknownAccount - } - if account.URL != (accounts.URL{}) && account.URL != w.account.URL { + if !w.Contains(account) { return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign @@ -128,10 +119,7 @@ func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passph // transaction with the given account using passphrase as extra authentication. func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { // Make sure the requested account is contained within - if account.Address != w.account.Address { - return nil, accounts.ErrUnknownAccount - } - if account.URL != (accounts.URL{}) && account.URL != w.account.URL { + if !w.Contains(account) { return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign From 2d0047b4b86bbfbefa8b56d13aa7a737a99bf644 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 035/280] accounts/abi: tuple support (#18406) --- accounts/abi/abi.go | 4 +- accounts/abi/abi_test.go | 54 +++-- accounts/abi/argument.go | 187 ++++++++++------ accounts/abi/pack_test.go | 302 ++++++++++++++++++++++++- accounts/abi/reflect.go | 70 +++--- accounts/abi/type.go | 140 ++++++++++-- accounts/abi/type_test.go | 433 +++++++++++++++++++----------------- accounts/abi/unpack.go | 92 +++++--- accounts/abi/unpack_test.go | 138 +++++++++++- 9 files changed, 1024 insertions(+), 396 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index ddb6f4f00b..defcca353a 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -61,13 +61,11 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { return nil, err } return arguments, nil - } method, exist := abi.Methods[name] if !exist { return nil, fmt.Errorf("method '%s' not found", name) } - arguments, err := method.Inputs.Pack(args...) if err != nil { return nil, err @@ -165,7 +163,7 @@ func UnpackRevert(data []byte) (string, error) { if !bytes.Equal(data[:4], revertSelector) { return "", errors.New("invalid data for unpacking") } - typ, _ := NewType("string") + typ, _ := NewType("string", nil) unpacked, err := (Arguments{{Type: typ}}).Unpack2(data[4:]) if err != nil { return "", err diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index e952c0bc7f..edb97e6850 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -54,11 +54,14 @@ const jsondata2 = ` { "type" : "function", "name" : "slice", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, { "type" : "function", "name" : "slice256", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }, { "type" : "function", "name" : "sliceAddress", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] }, - { "type" : "function", "name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] } + { "type" : "function", "name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }, + { "type" : "function", "name" : "nestedArray", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint256[2][2]" }, { "name" : "b", "type" : "address[]" } ] }, + { "type" : "function", "name" : "nestedArray2", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint8[][2]" } ] }, + { "type" : "function", "name" : "nestedSlice", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint8[][]" } ] } ]` func TestReader(t *testing.T) { - Uint256, _ := NewType("uint256") + Uint256, _ := NewType("uint256", nil) exp := ABI{ Methods: map[string]Method{ "balance": { @@ -179,7 +182,7 @@ func TestTestSlice(t *testing.T) { } func TestMethodSignature(t *testing.T) { - String, _ := NewType("string") + String, _ := NewType("string", nil) m := Method{"foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} exp := "foo(string,string)" if m.Sig() != exp { @@ -191,12 +194,31 @@ func TestMethodSignature(t *testing.T) { t.Errorf("expected ids to match %x != %x", m.Id(), idexp) } - uintt, _ := NewType("uint256") + uintt, _ := NewType("uint256", nil) m = Method{"foo", false, []Argument{{"bar", uintt, false}}, nil} exp = "foo(uint256)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) } + + // Method with tuple arguments + s, _ := NewType("tuple", []ArgumentMarshaling{ + {Name: "a", Type: "int256"}, + {Name: "b", Type: "int256[]"}, + {Name: "c", Type: "tuple[]", Components: []ArgumentMarshaling{ + {Name: "x", Type: "int256"}, + {Name: "y", Type: "int256"}, + }}, + {Name: "d", Type: "tuple[2]", Components: []ArgumentMarshaling{ + {Name: "x", Type: "int256"}, + {Name: "y", Type: "int256"}, + }}, + }) + m = Method{"foo", false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} + exp = "foo((int256,int256[],(int256,int256)[],(int256,int256)[2]),string)" + if m.Sig() != exp { + t.Error("signature mismatch", exp, "!=", m.Sig()) + } } func TestMultiPack(t *testing.T) { @@ -566,11 +588,13 @@ func TestBareEvents(t *testing.T) { const definition = `[ { "type" : "event", "name" : "balance" }, { "type" : "event", "name" : "anon", "anonymous" : true}, - { "type" : "event", "name" : "args", "inputs" : [{ "indexed":false, "name":"arg0", "type":"uint256" }, { "indexed":true, "name":"arg1", "type":"address" }] } + { "type" : "event", "name" : "args", "inputs" : [{ "indexed":false, "name":"arg0", "type":"uint256" }, { "indexed":true, "name":"arg1", "type":"address" }] }, + { "type" : "event", "name" : "tuple", "inputs" : [{ "indexed":false, "name":"t", "type":"tuple", "components":[{"name":"a", "type":"uint256"}] }, { "indexed":true, "name":"arg1", "type":"address" }] } ]` - arg0, _ := NewType("uint256") - arg1, _ := NewType("address") + arg0, _ := NewType("uint256", nil) + arg1, _ := NewType("address", nil) + tuple, _ := NewType("tuple", []ArgumentMarshaling{{Name: "a", Type: "uint256"}}) expectedEvents := map[string]struct { Anonymous bool @@ -582,6 +606,10 @@ func TestBareEvents(t *testing.T) { {Name: "arg0", Type: arg0, Indexed: false}, {Name: "arg1", Type: arg1, Indexed: true}, }}, + "tuple": {false, []Argument{ + {Name: "t", Type: tuple, Indexed: false}, + {Name: "arg1", Type: arg1, Indexed: true}, + }}, } abi, err := JSON(strings.NewReader(definition)) @@ -651,28 +679,24 @@ func TestUnpackEvent(t *testing.T) { } type ReceivedEvent struct { - Address common.Address - Amount *big.Int - Memo []byte + Sender common.Address + Amount *big.Int + Memo []byte } var ev ReceivedEvent err = abi.Unpack(&ev, "received", data) if err != nil { t.Error(err) - } else { - t.Logf("len(data): %d; received event: %+v", len(data), ev) } type ReceivedAddrEvent struct { - Address common.Address + Sender common.Address } var receivedAddrEv ReceivedAddrEvent err = abi.Unpack(&receivedAddrEv, "receivedAddr", data) if err != nil { t.Error(err) - } else { - t.Logf("len(data): %d; received event: %+v", len(data), receivedAddrEv) } } diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 071dc121af..99218904eb 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -34,24 +34,27 @@ type Argument struct { type Arguments []Argument +type ArgumentMarshaling struct { + Name string + Type string + Components []ArgumentMarshaling + Indexed bool +} + // UnmarshalJSON implements json.Unmarshaler interface func (argument *Argument) UnmarshalJSON(data []byte) error { - var extarg struct { - Name string - Type string - Indexed bool - } - err := json.Unmarshal(data, &extarg) + var arg ArgumentMarshaling + err := json.Unmarshal(data, &arg) if err != nil { return fmt.Errorf("argument json err: %v", err) } - argument.Type, err = NewType(extarg.Type) + argument.Type, err = NewType(arg.Type, arg.Components) if err != nil { return err } - argument.Name = extarg.Name - argument.Indexed = extarg.Indexed + argument.Name = arg.Name + argument.Indexed = arg.Indexed return nil } @@ -86,7 +89,6 @@ func (arguments Arguments) isTuple() bool { // Unpack performs the operation hexdata -> Go format func (arguments Arguments) Unpack(v interface{}, data []byte) error { - // make sure the passed value is arguments pointer if reflect.Ptr != reflect.ValueOf(v).Kind() { return fmt.Errorf("abi: Unpack(non-pointer %T)", v) @@ -98,7 +100,7 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { if arguments.isTuple() { return arguments.unpackTuple(v, marshalledValues) } - return arguments.unpackAtomic(v, marshalledValues) + return arguments.unpackAtomic(v, marshalledValues[0]) } // Unpack2 performs the operation hexdata -> Go format. @@ -112,49 +114,131 @@ func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { return arguments.UnpackValues(data) } -func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { +// unpack sets the unmarshalled value to go format. +// Note the dst here must be settable. +func unpack(t *Type, dst interface{}, src interface{}) error { + var ( + dstVal = reflect.ValueOf(dst).Elem() + srcVal = reflect.ValueOf(src) + ) + if t.T != TupleTy && !((t.T == SliceTy || t.T == ArrayTy) && t.Elem.T == TupleTy) { + return set(dstVal, srcVal) + } + + switch t.T { + case TupleTy: + if dstVal.Kind() != reflect.Struct { + return fmt.Errorf("abi: invalid dst value for unpack, want struct, got %s", dstVal.Kind()) + } + fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, dstVal) + if err != nil { + return err + } + for i, elem := range t.TupleElems { + fname := fieldmap[t.TupleRawNames[i]] + field := dstVal.FieldByName(fname) + if !field.IsValid() { + return fmt.Errorf("abi: field %s can't found in the given value", t.TupleRawNames[i]) + } + if err := unpack(elem, field.Addr().Interface(), srcVal.Field(i).Interface()); err != nil { + return err + } + } + return nil + case SliceTy: + if dstVal.Kind() != reflect.Slice { + return fmt.Errorf("abi: invalid dst value for unpack, want slice, got %s", dstVal.Kind()) + } + slice := reflect.MakeSlice(dstVal.Type(), srcVal.Len(), srcVal.Len()) + for i := 0; i < slice.Len(); i++ { + if err := unpack(t.Elem, slice.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil { + return err + } + } + dstVal.Set(slice) + case ArrayTy: + if dstVal.Kind() != reflect.Array { + return fmt.Errorf("abi: invalid dst value for unpack, want array, got %s", dstVal.Kind()) + } + array := reflect.New(dstVal.Type()).Elem() + for i := 0; i < array.Len(); i++ { + if err := unpack(t.Elem, array.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil { + return err + } + } + dstVal.Set(array) + } + return nil +} + +// unpackAtomic unpacks ( hexdata -> go ) a single value +func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { + if arguments.LengthNonIndexed() == 0 { + return nil + } + argument := arguments.NonIndexed()[0] + elem := reflect.ValueOf(v).Elem() + + if elem.Kind() == reflect.Struct { + fieldmap, err := mapArgNamesToStructFields([]string{argument.Name}, elem) + if err != nil { + return err + } + field := elem.FieldByName(fieldmap[argument.Name]) + if !field.IsValid() { + return fmt.Errorf("abi: field %s can't be found in the given value", argument.Name) + } + return unpack(&argument.Type, field.Addr().Interface(), marshalledValues) + } + return unpack(&argument.Type, elem.Addr().Interface(), marshalledValues) +} + +// unpackTuple unpacks ( hexdata -> go ) a batch of values. +func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { var ( value = reflect.ValueOf(v).Elem() typ = value.Type() kind = value.Kind() ) - if err := requireUnpackKind(value, typ, kind, arguments); err != nil { return err } // If the interface is a struct, get of abi->struct_field mapping - var abi2struct map[string]string if kind == reflect.Struct { - var err error - abi2struct, err = mapAbiToStructFields(arguments, value) + var ( + argNames []string + err error + ) + for _, arg := range arguments.NonIndexed() { + argNames = append(argNames, arg.Name) + } + abi2struct, err = mapArgNamesToStructFields(argNames, value) if err != nil { return err } } for i, arg := range arguments.NonIndexed() { - - reflectValue := reflect.ValueOf(marshalledValues[i]) - switch kind { case reflect.Struct: - if structField, ok := abi2struct[arg.Name]; ok { - if err := set(value.FieldByName(structField), reflectValue, arg); err != nil { - return err - } + field := value.FieldByName(abi2struct[arg.Name]) + if !field.IsValid() { + return fmt.Errorf("abi: field %s can't be found in the given value", arg.Name) + } + if err := unpack(&arg.Type, field.Addr().Interface(), marshalledValues[i]); err != nil { + return err } case reflect.Slice, reflect.Array: if value.Len() < i { return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len()) } v := value.Index(i) - if err := requireAssignable(v, reflectValue); err != nil { + if err := requireAssignable(v, reflect.ValueOf(marshalledValues[i])); err != nil { return err } - - if err := set(v.Elem(), reflectValue, arg); err != nil { + if err := unpack(&arg.Type, v.Addr().Interface(), marshalledValues[i]); err != nil { return err } default: @@ -162,48 +246,7 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa } } return nil -} -// unpackAtomic unpacks ( hexdata -> go ) a single value -func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interface{}) error { - if len(marshalledValues) != 1 { - return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) - } - - elem := reflect.ValueOf(v).Elem() - kind := elem.Kind() - reflectValue := reflect.ValueOf(marshalledValues[0]) - - var abi2struct map[string]string - if kind == reflect.Struct { - var err error - if abi2struct, err = mapAbiToStructFields(arguments, elem); err != nil { - return err - } - arg := arguments.NonIndexed()[0] - if structField, ok := abi2struct[arg.Name]; ok { - return set(elem.FieldByName(structField), reflectValue, arg) - } - return nil - } - - return set(elem, reflectValue, arguments.NonIndexed()[0]) - -} - -// Computes the full size of an array; -// i.e. counting nested arrays, which count towards size for unpacking. -func getArraySize(arr *Type) int { - size := arr.Size - // Arrays can be nested, with each element being the same size - arr = arr.Elem - for arr.T == ArrayTy { - // Keep multiplying by elem.Size while the elem is an array. - size *= arr.Size - arr = arr.Elem - } - // Now we have the full array size, including its children. - return size } // UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification, @@ -214,7 +257,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { virtualArgs := 0 for index, arg := range arguments.NonIndexed() { marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) - if arg.Type.T == ArrayTy && (*arg.Type.Elem).T != StringTy { + if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. // This means that we need to add two 'virtual' arguments when @@ -225,7 +268,11 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { // // Calculate the full array size to get the correct offset for the next argument. // Decrement it by 1, as the normal index increment is still applied. - virtualArgs += getArraySize(&arg.Type) - 1 + virtualArgs += getTypeSize(arg.Type)/32 - 1 + } else if arg.Type.T == TupleTy && !isDynamicType(arg.Type) { + // If we have a static tuple, like (uint256, bool, uint256), these are + // coded as just like uint256,bool,uint256 + virtualArgs += getTypeSize(arg.Type)/32 - 1 } if err != nil { return nil, err @@ -255,7 +302,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { // input offset is the bytes offset for packed output inputOffset := 0 for _, abiArg := range abiArgs { - inputOffset += getDynamicTypeOffset(abiArg.Type) + inputOffset += getTypeSize(abiArg.Type) } var ret []byte for i, a := range args { diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index e0080ee73c..8adff04a83 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -29,303 +29,356 @@ import ( func TestPack(t *testing.T) { for i, test := range []struct { - typ string - - input interface{} - output []byte + typ string + components []ArgumentMarshaling + input interface{} + output []byte }{ { "uint8", + nil, uint8(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "uint8[]", + nil, []uint8{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "uint16", + nil, uint16(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "uint16[]", + nil, []uint16{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "uint32", + nil, uint32(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "uint32[]", + nil, []uint32{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "uint64", + nil, uint64(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "uint64[]", + nil, []uint64{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "uint256", + nil, big.NewInt(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "uint256[]", + nil, []*big.Int{big.NewInt(1), big.NewInt(2)}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "int8", + nil, int8(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "int8[]", + nil, []int8{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "int16", + nil, int16(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "int16[]", + nil, []int16{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "int32", + nil, int32(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "int32[]", + nil, []int32{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "int64", + nil, int64(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "int64[]", + nil, []int64{1, 2}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "int256", + nil, big.NewInt(2), common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), }, { "int256[]", + nil, []*big.Int{big.NewInt(1), big.NewInt(2)}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), }, { "bytes1", + nil, [1]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes2", + nil, [2]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes3", + nil, [3]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes4", + nil, [4]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes5", + nil, [5]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes6", + nil, [6]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes7", + nil, [7]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes8", + nil, [8]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes9", + nil, [9]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes10", + nil, [10]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes11", + nil, [11]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes12", + nil, [12]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes13", + nil, [13]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes14", + nil, [14]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes15", + nil, [15]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes16", + nil, [16]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes17", + nil, [17]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes18", + nil, [18]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes19", + nil, [19]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes20", + nil, [20]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes21", + nil, [21]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes22", + nil, [22]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes23", + nil, [23]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes24", - [24]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes24", + nil, [24]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes25", + nil, [25]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes26", + nil, [26]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes27", + nil, [27]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes28", + nil, [28]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes29", + nil, [29]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes30", + nil, [30]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes31", + nil, [31]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "bytes32", + nil, [32]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "uint32[2][3][4]", + nil, [4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018"), }, { "address[]", + nil, []common.Address{{1}, {2}}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"), }, { "bytes32[]", + nil, []common.Hash{{1}, {2}}, common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000"), }, { "function", + nil, [24]byte{1}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), }, { "string", + nil, "foobar", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"), }, { "string[]", + nil, []string{"hello", "foobar"}, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 @@ -337,6 +390,7 @@ func TestPack(t *testing.T) { }, { "string[2]", + nil, []string{"hello", "foobar"}, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset to i = 0 "0000000000000000000000000000000000000000000000000000000000000080" + // offset to i = 1 @@ -347,6 +401,7 @@ func TestPack(t *testing.T) { }, { "bytes32[][]", + nil, [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 @@ -362,6 +417,7 @@ func TestPack(t *testing.T) { { "bytes32[][2]", + nil, [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 @@ -375,6 +431,7 @@ func TestPack(t *testing.T) { }, { "bytes32[3][2]", + nil, [][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}}, common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] @@ -383,12 +440,182 @@ func TestPack(t *testing.T) { "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] }, + { + // static tuple + "tuple", + []ArgumentMarshaling{ + {Name: "a", Type: "int64"}, + {Name: "b", Type: "int256"}, + {Name: "c", Type: "int256"}, + {Name: "d", Type: "bool"}, + {Name: "e", Type: "bytes32[3][2]"}, + }, + struct { + A int64 + B *big.Int + C *big.Int + D bool + E [][]common.Hash + }{1, big.NewInt(1), big.NewInt(-1), true, [][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}}}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001" + // struct[a] + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // struct[c] + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[d] + "0100000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][1] + "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][2] + "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000"), // struct[e] array[1][2] + }, + { + // dynamic tuple + "tuple", + []ArgumentMarshaling{ + {Name: "a", Type: "string"}, + {Name: "b", Type: "int64"}, + {Name: "c", Type: "bytes"}, + {Name: "d", Type: "string[]"}, + {Name: "e", Type: "int256[]"}, + {Name: "f", Type: "address[]"}, + }, + struct { + FieldA string `abi:"a"` // Test whether abi tag works + FieldB int64 `abi:"b"` + C []byte + D []string + E []*big.Int + F []common.Address + }{"foobar", 1, []byte{1}, []string{"foo", "bar"}, []*big.Int{big.NewInt(1), big.NewInt(-1)}, []common.Address{{1}, {2}}}, + common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000c0" + // struct[a] offset + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] + "0000000000000000000000000000000000000000000000000000000000000100" + // struct[c] offset + "0000000000000000000000000000000000000000000000000000000000000140" + // struct[d] offset + "0000000000000000000000000000000000000000000000000000000000000220" + // struct[e] offset + "0000000000000000000000000000000000000000000000000000000000000280" + // struct[f] offset + "0000000000000000000000000000000000000000000000000000000000000006" + // struct[a] length + "666f6f6261720000000000000000000000000000000000000000000000000000" + // struct[a] "foobar" + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[c] length + "0100000000000000000000000000000000000000000000000000000000000000" + // []byte{1} + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[d] length + "0000000000000000000000000000000000000000000000000000000000000040" + // foo offset + "0000000000000000000000000000000000000000000000000000000000000080" + // bar offset + "0000000000000000000000000000000000000000000000000000000000000003" + // foo length + "666f6f0000000000000000000000000000000000000000000000000000000000" + // foo + "0000000000000000000000000000000000000000000000000000000000000003" + // bar offset + "6261720000000000000000000000000000000000000000000000000000000000" + // bar + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[e] length + "0000000000000000000000000000000000000000000000000000000000000001" + // 1 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // -1 + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[f] length + "0000000000000000000000000100000000000000000000000000000000000000" + // common.Address{1} + "0000000000000000000000000200000000000000000000000000000000000000"), // common.Address{2} + }, + { + // nested tuple + "tuple", + []ArgumentMarshaling{ + {Name: "a", Type: "tuple", Components: []ArgumentMarshaling{{Name: "a", Type: "uint256"}, {Name: "b", Type: "uint256[]"}}}, + {Name: "b", Type: "int256[]"}, + }, + struct { + A struct { + FieldA *big.Int `abi:"a"` + B []*big.Int + } + B []*big.Int + }{ + A: struct { + FieldA *big.Int `abi:"a"` // Test whether abi tag works for nested tuple + B []*big.Int + }{big.NewInt(1), []*big.Int{big.NewInt(1), big.NewInt(0)}}, + B: []*big.Int{big.NewInt(1), big.NewInt(0)}}, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // a offset + "00000000000000000000000000000000000000000000000000000000000000e0" + // b offset + "0000000000000000000000000000000000000000000000000000000000000001" + // a.a value + "0000000000000000000000000000000000000000000000000000000000000040" + // a.b offset + "0000000000000000000000000000000000000000000000000000000000000002" + // a.b length + "0000000000000000000000000000000000000000000000000000000000000001" + // a.b[0] value + "0000000000000000000000000000000000000000000000000000000000000000" + // a.b[1] value + "0000000000000000000000000000000000000000000000000000000000000002" + // b length + "0000000000000000000000000000000000000000000000000000000000000001" + // b[0] value + "0000000000000000000000000000000000000000000000000000000000000000"), // b[1] value + }, + { + // tuple slice + "tuple[]", + []ArgumentMarshaling{ + {Name: "a", Type: "int256"}, + {Name: "b", Type: "int256[]"}, + }, + []struct { + A *big.Int + B []*big.Int + }{ + {big.NewInt(-1), []*big.Int{big.NewInt(1), big.NewInt(0)}}, + {big.NewInt(1), []*big.Int{big.NewInt(2), big.NewInt(-1)}}, + }, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // tuple length + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset + "00000000000000000000000000000000000000000000000000000000000000e0" + // tuple[1] offset + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0].B offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].B length + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].B[0] value + "0000000000000000000000000000000000000000000000000000000000000000" + // tuple[0].B[1] value + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[1].B offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B length + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B[0] value + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].B[1] value + }, + { + // static tuple array + "tuple[2]", + []ArgumentMarshaling{ + {Name: "a", Type: "int256"}, + {Name: "b", Type: "int256"}, + }, + [2]struct { + A *big.Int + B *big.Int + }{ + {big.NewInt(-1), big.NewInt(1)}, + {big.NewInt(1), big.NewInt(-1)}, + }, + common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].a + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].b + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].a + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].b + }, + { + // dynamic tuple array + "tuple[2]", + []ArgumentMarshaling{ + {Name: "a", Type: "int256[]"}, + }, + [2]struct { + A []*big.Int + }{ + {[]*big.Int{big.NewInt(-1), big.NewInt(1)}}, + {[]*big.Int{big.NewInt(1), big.NewInt(-1)}}, + }, + common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset + "00000000000000000000000000000000000000000000000000000000000000c0" + // tuple[1] offset + "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[0].A offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].A length + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A[0] + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].A[1] + "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[1].A offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].A length + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A[0] + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].A[1] + }, } { - typ, err := NewType(test.typ) + typ, err := NewType(test.typ, test.components) if err != nil { t.Fatalf("%v failed. Unexpected parse error: %v", i, err) } - output, err := typ.pack(reflect.ValueOf(test.input)) if err != nil { t.Fatalf("%v failed. Unexpected pack error: %v", i, err) @@ -465,6 +692,59 @@ func TestMethodPack(t *testing.T) { if !bytes.Equal(packed, sig) { t.Errorf("expected %x got %x", sig, packed) } + + a := [2][2]*big.Int{{big.NewInt(1), big.NewInt(1)}, {big.NewInt(2), big.NewInt(0)}} + sig = abi.Methods["nestedArray"].Id() + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + sig = append(sig, common.LeftPadBytes(addrC[:], 32)...) + sig = append(sig, common.LeftPadBytes(addrD[:], 32)...) + packed, err = abi.Pack("nestedArray", a, []common.Address{addrC, addrD}) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(packed, sig) { + t.Errorf("expected %x got %x", sig, packed) + } + + sig = abi.Methods["nestedArray2"].Id() + sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0x80}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + packed, err = abi.Pack("nestedArray2", [2][]uint8{{1}, {1}}) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(packed, sig) { + t.Errorf("expected %x got %x", sig, packed) + } + + sig = abi.Methods["nestedSlice"].Id() + sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0x02}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{0xa0}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) + sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) + packed, err = abi.Pack("nestedSlice", [][]uint8{{1, 2}, {1, 2}}) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(packed, sig) { + t.Errorf("expected %x got %x", sig, packed) + } } func TestPackNumber(t *testing.T) { diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index ac249e8507..bcb5130a92 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -71,18 +71,17 @@ func mustArrayToByteSlice(value reflect.Value) reflect.Value { // // set is a bit more lenient when it comes to assignment and doesn't force an as // strict ruleset as bare `reflect` does. -func set(dst, src reflect.Value, output Argument) error { - dstType := dst.Type() - srcType := src.Type() +func set(dst, src reflect.Value) error { + dstType, srcType := dst.Type(), src.Type() switch { - case dstType.AssignableTo(srcType): + case dstType.Kind() == reflect.Interface: + return set(dst.Elem(), src) + case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT: + return set(dst.Elem(), src) + case srcType.AssignableTo(dstType) && dst.CanSet(): dst.Set(src) case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice: - return setSlice(dst, src, output) - case dstType.Kind() == reflect.Interface: - dst.Set(src) - case dstType.Kind() == reflect.Ptr: - return set(dst.Elem(), src, output) + return setSlice(dst, src) default: return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) } @@ -91,7 +90,7 @@ func set(dst, src reflect.Value, output Argument) error { // setSlice attempts to assign src to dst when slices are not assignable by default // e.g. src: [][]byte -> dst: [][15]byte -func setSlice(dst, src reflect.Value, output Argument) error { +func setSlice(dst, src reflect.Value) error { slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) for i := 0; i < src.Len(); i++ { v := src.Index(i) @@ -127,17 +126,14 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, return nil } -// mapAbiToStringField maps abi to struct fields. +// mapArgNamesToStructFields maps a slice of argument names to struct fields. // first round: for each Exportable field that contains a `abi:""` tag -// -// and this field name exists in the arguments, pair them together. -// -// second round: for each argument field that has not been already linked, -// -// find what variable is expected to be mapped into, if it exists and has not been -// used, pair them. -func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) { - +// and this field name exists in the given argument name list, pair them together. +// second round: for each argument name that has not been already linked, +// find what variable is expected to be mapped into, if it exists and has not been +// used, pair them. +// Note this function assumes the given value is a struct value. +func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) { typ := value.Type() abi2struct := make(map[string]string) @@ -151,45 +147,39 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) { continue } - // skip fields that have no abi:"" tag. var ok bool var tagName string if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { continue } - // check if tag is empty. if tagName == "" { return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName) } - // check which argument field matches with the abi tag. found := false - for _, abiField := range args.NonIndexed() { - if abiField.Name == tagName { - if abi2struct[abiField.Name] != "" { + for _, arg := range argNames { + if arg == tagName { + if abi2struct[arg] != "" { return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName) } // pair them - abi2struct[abiField.Name] = structFieldName - struct2abi[structFieldName] = abiField.Name + abi2struct[arg] = structFieldName + struct2abi[structFieldName] = arg found = true } } - // check if this tag has been mapped. if !found { return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName) } - } // second round ~~~ - for _, arg := range args { + for _, argName := range argNames { - abiFieldName := arg.Name - structFieldName := ToCamelCase(abiFieldName) + structFieldName := ToCamelCase(argName) if structFieldName == "" { return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") @@ -199,11 +189,11 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin // struct field with the same field name. If so, raise an error: // abi: [ { "name": "value" } ] // struct { Value *big.Int , Value1 *big.Int `abi:"value"`} - if abi2struct[abiFieldName] != "" { - if abi2struct[abiFieldName] != structFieldName && + if abi2struct[argName] != "" { + if abi2struct[argName] != structFieldName && struct2abi[structFieldName] == "" && value.FieldByName(structFieldName).IsValid() { - return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName) + return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", argName) } continue } @@ -215,16 +205,14 @@ func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]strin if value.FieldByName(structFieldName).IsValid() { // pair them - abi2struct[abiFieldName] = structFieldName - struct2abi[structFieldName] = abiFieldName + abi2struct[argName] = structFieldName + struct2abi[structFieldName] = argName } else { // not paired, but annotate as used, to detect cases like // abi : [ { "name": "value" }, { "name": "_value" } ] // struct { Value *big.Int } - struct2abi[structFieldName] = abiFieldName + struct2abi[structFieldName] = argName } - } - return abi2struct, nil } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index b114c16825..325cd724e4 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -33,6 +33,7 @@ const ( StringTy SliceTy ArrayTy + TupleTy AddressTy FixedBytesTy BytesTy @@ -44,13 +45,16 @@ const ( // Type is the reflection of the supported argument type type Type struct { Elem *Type - Kind reflect.Kind Type reflect.Type Size int T byte // Our own type checking stringKind string // holds the unparsed string for deriving signatures + + // Tuple relative fields + TupleElems []*Type // Type information of all tuple fields + TupleRawNames []string // Raw field name of all tuple fields } var ( @@ -59,7 +63,7 @@ var ( ) // NewType creates a new reflection type of abi type given in t. -func NewType(t string) (typ Type, err error) { +func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { // check that array brackets are equal if they exist if strings.Count(t, "[") != strings.Count(t, "]") { return Type{}, errors.New("invalid arg type in abi") @@ -72,7 +76,7 @@ func NewType(t string) (typ Type, err error) { if strings.Count(t, "[") != 0 { i := strings.LastIndex(t, "[") // recursively embed the type - embeddedType, err := NewType(t[:i]) + embeddedType, err := NewType(t[:i], components) if err != nil { return Type{}, err } @@ -88,6 +92,9 @@ func NewType(t string) (typ Type, err error) { typ.Kind = reflect.Slice typ.Elem = &embeddedType typ.Type = reflect.SliceOf(embeddedType.Type) + if embeddedType.T == TupleTy { + typ.stringKind = embeddedType.stringKind + sliced + } } else if len(intz) == 1 { // is a array typ.T = ArrayTy @@ -98,6 +105,9 @@ func NewType(t string) (typ Type, err error) { return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) } typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type) + if embeddedType.T == TupleTy { + typ.stringKind = embeddedType.stringKind + sliced + } } else { return Type{}, errors.New("invalid formatting of array type") } @@ -158,6 +168,40 @@ func NewType(t string) (typ Type, err error) { typ.Size = varSize typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0))) } + case "tuple": + var ( + fields []reflect.StructField + elems []*Type + names []string + expression string // canonical parameter expression + ) + expression += "(" + for idx, c := range components { + cType, err := NewType(c.Type, c.Components) + if err != nil { + return Type{}, err + } + if ToCamelCase(c.Name) == "" { + return Type{}, errors.New("abi: purely anonymous or underscored field is not supported") + } + fields = append(fields, reflect.StructField{ + Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field. + Type: cType.Type, + }) + elems = append(elems, &cType) + names = append(names, c.Name) + expression += cType.stringKind + if idx != len(components)-1 { + expression += "," + } + } + expression += ")" + typ.Kind = reflect.Struct + typ.Type = reflect.StructOf(fields) + typ.TupleElems = elems + typ.TupleRawNames = names + typ.T = TupleTy + typ.stringKind = expression case "function": typ.Kind = reflect.Array typ.T = FunctionTy @@ -178,7 +222,6 @@ func (t Type) String() (out string) { func (t Type) pack(v reflect.Value) ([]byte, error) { // dereference pointer first if it's a pointer v = indirect(v) - if err := typeCheck(t, v); err != nil { return nil, err } @@ -196,7 +239,7 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { offset := 0 offsetReq := isDynamicType(*t.Elem) if offsetReq { - offset = getDynamicTypeOffset(*t.Elem) * v.Len() + offset = getTypeSize(*t.Elem) * v.Len() } var tail []byte for i := 0; i < v.Len(); i++ { @@ -213,6 +256,45 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { tail = append(tail, val...) } return append(ret, tail...), nil + case TupleTy: + // (T1,...,Tk) for k >= 0 and any types T1, …, Tk + // enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k)) + // where X = (X(1), ..., X(k)) and head and tail are defined for Ti being a static + // type as + // head(X(i)) = enc(X(i)) and tail(X(i)) = "" (the empty string) + // and as + // head(X(i)) = enc(len(head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(i-1)))) + // tail(X(i)) = enc(X(i)) + // otherwise, i.e. if Ti is a dynamic type. + fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, v) + if err != nil { + return nil, err + } + // Calculate prefix occupied size. + offset := 0 + for _, elem := range t.TupleElems { + offset += getTypeSize(*elem) + } + var ret, tail []byte + for i, elem := range t.TupleElems { + field := v.FieldByName(fieldmap[t.TupleRawNames[i]]) + if !field.IsValid() { + return nil, fmt.Errorf("field %s for tuple not found in the given struct", t.TupleRawNames[i]) + } + val, err := elem.pack(field) + if err != nil { + return nil, err + } + if isDynamicType(*elem) { + ret = append(ret, packNum(reflect.ValueOf(offset))...) + tail = append(tail, val...) + offset += len(val) + } else { + ret = append(ret, val...) + } + } + return append(ret, tail...), nil + default: return packElement(t, v), nil } @@ -225,25 +307,45 @@ func (t Type) requiresLengthPrefix() bool { } // isDynamicType returns true if the type is dynamic. -// StringTy, BytesTy, and SliceTy(irrespective of slice element type) are dynamic types -// ArrayTy is considered dynamic if and only if the Array element is a dynamic type. -// This function recursively checks the type for slice and array elements. +// The following types are called “dynamic”: +// * bytes +// * string +// * T[] for any T +// * T[k] for any dynamic T and any k >= 0 +// * (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k func isDynamicType(t Type) bool { - // dynamic types - // array is also a dynamic type if the array type is dynamic + if t.T == TupleTy { + for _, elem := range t.TupleElems { + if isDynamicType(*elem) { + return true + } + } + return false + } return t.T == StringTy || t.T == BytesTy || t.T == SliceTy || (t.T == ArrayTy && isDynamicType(*t.Elem)) } -// getDynamicTypeOffset returns the offset for the type. -// See `isDynamicType` to know which types are considered dynamic. -// If the type t is an array and element type is not a dynamic type, then we consider it a static type and -// return 32 * size of array since length prefix is not required. -// If t is a dynamic type or element type(for slices and arrays) is dynamic, then we simply return 32 as offset. -func getDynamicTypeOffset(t Type) int { - // if it is an array and there are no dynamic types - // then the array is static type +// getTypeSize returns the size that this type needs to occupy. +// We distinguish static and dynamic types. Static types are encoded in-place +// and dynamic types are encoded at a separately allocated location after the +// current block. +// So for a static variable, the size returned represents the size that the +// variable actually occupies. +// For a dynamic variable, the returned size is fixed 32 bytes, which is used +// to store the location reference for actual value storage. +func getTypeSize(t Type) int { if t.T == ArrayTy && !isDynamicType(*t.Elem) { - return 32 * t.Size + // Recursively calculate type size if it is a nested array + if t.Elem.T == ArrayTy { + return t.Size * getTypeSize(*t.Elem) + } + return t.Size * 32 + } else if t.T == TupleTy && !isDynamicType(t) { + total := 0 + for _, elem := range t.TupleElems { + total += getTypeSize(*elem) + } + return total } return 32 } diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index a8c84430d7..fdedad0f66 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -32,72 +32,75 @@ type typeWithoutStringer Type // Tests that all allowed types get recognized by the type parser. func TestTypeRegexp(t *testing.T) { tests := []struct { - blob string - kind Type + blob string + components []ArgumentMarshaling + kind Type }{ - {"bool", Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, - {"bool[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, - {"bool[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, - {"bool[2][]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, - {"bool[][]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, - {"bool[][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, - {"bool[2][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, - {"bool[2][][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, - {"bool[2][2][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, - {"bool[][][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, - {"bool[][2][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, - {"int8", Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, - {"int16", Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, - {"int32", Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, - {"int64", Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, - {"int256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, - {"int8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, - {"int8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, - {"int16[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, - {"int16[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, - {"int32[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, - {"int32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, - {"int64[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, - {"int64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, - {"int256[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, - {"int256[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, - {"uint8", Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, - {"uint16", Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, - {"uint32", Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, - {"uint64", Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, - {"uint256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, - {"uint8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, - {"uint8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, - {"uint16[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, - {"uint16[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, - {"uint32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, - {"uint32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, - {"uint64[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, - {"uint64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, - {"uint256[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, - {"uint256[2]", Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, - {"bytes32", Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, - {"bytes[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Kind: reflect.Slice, Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, - {"bytes[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), Kind: reflect.Slice, stringKind: "bytes"}, stringKind: "bytes[2]"}}, - {"bytes32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Kind: reflect.Array, Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, - {"bytes32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, - {"string", Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, - {"string[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, - {"string[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, - {"address", Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, - {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, - {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, + {"bool", nil, Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, + {"bool[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, + {"bool[2]", nil, Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, + {"bool[2][]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, + {"bool[][]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, + {"bool[][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, + {"bool[2][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, + {"bool[2][][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, + {"bool[2][2][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, + {"bool[][][]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, + {"bool[][2][]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, + {"int8", nil, Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, + {"int16", nil, Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, + {"int32", nil, Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, + {"int64", nil, Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, + {"int256", nil, Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, + {"int8[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, + {"int8[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, + {"int16[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, + {"int16[2]", nil, Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, + {"int32[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, + {"int32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, + {"int64[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, + {"int64[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, + {"int256[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, + {"int256[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, + {"uint8", nil, Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, + {"uint16", nil, Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, + {"uint32", nil, Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, + {"uint64", nil, Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, + {"uint256", nil, Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, + {"uint8[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, + {"uint8[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, + {"uint16[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, + {"uint16[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, + {"uint32[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, + {"uint32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, + {"uint64[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, + {"uint64[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, + {"uint256[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, + {"uint256[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, + {"bytes32", nil, Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, + {"bytes[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Kind: reflect.Slice, Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, + {"bytes[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), Kind: reflect.Slice, stringKind: "bytes"}, stringKind: "bytes[2]"}}, + {"bytes32[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Kind: reflect.Array, Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, + {"bytes32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, + {"string", nil, Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, + {"string[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, + {"string[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, + {"address", nil, Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, + {"address[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, + {"address[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, // TODO when fixed types are implemented properly - // {"fixed", Type{}}, - // {"fixed128x128", Type{}}, - // {"fixed[]", Type{}}, - // {"fixed[2]", Type{}}, - // {"fixed128x128[]", Type{}}, - // {"fixed128x128[2]", Type{}}, + // {"fixed", nil, Type{}}, + // {"fixed128x128", nil, Type{}}, + // {"fixed[]", nil, Type{}}, + // {"fixed[2]", nil, Type{}}, + // {"fixed128x128[]", nil, Type{}}, + // {"fixed128x128[2]", nil, Type{}}, + {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct{ A int64 }{}), stringKind: "(int64)", + TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, } for _, tt := range tests { - typ, err := NewType(tt.blob) + typ, err := NewType(tt.blob, tt.components) if err != nil { t.Errorf("type %q: failed to parse type string: %v", tt.blob, err) } @@ -109,154 +112,170 @@ func TestTypeRegexp(t *testing.T) { func TestTypeCheck(t *testing.T) { for i, test := range []struct { - typ string - input interface{} - err string + typ string + components []ArgumentMarshaling + input interface{} + err string }{ - {"uint", big.NewInt(1), "unsupported arg type: uint"}, - {"int", big.NewInt(1), "unsupported arg type: int"}, - {"uint256", big.NewInt(1), ""}, - {"uint256[][3][]", [][3][]*big.Int{{{}}}, ""}, - {"uint256[][][3]", [3][][]*big.Int{{{}}}, ""}, - {"uint256[3][][]", [][][3]*big.Int{{{}}}, ""}, - {"uint256[3][3][3]", [3][3][3]*big.Int{{{}}}, ""}, - {"uint8[][]", [][]uint8{}, ""}, - {"int256", big.NewInt(1), ""}, - {"uint8", uint8(1), ""}, - {"uint16", uint16(1), ""}, - {"uint32", uint32(1), ""}, - {"uint64", uint64(1), ""}, - {"int8", int8(1), ""}, - {"int16", int16(1), ""}, - {"int32", int32(1), ""}, - {"int64", int64(1), ""}, - {"uint24", big.NewInt(1), ""}, - {"uint40", big.NewInt(1), ""}, - {"uint48", big.NewInt(1), ""}, - {"uint56", big.NewInt(1), ""}, - {"uint72", big.NewInt(1), ""}, - {"uint80", big.NewInt(1), ""}, - {"uint88", big.NewInt(1), ""}, - {"uint96", big.NewInt(1), ""}, - {"uint104", big.NewInt(1), ""}, - {"uint112", big.NewInt(1), ""}, - {"uint120", big.NewInt(1), ""}, - {"uint128", big.NewInt(1), ""}, - {"uint136", big.NewInt(1), ""}, - {"uint144", big.NewInt(1), ""}, - {"uint152", big.NewInt(1), ""}, - {"uint160", big.NewInt(1), ""}, - {"uint168", big.NewInt(1), ""}, - {"uint176", big.NewInt(1), ""}, - {"uint184", big.NewInt(1), ""}, - {"uint192", big.NewInt(1), ""}, - {"uint200", big.NewInt(1), ""}, - {"uint208", big.NewInt(1), ""}, - {"uint216", big.NewInt(1), ""}, - {"uint224", big.NewInt(1), ""}, - {"uint232", big.NewInt(1), ""}, - {"uint240", big.NewInt(1), ""}, - {"uint248", big.NewInt(1), ""}, - {"int24", big.NewInt(1), ""}, - {"int40", big.NewInt(1), ""}, - {"int48", big.NewInt(1), ""}, - {"int56", big.NewInt(1), ""}, - {"int72", big.NewInt(1), ""}, - {"int80", big.NewInt(1), ""}, - {"int88", big.NewInt(1), ""}, - {"int96", big.NewInt(1), ""}, - {"int104", big.NewInt(1), ""}, - {"int112", big.NewInt(1), ""}, - {"int120", big.NewInt(1), ""}, - {"int128", big.NewInt(1), ""}, - {"int136", big.NewInt(1), ""}, - {"int144", big.NewInt(1), ""}, - {"int152", big.NewInt(1), ""}, - {"int160", big.NewInt(1), ""}, - {"int168", big.NewInt(1), ""}, - {"int176", big.NewInt(1), ""}, - {"int184", big.NewInt(1), ""}, - {"int192", big.NewInt(1), ""}, - {"int200", big.NewInt(1), ""}, - {"int208", big.NewInt(1), ""}, - {"int216", big.NewInt(1), ""}, - {"int224", big.NewInt(1), ""}, - {"int232", big.NewInt(1), ""}, - {"int240", big.NewInt(1), ""}, - {"int248", big.NewInt(1), ""}, - {"uint30", uint8(1), "abi: cannot use uint8 as type ptr as argument"}, - {"uint8", uint16(1), "abi: cannot use uint16 as type uint8 as argument"}, - {"uint8", uint32(1), "abi: cannot use uint32 as type uint8 as argument"}, - {"uint8", uint64(1), "abi: cannot use uint64 as type uint8 as argument"}, - {"uint8", int8(1), "abi: cannot use int8 as type uint8 as argument"}, - {"uint8", int16(1), "abi: cannot use int16 as type uint8 as argument"}, - {"uint8", int32(1), "abi: cannot use int32 as type uint8 as argument"}, - {"uint8", int64(1), "abi: cannot use int64 as type uint8 as argument"}, - {"uint16", uint16(1), ""}, - {"uint16", uint8(1), "abi: cannot use uint8 as type uint16 as argument"}, - {"uint16[]", []uint16{1, 2, 3}, ""}, - {"uint16[]", [3]uint16{1, 2, 3}, ""}, - {"uint16[]", []uint32{1, 2, 3}, "abi: cannot use []uint32 as type [0]uint16 as argument"}, - {"uint16[3]", [3]uint32{1, 2, 3}, "abi: cannot use [3]uint32 as type [3]uint16 as argument"}, - {"uint16[3]", [4]uint16{1, 2, 3}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, - {"uint16[3]", []uint16{1, 2, 3}, ""}, - {"uint16[3]", []uint16{1, 2, 3, 4}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, - {"address[]", []common.Address{{1}}, ""}, - {"address[1]", []common.Address{{1}}, ""}, - {"address[1]", [1]common.Address{{1}}, ""}, - {"address[2]", [1]common.Address{{1}}, "abi: cannot use [1]array as type [2]array as argument"}, - {"bytes32", [32]byte{}, ""}, - {"bytes31", [31]byte{}, ""}, - {"bytes30", [30]byte{}, ""}, - {"bytes29", [29]byte{}, ""}, - {"bytes28", [28]byte{}, ""}, - {"bytes27", [27]byte{}, ""}, - {"bytes26", [26]byte{}, ""}, - {"bytes25", [25]byte{}, ""}, - {"bytes24", [24]byte{}, ""}, - {"bytes23", [23]byte{}, ""}, - {"bytes22", [22]byte{}, ""}, - {"bytes21", [21]byte{}, ""}, - {"bytes20", [20]byte{}, ""}, - {"bytes19", [19]byte{}, ""}, - {"bytes18", [18]byte{}, ""}, - {"bytes17", [17]byte{}, ""}, - {"bytes16", [16]byte{}, ""}, - {"bytes15", [15]byte{}, ""}, - {"bytes14", [14]byte{}, ""}, - {"bytes13", [13]byte{}, ""}, - {"bytes12", [12]byte{}, ""}, - {"bytes11", [11]byte{}, ""}, - {"bytes10", [10]byte{}, ""}, - {"bytes9", [9]byte{}, ""}, - {"bytes8", [8]byte{}, ""}, - {"bytes7", [7]byte{}, ""}, - {"bytes6", [6]byte{}, ""}, - {"bytes5", [5]byte{}, ""}, - {"bytes4", [4]byte{}, ""}, - {"bytes3", [3]byte{}, ""}, - {"bytes2", [2]byte{}, ""}, - {"bytes1", [1]byte{}, ""}, - {"bytes32", [33]byte{}, "abi: cannot use [33]uint8 as type [32]uint8 as argument"}, - {"bytes32", common.Hash{1}, ""}, - {"bytes31", common.Hash{1}, "abi: cannot use common.Hash as type [31]uint8 as argument"}, - {"bytes31", [32]byte{}, "abi: cannot use [32]uint8 as type [31]uint8 as argument"}, - {"bytes", []byte{0, 1}, ""}, - {"bytes", [2]byte{0, 1}, "abi: cannot use array as type slice as argument"}, - {"bytes", common.Hash{1}, "abi: cannot use array as type slice as argument"}, - {"string", "hello world", ""}, - {"string", string(""), ""}, - {"string", []byte{}, "abi: cannot use slice as type string as argument"}, - {"bytes32[]", [][32]byte{{}}, ""}, - {"function", [24]byte{}, ""}, - {"bytes20", common.Address{}, ""}, - {"address", [20]byte{}, ""}, - {"address", common.Address{}, ""}, - {"bytes32[]]", "", "invalid arg type in abi"}, - {"invalidType", "", "unsupported arg type: invalidType"}, - {"invalidSlice[]", "", "unsupported arg type: invalidSlice"}, + {"uint", nil, big.NewInt(1), "unsupported arg type: uint"}, + {"int", nil, big.NewInt(1), "unsupported arg type: int"}, + {"uint256", nil, big.NewInt(1), ""}, + {"uint256[][3][]", nil, [][3][]*big.Int{{{}}}, ""}, + {"uint256[][][3]", nil, [3][][]*big.Int{{{}}}, ""}, + {"uint256[3][][]", nil, [][][3]*big.Int{{{}}}, ""}, + {"uint256[3][3][3]", nil, [3][3][3]*big.Int{{{}}}, ""}, + {"uint8[][]", nil, [][]uint8{}, ""}, + {"int256", nil, big.NewInt(1), ""}, + {"uint8", nil, uint8(1), ""}, + {"uint16", nil, uint16(1), ""}, + {"uint32", nil, uint32(1), ""}, + {"uint64", nil, uint64(1), ""}, + {"int8", nil, int8(1), ""}, + {"int16", nil, int16(1), ""}, + {"int32", nil, int32(1), ""}, + {"int64", nil, int64(1), ""}, + {"uint24", nil, big.NewInt(1), ""}, + {"uint40", nil, big.NewInt(1), ""}, + {"uint48", nil, big.NewInt(1), ""}, + {"uint56", nil, big.NewInt(1), ""}, + {"uint72", nil, big.NewInt(1), ""}, + {"uint80", nil, big.NewInt(1), ""}, + {"uint88", nil, big.NewInt(1), ""}, + {"uint96", nil, big.NewInt(1), ""}, + {"uint104", nil, big.NewInt(1), ""}, + {"uint112", nil, big.NewInt(1), ""}, + {"uint120", nil, big.NewInt(1), ""}, + {"uint128", nil, big.NewInt(1), ""}, + {"uint136", nil, big.NewInt(1), ""}, + {"uint144", nil, big.NewInt(1), ""}, + {"uint152", nil, big.NewInt(1), ""}, + {"uint160", nil, big.NewInt(1), ""}, + {"uint168", nil, big.NewInt(1), ""}, + {"uint176", nil, big.NewInt(1), ""}, + {"uint184", nil, big.NewInt(1), ""}, + {"uint192", nil, big.NewInt(1), ""}, + {"uint200", nil, big.NewInt(1), ""}, + {"uint208", nil, big.NewInt(1), ""}, + {"uint216", nil, big.NewInt(1), ""}, + {"uint224", nil, big.NewInt(1), ""}, + {"uint232", nil, big.NewInt(1), ""}, + {"uint240", nil, big.NewInt(1), ""}, + {"uint248", nil, big.NewInt(1), ""}, + {"int24", nil, big.NewInt(1), ""}, + {"int40", nil, big.NewInt(1), ""}, + {"int48", nil, big.NewInt(1), ""}, + {"int56", nil, big.NewInt(1), ""}, + {"int72", nil, big.NewInt(1), ""}, + {"int80", nil, big.NewInt(1), ""}, + {"int88", nil, big.NewInt(1), ""}, + {"int96", nil, big.NewInt(1), ""}, + {"int104", nil, big.NewInt(1), ""}, + {"int112", nil, big.NewInt(1), ""}, + {"int120", nil, big.NewInt(1), ""}, + {"int128", nil, big.NewInt(1), ""}, + {"int136", nil, big.NewInt(1), ""}, + {"int144", nil, big.NewInt(1), ""}, + {"int152", nil, big.NewInt(1), ""}, + {"int160", nil, big.NewInt(1), ""}, + {"int168", nil, big.NewInt(1), ""}, + {"int176", nil, big.NewInt(1), ""}, + {"int184", nil, big.NewInt(1), ""}, + {"int192", nil, big.NewInt(1), ""}, + {"int200", nil, big.NewInt(1), ""}, + {"int208", nil, big.NewInt(1), ""}, + {"int216", nil, big.NewInt(1), ""}, + {"int224", nil, big.NewInt(1), ""}, + {"int232", nil, big.NewInt(1), ""}, + {"int240", nil, big.NewInt(1), ""}, + {"int248", nil, big.NewInt(1), ""}, + {"uint30", nil, uint8(1), "abi: cannot use uint8 as type ptr as argument"}, + {"uint8", nil, uint16(1), "abi: cannot use uint16 as type uint8 as argument"}, + {"uint8", nil, uint32(1), "abi: cannot use uint32 as type uint8 as argument"}, + {"uint8", nil, uint64(1), "abi: cannot use uint64 as type uint8 as argument"}, + {"uint8", nil, int8(1), "abi: cannot use int8 as type uint8 as argument"}, + {"uint8", nil, int16(1), "abi: cannot use int16 as type uint8 as argument"}, + {"uint8", nil, int32(1), "abi: cannot use int32 as type uint8 as argument"}, + {"uint8", nil, int64(1), "abi: cannot use int64 as type uint8 as argument"}, + {"uint16", nil, uint16(1), ""}, + {"uint16", nil, uint8(1), "abi: cannot use uint8 as type uint16 as argument"}, + {"uint16[]", nil, []uint16{1, 2, 3}, ""}, + {"uint16[]", nil, [3]uint16{1, 2, 3}, ""}, + {"uint16[]", nil, []uint32{1, 2, 3}, "abi: cannot use []uint32 as type [0]uint16 as argument"}, + {"uint16[3]", nil, [3]uint32{1, 2, 3}, "abi: cannot use [3]uint32 as type [3]uint16 as argument"}, + {"uint16[3]", nil, [4]uint16{1, 2, 3}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, + {"uint16[3]", nil, []uint16{1, 2, 3}, ""}, + {"uint16[3]", nil, []uint16{1, 2, 3, 4}, "abi: cannot use [4]uint16 as type [3]uint16 as argument"}, + {"address[]", nil, []common.Address{{1}}, ""}, + {"address[1]", nil, []common.Address{{1}}, ""}, + {"address[1]", nil, [1]common.Address{{1}}, ""}, + {"address[2]", nil, [1]common.Address{{1}}, "abi: cannot use [1]array as type [2]array as argument"}, + {"bytes32", nil, [32]byte{}, ""}, + {"bytes31", nil, [31]byte{}, ""}, + {"bytes30", nil, [30]byte{}, ""}, + {"bytes29", nil, [29]byte{}, ""}, + {"bytes28", nil, [28]byte{}, ""}, + {"bytes27", nil, [27]byte{}, ""}, + {"bytes26", nil, [26]byte{}, ""}, + {"bytes25", nil, [25]byte{}, ""}, + {"bytes24", nil, [24]byte{}, ""}, + {"bytes23", nil, [23]byte{}, ""}, + {"bytes22", nil, [22]byte{}, ""}, + {"bytes21", nil, [21]byte{}, ""}, + {"bytes20", nil, [20]byte{}, ""}, + {"bytes19", nil, [19]byte{}, ""}, + {"bytes18", nil, [18]byte{}, ""}, + {"bytes17", nil, [17]byte{}, ""}, + {"bytes16", nil, [16]byte{}, ""}, + {"bytes15", nil, [15]byte{}, ""}, + {"bytes14", nil, [14]byte{}, ""}, + {"bytes13", nil, [13]byte{}, ""}, + {"bytes12", nil, [12]byte{}, ""}, + {"bytes11", nil, [11]byte{}, ""}, + {"bytes10", nil, [10]byte{}, ""}, + {"bytes9", nil, [9]byte{}, ""}, + {"bytes8", nil, [8]byte{}, ""}, + {"bytes7", nil, [7]byte{}, ""}, + {"bytes6", nil, [6]byte{}, ""}, + {"bytes5", nil, [5]byte{}, ""}, + {"bytes4", nil, [4]byte{}, ""}, + {"bytes3", nil, [3]byte{}, ""}, + {"bytes2", nil, [2]byte{}, ""}, + {"bytes1", nil, [1]byte{}, ""}, + {"bytes32", nil, [33]byte{}, "abi: cannot use [33]uint8 as type [32]uint8 as argument"}, + {"bytes32", nil, common.Hash{1}, ""}, + {"bytes31", nil, common.Hash{1}, "abi: cannot use common.Hash as type [31]uint8 as argument"}, + {"bytes31", nil, [32]byte{}, "abi: cannot use [32]uint8 as type [31]uint8 as argument"}, + {"bytes", nil, []byte{0, 1}, ""}, + {"bytes", nil, [2]byte{0, 1}, "abi: cannot use array as type slice as argument"}, + {"bytes", nil, common.Hash{1}, "abi: cannot use array as type slice as argument"}, + {"string", nil, "hello world", ""}, + {"string", nil, string(""), ""}, + {"string", nil, []byte{}, "abi: cannot use slice as type string as argument"}, + {"bytes32[]", nil, [][32]byte{{}}, ""}, + {"function", nil, [24]byte{}, ""}, + {"bytes20", nil, common.Address{}, ""}, + {"address", nil, [20]byte{}, ""}, + {"address", nil, common.Address{}, ""}, + {"bytes32[]]", nil, "", "invalid arg type in abi"}, + {"invalidType", nil, "", "unsupported arg type: invalidType"}, + {"invalidSlice[]", nil, "", "unsupported arg type: invalidSlice"}, + // simple tuple + {"tuple", []ArgumentMarshaling{{Name: "a", Type: "uint256"}, {Name: "b", Type: "uint256"}}, struct { + A *big.Int + B *big.Int + }{}, ""}, + // tuple slice + {"tuple[]", []ArgumentMarshaling{{Name: "a", Type: "uint256"}, {Name: "b", Type: "uint256"}}, []struct { + A *big.Int + B *big.Int + }{}, ""}, + // tuple array + {"tuple[2]", []ArgumentMarshaling{{Name: "a", Type: "uint256"}, {Name: "b", Type: "uint256"}}, []struct { + A *big.Int + B *big.Int + }{{big.NewInt(0), big.NewInt(0)}, {big.NewInt(0), big.NewInt(0)}}, ""}, } { - typ, err := NewType(test.typ) + typ, err := NewType(test.typ, test.components) if err != nil && len(test.err) == 0 { t.Fatal("unexpected parse error:", err) } else if err != nil && len(test.err) != 0 { diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 27d3af3ee3..a1c3c804b1 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -116,17 +116,6 @@ func readFixedBytes(t Type, word []byte) (interface{}, error) { } -func getFullElemSize(elem *Type) int { - //all other should be counted as 32 (slices have pointers to respective elements) - size := 32 - //arrays wrap it, each element being the same size - for elem.T == ArrayTy { - size *= elem.Size - elem = elem.Elem - } - return size -} - // iteratively unpack elements func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) { if size < 0 { @@ -151,13 +140,9 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) // Arrays have packed elements, resulting in longer unpack steps. // Slices have just 32 bytes per element (pointing to the contents). - elemSize := 32 - if t.T == ArrayTy || t.T == SliceTy { - elemSize = getFullElemSize(t.Elem) - } + elemSize := getTypeSize(*t.Elem) for i, j := start, 0; j < size; i, j = i+elemSize, j+1 { - inter, err := toGoType(i, *t.Elem, output) if err != nil { return nil, err @@ -171,6 +156,36 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) return refSlice.Interface(), nil } +func forTupleUnpack(t Type, output []byte) (interface{}, error) { + retval := reflect.New(t.Type).Elem() + virtualArgs := 0 + for index, elem := range t.TupleElems { + marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output) + if elem.T == ArrayTy && !isDynamicType(*elem) { + // If we have a static array, like [3]uint256, these are coded as + // just like uint256,uint256,uint256. + // This means that we need to add two 'virtual' arguments when + // we count the index from now on. + // + // Array values nested multiple levels deep are also encoded inline: + // [2][3]uint256: uint256,uint256,uint256,uint256,uint256,uint256 + // + // Calculate the full array size to get the correct offset for the next argument. + // Decrement it by 1, as the normal index increment is still applied. + virtualArgs += getTypeSize(*elem)/32 - 1 + } else if elem.T == TupleTy && !isDynamicType(*elem) { + // If we have a static tuple, like (uint256, bool, uint256), these are + // coded as just like uint256,bool,uint256 + virtualArgs += getTypeSize(*elem)/32 - 1 + } + if err != nil { + return nil, err + } + retval.Field(index).Set(reflect.ValueOf(marshalledValue)) + } + return retval.Interface(), nil +} + // toGoType parses the output bytes and recursively assigns the value of these bytes // into a go type with accordance with the ABI spec. func toGoType(index int, t Type, output []byte) (interface{}, error) { @@ -179,14 +194,14 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { } var ( - returnOutput []byte - begin, end int - err error + returnOutput []byte + begin, length int + err error ) // if we require a length prefix, find the beginning word and size returned. if t.requiresLengthPrefix() { - begin, end, err = lengthPrefixPointsTo(index, output) + begin, length, err = lengthPrefixPointsTo(index, output) if err != nil { return nil, err } @@ -195,19 +210,26 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { } switch t.T { - case SliceTy: - if (*t.Elem).T == StringTy { - return forEachUnpack(t, output[begin:], 0, end) + case TupleTy: + if isDynamicType(t) { + begin, err := tuplePointsTo(index, output) + if err != nil { + return nil, err + } + return forTupleUnpack(t, output[begin:]) + } else { + return forTupleUnpack(t, output[index:]) } - return forEachUnpack(t, output, begin, end) + case SliceTy: + return forEachUnpack(t, output[begin:], 0, length) case ArrayTy: - if (*t.Elem).T == StringTy { + if isDynamicType(*t.Elem) { offset := int64(binary.BigEndian.Uint64(returnOutput[len(returnOutput)-8:])) return forEachUnpack(t, output[offset:], 0, t.Size) } - return forEachUnpack(t, output, index, t.Size) + return forEachUnpack(t, output[index:], 0, t.Size) case StringTy: // variable arrays are written at the end of the return bytes - return string(output[begin : begin+end]), nil + return string(output[begin : begin+length]), nil case IntTy, UintTy: return readInteger(t.T, t.Kind, returnOutput), nil case BoolTy: @@ -217,7 +239,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { case HashTy: return common.BytesToHash(returnOutput), nil case BytesTy: - return output[begin : begin+end], nil + return output[begin : begin+length], nil case FixedBytesTy: return readFixedBytes(t, returnOutput) case FunctionTy: @@ -258,3 +280,17 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err length = int(lengthBig.Uint64()) return } + +// tuplePointsTo resolves the location reference for dynamic tuple. +func tuplePointsTo(index int, output []byte) (start int, err error) { + offset := big.NewInt(0).SetBytes(output[index : index+32]) + outputLen := big.NewInt(int64(len(output))) + + if offset.Cmp(big.NewInt(int64(len(output)))) > 0 { + return 0, fmt.Errorf("abi: cannot marshal in to go slice: offset %v would go over slice boundary (len=%v)", offset, outputLen) + } + if offset.BitLen() > 63 { + return 0, fmt.Errorf("abi offset larger than int64: %v", offset) + } + return int(offset.Uint64()), nil +} diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 92b960f5e4..2b9514d6c1 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -173,7 +173,7 @@ var unpackTests = []unpackTest{ // multi dimensional, if these pass, all types that don't require length prefix should pass { def: `[{"type": "uint8[][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000E0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: [][]uint8{{1, 2}, {1, 2}}, }, { @@ -183,7 +183,7 @@ var unpackTests = []unpackTest{ }, { def: `[{"type": "uint8[][2]"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", + enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", want: [2][]uint8{{1}, {1}}, }, { @@ -603,6 +603,38 @@ func TestMultiReturnWithStringArray(t *testing.T) { } } +func TestMultiReturnWithStringSlice(t *testing.T) { + const definition = `[{"name" : "multi", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]` + abi, err := JSON(strings.NewReader(definition)) + if err != nil { + t.Fatal(err) + } + buff := new(bytes.Buffer) + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // output[0] offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000120")) // output[1] offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // output[0] length + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040")) // output[0][0] offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // output[0][1] offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000008")) // output[0][0] length + buff.Write(common.Hex2Bytes("657468657265756d000000000000000000000000000000000000000000000000")) // output[0][0] value + buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000b")) // output[0][1] length + buff.Write(common.Hex2Bytes("676f2d657468657265756d000000000000000000000000000000000000000000")) // output[0][1] value + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // output[1] length + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000064")) // output[1][0] value + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000065")) // output[1][1] value + ret1, ret1Exp := new([]string), []string{"ethereum", "go-ethereum"} + ret2, ret2Exp := new([]*big.Int), []*big.Int{big.NewInt(100), big.NewInt(101)} + if err := abi.Unpack(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(*ret1, ret1Exp) { + t.Error("string slice result", *ret1, "!= Expected", ret1Exp) + } + if !reflect.DeepEqual(*ret2, ret2Exp) { + t.Error("uint256 slice result", *ret2, "!= Expected", ret2Exp) + } +} + func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { // Similar to TestMultiReturnWithArray, but with a special case in mind: // values of nested static arrays count towards the size as well, and any element following @@ -892,6 +924,108 @@ func TestUnmarshal(t *testing.T) { } } +func TestUnpackTuple(t *testing.T) { + const simpleTuple = `[{"name":"tuple","constant":false,"outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]` + abi, err := JSON(strings.NewReader(simpleTuple)) + if err != nil { + t.Fatal(err) + } + buff := new(bytes.Buffer) + + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // ret[a] = 1 + buff.Write(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) // ret[b] = -1 + + v := struct { + Ret struct { + A *big.Int + B *big.Int + } + }{Ret: struct { + A *big.Int + B *big.Int + }{new(big.Int), new(big.Int)}} + + err = abi.Unpack(&v, "tuple", buff.Bytes()) + if err != nil { + t.Error(err) + } else { + if v.Ret.A.Cmp(big.NewInt(1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.Ret.A) + } + if v.Ret.B.Cmp(big.NewInt(-1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", v.Ret.B, -1) + } + } + + // Test nested tuple + const nestedTuple = `[{"name":"tuple","constant":false,"outputs":[ + {"type":"tuple","name":"s","components":[{"type":"uint256","name":"a"},{"type":"uint256[]","name":"b"},{"type":"tuple[]","name":"c","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}]}, + {"type":"tuple","name":"t","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}, + {"type":"uint256","name":"a"} + ]}]` + + abi, err = JSON(strings.NewReader(nestedTuple)) + if err != nil { + t.Fatal(err) + } + buff.Reset() + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000080")) // s offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")) // t.X = 0 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // t.Y = 1 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // a = 1 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.A = 1 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000060")) // s.B offset + buff.Write(common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000c0")) // s.C offset + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.B length + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.B[0] = 1 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.B[0] = 2 + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C length + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.C[0].X + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C[0].Y + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002")) // s.C[1].X + buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // s.C[1].Y + + type T struct { + X *big.Int `abi:"x"` + Z *big.Int `abi:"y"` // Test whether the abi tag works. + } + + type S struct { + A *big.Int + B []*big.Int + C []T + } + + type Ret struct { + FieldS S `abi:"s"` + FieldT T `abi:"t"` + A *big.Int + } + var ret Ret + var expected = Ret{ + FieldS: S{ + A: big.NewInt(1), + B: []*big.Int{big.NewInt(1), big.NewInt(2)}, + C: []T{ + {big.NewInt(1), big.NewInt(2)}, + {big.NewInt(2), big.NewInt(1)}, + }, + }, + FieldT: T{ + big.NewInt(0), big.NewInt(1), + }, + A: big.NewInt(1), + } + + err = abi.Unpack(&ret, "tuple", buff.Bytes()) + if err != nil { + t.Error(err) + } + if reflect.DeepEqual(ret, expected) { + t.Error("unexpected unpack value") + } +} + func TestOOMMaliciousInput(t *testing.T) { oomTests := []unpackTest{ { From 7d5953f97240674d3c9e98c82eee9d80d42724ff Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:07 +0800 Subject: [PATCH 036/280] accounts/abi: Extra slice tests (#18424) Co-authored-by: weimumu <934657014@qq.com> --- accounts/abi/unpack_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 2b9514d6c1..2f28fd03fb 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -176,6 +176,11 @@ var unpackTests = []unpackTest{ enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: [][]uint8{{1, 2}, {1, 2}}, }, + { + def: `[{"type": "uint8[][]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + want: [][]uint8{{1, 2}, {1, 2, 3}}, + }, { def: `[{"type": "uint8[2][2]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", @@ -251,6 +256,16 @@ var unpackTests = []unpackTest{ enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b676f2d657468657265756d000000000000000000000000000000000000000000", want: []string{"Ethereum", "go-ethereum"}, }, + { + def: `[{"type": "bytes[]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003f0f0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f0f0f00000000000000000000000000000000000000000000000000000000000", + want: [][]byte{{0xf0, 0xf0, 0xf0}, {0xf0, 0xf0, 0xf0}}, + }, + { + def: `[{"type": "uint256[2][][]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", + want: [][][2]*big.Int{{{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}, {{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}}, + }, { def: `[{"type": "int8[]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", From e70bb4b1197635b0970bec96632df645a4e31bc4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 037/280] accounts/abi: Add tests for reflection ahead of refactor (#18434) --- accounts/abi/reflect_test.go | 191 +++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 accounts/abi/reflect_test.go diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go new file mode 100644 index 0000000000..c425e6e54b --- /dev/null +++ b/accounts/abi/reflect_test.go @@ -0,0 +1,191 @@ +// Copyright 2019 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 . + +package abi + +import ( + "reflect" + "testing" +) + +type reflectTest struct { + name string + args []string + struc interface{} + want map[string]string + err string +} + +var reflectTests = []reflectTest{ + { + name: "OneToOneCorrespondance", + args: []string{"fieldA"}, + struc: struct { + FieldA int `abi:"fieldA"` + }{}, + want: map[string]string{ + "fieldA": "FieldA", + }, + }, + { + name: "MissingFieldsInStruct", + args: []string{"fieldA", "fieldB"}, + struc: struct { + FieldA int `abi:"fieldA"` + }{}, + want: map[string]string{ + "fieldA": "FieldA", + }, + }, + { + name: "MoreFieldsInStructThanArgs", + args: []string{"fieldA"}, + struc: struct { + FieldA int `abi:"fieldA"` + FieldB int + }{}, + want: map[string]string{ + "fieldA": "FieldA", + }, + }, + { + name: "MissingFieldInArgs", + args: []string{"fieldA"}, + struc: struct { + FieldA int `abi:"fieldA"` + FieldB int `abi:"fieldB"` + }{}, + err: "struct: abi tag 'fieldB' defined but not found in abi", + }, + { + name: "NoAbiDescriptor", + args: []string{"fieldA"}, + struc: struct { + FieldA int + }{}, + want: map[string]string{ + "fieldA": "FieldA", + }, + }, + { + name: "NoArgs", + args: []string{}, + struc: struct { + FieldA int `abi:"fieldA"` + }{}, + err: "struct: abi tag 'fieldA' defined but not found in abi", + }, + { + name: "DifferentName", + args: []string{"fieldB"}, + struc: struct { + FieldA int `abi:"fieldB"` + }{}, + want: map[string]string{ + "fieldB": "FieldA", + }, + }, + { + name: "DifferentName", + args: []string{"fieldB"}, + struc: struct { + FieldA int `abi:"fieldB"` + }{}, + want: map[string]string{ + "fieldB": "FieldA", + }, + }, + { + name: "MultipleFields", + args: []string{"fieldA", "fieldB"}, + struc: struct { + FieldA int `abi:"fieldA"` + FieldB int `abi:"fieldB"` + }{}, + want: map[string]string{ + "fieldA": "FieldA", + "fieldB": "FieldB", + }, + }, + { + name: "MultipleFieldsABIMissing", + args: []string{"fieldA", "fieldB"}, + struc: struct { + FieldA int `abi:"fieldA"` + FieldB int + }{}, + want: map[string]string{ + "fieldA": "FieldA", + "fieldB": "FieldB", + }, + }, + { + name: "NameConflict", + args: []string{"fieldB"}, + struc: struct { + FieldA int `abi:"fieldB"` + FieldB int + }{}, + err: "abi: multiple variables maps to the same abi field 'fieldB'", + }, + { + name: "Underscored", + args: []string{"_"}, + struc: struct { + FieldA int + }{}, + err: "abi: purely underscored output cannot unpack to struct", + }, + { + name: "DoubleMapping", + args: []string{"fieldB", "fieldC", "fieldA"}, + struc: struct { + FieldA int `abi:"fieldC"` + FieldB int + }{}, + err: "abi: multiple outputs mapping to the same struct field 'FieldA'", + }, + { + name: "AlreadyMapped", + args: []string{"fieldB", "fieldB"}, + struc: struct { + FieldB int `abi:"fieldB"` + }{}, + err: "struct: abi tag in 'FieldB' already mapped", + }, +} + +func TestReflectNameToStruct(t *testing.T) { + for _, test := range reflectTests { + t.Run(test.name, func(t *testing.T) { + m, err := mapArgNamesToStructFields(test.args, reflect.ValueOf(test.struc)) + if len(test.err) > 0 { + if err == nil || err.Error() != test.err { + t.Fatalf("Invalid error: expected %v, got %v", test.err, err) + } + } else { + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + for fname := range test.want { + if m[fname] != test.want[fname] { + t.Fatalf("Incorrect value for field %s: expected %v, got %v", fname, test.want[fname], m[fname]) + } + } + } + }) + } +} From d44902a64ad533ca65fe874023142b22e85fd4ec Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 038/280] accounts/abi: allow interface as the destination (#18490) --- accounts/abi/reflect.go | 2 +- accounts/abi/unpack_test.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index bcb5130a92..fc2faa6869 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -74,7 +74,7 @@ func mustArrayToByteSlice(value reflect.Value) reflect.Value { func set(dst, src reflect.Value) error { dstType, srcType := dst.Type(), src.Type() switch { - case dstType.Kind() == reflect.Interface: + case dstType.Kind() == reflect.Interface && dst.Elem().IsValid(): return set(dst.Elem(), src) case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT: return set(dst.Elem(), src) diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 2f28fd03fb..e8f8995f5c 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -512,6 +512,11 @@ func TestMethodMultiReturn(t *testing.T) { Int *big.Int } + newInterfaceSlice := func(len int) interface{} { + slice := make([]interface{}, len) + return &slice + } + abi, data, expected := methodMultiReturn(require.New(t)) bigint := new(big.Int) var testCases = []struct { @@ -539,6 +544,16 @@ func TestMethodMultiReturn(t *testing.T) { &[2]interface{}{&expected.Int, &expected.String}, "", "Can unpack into an array", + }, { + &[2]interface{}{}, + &[2]interface{}{expected.Int, expected.String}, + "", + "Can unpack into interface array", + }, { + newInterfaceSlice(2), + &[]interface{}{expected.Int, expected.String}, + "", + "Can unpack into interface slice", }, { &[]interface{}{new(int), new(int)}, &[]interface{}{&expected.Int, &expected.String}, From e3c75c01c73b73fdfa8b293a481d4ccbf4fcc09d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 039/280] accounts/usbwallet: support trezor passphrases (#16503) When opening the wallet, ask for passphrase as well as for the PIN and return the relevant error (PIN/passphrase required). Open must then be called again with either PIN or passphrase to advance the process. This also updates the console bridge to support passphrase authentication. --- accounts/usbwallet/trezor.go | 78 ++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index cd8f3d4516..a58251028d 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -42,6 +42,9 @@ import ( // encoded passphrase. var ErrTrezorPINNeeded = errors.New("trezor: pin needed") +// ErrTrezorPassphraseNeeded is returned if opening the trezor requires a passphrase +var ErrTrezorPassphraseNeeded = errors.New("trezor: passphrase needed") + // errTrezorReplyInvalidHeader is the error message returned by a Trezor data exchange // if the device replies with a mismatching header. This usually means the device // is in browser mode. @@ -49,12 +52,13 @@ var errTrezorReplyInvalidHeader = errors.New("trezor: invalid reply header") // trezorDriver implements the communication with a Trezor hardware wallet. type trezorDriver struct { - device io.ReadWriter // USB device connection to communicate through - version [3]uint32 // Current version of the Trezor firmware - label string // Current textual label of the Trezor device - pinwait bool // Flags whether the device is waiting for PIN entry - failure error // Any failure that would make the device unusable - log log.Logger // Contextual logger to tag the trezor with its id + device io.ReadWriter // USB device connection to communicate through + version [3]uint32 // Current version of the Trezor firmware + label string // Current textual label of the Trezor device + pinwait bool // Flags whether the device is waiting for PIN entry + passphrasewait bool // Flags whether the device is waiting for passphrase entry + failure error // Any failure that would make the device unusable + log log.Logger // Contextual logger to tag the trezor with its id } // newTrezorDriver creates a new instance of a Trezor USB protocol driver. @@ -80,19 +84,21 @@ func (w *trezorDriver) Status() (string, error) { } // Open implements usbwallet.driver, attempting to initialize the connection to -// the Trezor hardware wallet. Initializing the Trezor is a two phase operation: -// - The first phase is to initialize the connection and read the wallet's -// features. This phase is invoked is the provided passphrase is empty. The -// device will display the pinpad as a result and will return an appropriate -// error to notify the user that a second open phase is needed. -// - The second phase is to unlock access to the Trezor, which is done by the -// user actually providing a passphrase mapping a keyboard keypad to the pin -// number of the user (shuffled according to the pinpad displayed). +// the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation: +// * The first phase is to initialize the connection and read the wallet's +// features. This phase is invoked is the provided passphrase is empty. The +// device will display the pinpad as a result and will return an appropriate +// error to notify the user that a second open phase is needed. +// * The second phase is to unlock access to the Trezor, which is done by the +// user actually providing a passphrase mapping a keyboard keypad to the pin +// number of the user (shuffled according to the pinpad displayed). +// * If needed the device will ask for passphrase which will require calling +// open again with the actual passphrase (3rd phase) func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { w.device, w.failure = device, nil // If phase 1 is requested, init the connection and wait for user callback - if passphrase == "" { + if passphrase == "" && !w.passphrasewait { // If we're already waiting for a PIN entry, insta-return if w.pinwait { return ErrTrezorPINNeeded @@ -105,26 +111,46 @@ func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { w.version = [3]uint32{features.GetMajorVersion(), features.GetMinorVersion(), features.GetPatchVersion()} w.label = features.GetLabel() - // Do a manual ping, forcing the device to ask for its PIN + // Do a manual ping, forcing the device to ask for its PIN and Passphrase askPin := true - res, err := w.trezorExchange(&trezor.Ping{PinProtection: &askPin}, new(trezor.PinMatrixRequest), new(trezor.Success)) + askPassphrase := true + res, err := w.trezorExchange(&trezor.Ping{PinProtection: &askPin, PassphraseProtection: &askPassphrase}, new(trezor.PinMatrixRequest), new(trezor.PassphraseRequest), new(trezor.Success)) if err != nil { return err } // Only return the PIN request if the device wasn't unlocked until now - if res == 1 { - return nil // Device responded with trezor.Success + switch res { + case 0: + w.pinwait = true + return ErrTrezorPINNeeded + case 1: + w.pinwait = false + w.passphrasewait = true + return ErrTrezorPassphraseNeeded + case 2: + return nil // responded with trezor.Success } - w.pinwait = true - return ErrTrezorPINNeeded } // Phase 2 requested with actual PIN entry - w.pinwait = false - - if _, err := w.trezorExchange(&trezor.PinMatrixAck{Pin: &passphrase}, new(trezor.Success)); err != nil { - w.failure = err - return err + if w.pinwait { + w.pinwait = false + res, err := w.trezorExchange(&trezor.PinMatrixAck{Pin: &passphrase}, new(trezor.Success), new(trezor.PassphraseRequest)) + if err != nil { + w.failure = err + return err + } + if res == 1 { + w.passphrasewait = true + return ErrTrezorPassphraseNeeded + } + } else if w.passphrasewait { + w.passphrasewait = false + if _, err := w.trezorExchange(&trezor.PassphraseAck{Passphrase: &passphrase}, new(trezor.Success)); err != nil { + w.failure = err + return err + } } + return nil } From f0ed12486ae796cccec3f98abf61b6c77e68abd0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 040/280] accounts/usbwallet/trezor: expose protobuf package (#17980) When some of the same messages are redefined anywhere in a Go project, the protobuf package panics (see https://github.com/golang/protobuf/issues/178). Since this package is internal, there is no way to work around it, as one cannot use it directly, but also cannot define the same messages. There is no downside in making the package accessible. --- accounts/usbwallet/trezor.go | 22 +++++++++---------- .../{internal => }/trezor/messages.pb.go | 0 .../{internal => }/trezor/messages.proto | 0 .../usbwallet/{internal => }/trezor/trezor.go | 0 .../{internal => }/trezor/types.pb.go | 0 .../{internal => }/trezor/types.proto | 0 6 files changed, 11 insertions(+), 11 deletions(-) rename accounts/usbwallet/{internal => }/trezor/messages.pb.go (100%) rename accounts/usbwallet/{internal => }/trezor/messages.proto (100%) rename accounts/usbwallet/{internal => }/trezor/trezor.go (100%) rename accounts/usbwallet/{internal => }/trezor/types.pb.go (100%) rename accounts/usbwallet/{internal => }/trezor/types.proto (100%) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index a58251028d..3b63a9f234 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -28,7 +28,7 @@ import ( "math/big" "github.com/XinFinOrg/XDPoSChain/accounts" - "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/internal/trezor" + "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/trezor" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -85,15 +85,15 @@ func (w *trezorDriver) Status() (string, error) { // Open implements usbwallet.driver, attempting to initialize the connection to // the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation: -// * The first phase is to initialize the connection and read the wallet's -// features. This phase is invoked is the provided passphrase is empty. The -// device will display the pinpad as a result and will return an appropriate -// error to notify the user that a second open phase is needed. -// * The second phase is to unlock access to the Trezor, which is done by the -// user actually providing a passphrase mapping a keyboard keypad to the pin -// number of the user (shuffled according to the pinpad displayed). -// * If needed the device will ask for passphrase which will require calling -// open again with the actual passphrase (3rd phase) +// - The first phase is to initialize the connection and read the wallet's +// features. This phase is invoked is the provided passphrase is empty. The +// device will display the pinpad as a result and will return an appropriate +// error to notify the user that a second open phase is needed. +// - The second phase is to unlock access to the Trezor, which is done by the +// user actually providing a passphrase mapping a keyboard keypad to the pin +// number of the user (shuffled according to the pinpad displayed). +// - If needed the device will ask for passphrase which will require calling +// open again with the actual passphrase (3rd phase) func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error { w.device, w.failure = device, nil @@ -249,7 +249,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction } else { // Trezor backend does not support typed transactions yet. signer = types.NewEIP155Signer(chainID) - signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2 + 35) } // Inject the final signature into the transaction and sanity check the sender diff --git a/accounts/usbwallet/internal/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go similarity index 100% rename from accounts/usbwallet/internal/trezor/messages.pb.go rename to accounts/usbwallet/trezor/messages.pb.go diff --git a/accounts/usbwallet/internal/trezor/messages.proto b/accounts/usbwallet/trezor/messages.proto similarity index 100% rename from accounts/usbwallet/internal/trezor/messages.proto rename to accounts/usbwallet/trezor/messages.proto diff --git a/accounts/usbwallet/internal/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go similarity index 100% rename from accounts/usbwallet/internal/trezor/trezor.go rename to accounts/usbwallet/trezor/trezor.go diff --git a/accounts/usbwallet/internal/trezor/types.pb.go b/accounts/usbwallet/trezor/types.pb.go similarity index 100% rename from accounts/usbwallet/internal/trezor/types.pb.go rename to accounts/usbwallet/trezor/types.pb.go diff --git a/accounts/usbwallet/internal/trezor/types.proto b/accounts/usbwallet/trezor/types.proto similarity index 100% rename from accounts/usbwallet/internal/trezor/types.proto rename to accounts/usbwallet/trezor/types.proto From fe14069bd75a2dd5cb0e9cad147ea710014c9ba7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 041/280] accounts: support for external signer API (#18079) --- accounts/accounts.go | 20 ++++++++++++++++---- accounts/accounts_test.go | 32 ++++++++++++++++++++++++++++++++ accounts/keystore/wallet.go | 20 +++++++++++++++----- accounts/usbwallet/wallet.go | 20 +++++++++++++++----- eth/backend.go | 4 ++-- internal/ethapi/api.go | 4 ++-- 6 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 accounts/accounts_test.go diff --git a/accounts/accounts.go b/accounts/accounts.go index f6dd18ff17..0b1e555f3f 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -89,7 +89,19 @@ type Wallet interface { // chain state reader. SelfDerive(base DerivationPath, chain ethereum.ChainStateReader) - // SignHash requests the wallet to sign the given hash. + // SignData requests the wallet to sign the hash of the given data + // It looks up the account specified either solely via its address contained within, + // or optionally with the aid of any location metadata from the embedded URL field. + // + // If the wallet requires additional authentication to sign the request (e.g. + // a password to decrypt the account, or a PIN code o verify the transaction), + // an AuthNeededError instance will be returned, containing infos for the user + // about which fields or actions are needed. The user may retry by providing + // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock + // the account in a keystore). + SignData(account Account, mimeType string, data []byte) ([]byte, error) + + // SignText requests the wallet to sign the given hash. // // It looks up the account specified either solely via its address contained within, // or optionally with the aid of any location metadata from the embedded URL field. @@ -100,7 +112,7 @@ type Wallet interface { // about which fields or actions are needed. The user may retry by providing // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock // the account in a keystore). - SignHash(account Account, hash []byte) ([]byte, error) + SignText(account Account, text []byte) ([]byte, error) // SignTx requests the wallet to sign the given transaction. // @@ -115,12 +127,12 @@ type Wallet interface { // the account in a keystore). SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) - // SignHashWithPassphrase requests the wallet to sign the given hash with the + // SignTextWithPassphrase requests the wallet to sign the given hash with the // given passphrase as extra authentication information. // // It looks up the account specified either solely via its address contained within, // or optionally with the aid of any location metadata from the embedded URL field. - SignHashWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) + SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) // SignTxWithPassphrase requests the wallet to sign the given transaction, with the // given passphrase as extra authentication information. diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go new file mode 100644 index 0000000000..babbbc85c5 --- /dev/null +++ b/accounts/accounts_test.go @@ -0,0 +1,32 @@ +// Copyright 2019 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 . + +package accounts + +import ( + "bytes" + "testing" + + "github.com/XinFinOrg/XDPoSChain/common/hexutil" +) + +func TestTextHash(t *testing.T) { + hash := TextHash([]byte("Hello Joe")) + want := hexutil.MustDecode("0xa080337ae51c4e064c189e113edd0ba391df9206e2f49db658bb32cf2911730b") + if !bytes.Equal(hash, want) { + t.Fatalf("wrong hash: %x", hash) + } +} diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 41c270c4fd..e1ec309457 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -22,6 +22,7 @@ import ( ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" ) // keystoreWallet implements the accounts.Wallet interface for the original @@ -78,11 +79,11 @@ func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (account // there is no notion of hierarchical account derivation for plain keystore accounts. func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) {} -// SignHash implements accounts.Wallet, attempting to sign the given hash with +// signHash attempts to sign the given hash with // the given account. If the wallet does not wrap this particular account, an // error is returned to avoid account leakage (even though in theory we may be // able to sign via our shared keystore backend). -func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { +func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { // Make sure the requested account is contained within if !w.Contains(account) { return nil, accounts.ErrUnknownAccount @@ -91,6 +92,15 @@ func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte return w.keystore.SignHash(account, hash) } +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.signHash(account, crypto.Keccak256(data)) +} + +func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.signHash(account, accounts.TextHash(text)) +} + // SignTx implements accounts.Wallet, attempting to sign the given transaction // with the given account. If the wallet does not wrap this particular account, // an error is returned to avoid account leakage (even though in theory we may @@ -104,15 +114,15 @@ func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, return w.keystore.SignTx(account, tx, chainID) } -// SignHashWithPassphrase implements accounts.Wallet, attempting to sign the +// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the // given hash with the given account using passphrase as extra authentication. -func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { +func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { // Make sure the requested account is contained within if !w.Contains(account) { return nil, accounts.ErrUnknownAccount } // Account seems valid, request the keystore to sign - return w.keystore.SignHashWithPassphrase(account, passphrase, hash) + return w.keystore.SignHashWithPassphrase(account, passphrase, accounts.TextHash(text)) } // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 6778c2e015..38a8eefa30 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/karalabe/hid" ) @@ -495,12 +496,21 @@ func (w *wallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainSt w.deriveChain = chain } -// SignHash implements accounts.Wallet, however signing arbitrary data is not +// signHash implements accounts.Wallet, however signing arbitrary data is not // supported for hardware wallets, so this method will always return an error. -func (w *wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { +func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { return nil, accounts.ErrNotSupported } +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.signHash(account, crypto.Keccak256(data)) +} + +func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.signHash(account, accounts.TextHash(text)) +} + // SignTx implements accounts.Wallet. It sends the transaction over to the Ledger // wallet to request a confirmation from the user. It returns either the signed // transaction or a failure if the user denied the transaction. @@ -547,11 +557,11 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID return signed, nil } -// SignHashWithPassphrase implements accounts.Wallet, however signing arbitrary +// SignTextWithPassphrase implements accounts.Wallet, however signing arbitrary // data is not supported for Ledger wallets, so this method will always return // an error. -func (w *wallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { - return w.SignHash(account, hash) +func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return w.SignText(account, accounts.TextHash(text)) } // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given diff --git a/eth/backend.go b/eth/backend.go index dcfbf8c137..653694e38c 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -282,7 +282,7 @@ func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX return block, false, err } header := block.Header() - sighash, err := wallet.SignHash(accounts.Account{Address: eb}, c.SigHash(header).Bytes()) + sighash, err := wallet.SignText(accounts.Account{Address: eb}, c.SigHash(header).Bytes()) if err != nil || sighash == nil { log.Error("Can't get signature hash of m2", "sighash", sighash, "err", err) return block, false, err @@ -503,7 +503,7 @@ func (e *Ethereum) StartStaking(local bool) error { log.Error("Etherbase account unavailable locally", "address", eb, "err", err) return fmt.Errorf("signer missing: %v", err) } - XDPoS.Authorize(eb, wallet.SignHash) + XDPoS.Authorize(eb, wallet.SignText) } if local { // If local (CPU) mining is started, we can disable the transaction rejection diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 12085a9c69..eb9cac622c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -543,7 +543,7 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c return nil, err } // Assemble sign the data with the wallet - signature, err := wallet.SignHashWithPassphrase(account, passwd, signHash(data)) + signature, err := wallet.SignTextWithPassphrase(account, passwd, signHash(data)) if err != nil { return nil, err } @@ -3292,7 +3292,7 @@ func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) return nil, err } // Sign the requested hash with the wallet - signature, err := wallet.SignHash(account, signHash(data)) + signature, err := wallet.SignText(account, signHash(data)) if err == nil { signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper } From 07935ce1249b6302a20a98a0c0f3fc191325d988 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 042/280] accounts: support for external signer API (#18079) --- accounts/accounts.go | 13 +++++++++++++ accounts/keystore/wallet.go | 8 ++++---- accounts/usbwallet/wallet.go | 6 +++--- eth/backend.go | 4 ++-- internal/ethapi/api.go | 17 ++--------------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 0b1e555f3f..78b63d3983 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -89,6 +89,19 @@ type Wallet interface { // chain state reader. SelfDerive(base DerivationPath, chain ethereum.ChainStateReader) + // SignHash requests the wallet to sign the given hash. + // + // It looks up the account specified either solely via its address contained within, + // or optionally with the aid of any location metadata from the embedded URL field. + // + // If the wallet requires additional authentication to sign the request (e.g. + // a password to decrypt the account, or a PIN code o verify the transaction), + // an AuthNeededError instance will be returned, containing infos for the user + // about which fields or actions are needed. The user may retry by providing + // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock + // the account in a keystore). + SignHash(account Account, hash []byte) ([]byte, error) + // SignData requests the wallet to sign the hash of the given data // It looks up the account specified either solely via its address contained within, // or optionally with the aid of any location metadata from the embedded URL field. diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index e1ec309457..602d640caa 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -79,11 +79,11 @@ func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (account // there is no notion of hierarchical account derivation for plain keystore accounts. func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) {} -// signHash attempts to sign the given hash with +// SignHash attempts to sign the given hash with // the given account. If the wallet does not wrap this particular account, an // error is returned to avoid account leakage (even though in theory we may be // able to sign via our shared keystore backend). -func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { +func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { // Make sure the requested account is contained within if !w.Contains(account) { return nil, accounts.ErrUnknownAccount @@ -94,11 +94,11 @@ func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte // SignData signs keccak256(data). The mimetype parameter describes the type of data being signed func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - return w.signHash(account, crypto.Keccak256(data)) + return w.SignHash(account, crypto.Keccak256(data)) } func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { - return w.signHash(account, accounts.TextHash(text)) + return w.SignHash(account, accounts.TextHash(text)) } // SignTx implements accounts.Wallet, attempting to sign the given transaction diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 38a8eefa30..40dda2b410 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -498,17 +498,17 @@ func (w *wallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainSt // signHash implements accounts.Wallet, however signing arbitrary data is not // supported for hardware wallets, so this method will always return an error. -func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { +func (w *wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { return nil, accounts.ErrNotSupported } // SignData signs keccak256(data). The mimetype parameter describes the type of data being signed func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - return w.signHash(account, crypto.Keccak256(data)) + return w.SignHash(account, crypto.Keccak256(data)) } func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { - return w.signHash(account, accounts.TextHash(text)) + return w.SignHash(account, accounts.TextHash(text)) } // SignTx implements accounts.Wallet. It sends the transaction over to the Ledger diff --git a/eth/backend.go b/eth/backend.go index 653694e38c..dcfbf8c137 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -282,7 +282,7 @@ func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX return block, false, err } header := block.Header() - sighash, err := wallet.SignText(accounts.Account{Address: eb}, c.SigHash(header).Bytes()) + sighash, err := wallet.SignHash(accounts.Account{Address: eb}, c.SigHash(header).Bytes()) if err != nil || sighash == nil { log.Error("Can't get signature hash of m2", "sighash", sighash, "err", err) return block, false, err @@ -503,7 +503,7 @@ func (e *Ethereum) StartStaking(local bool) error { log.Error("Etherbase account unavailable locally", "address", eb, "err", err) return fmt.Errorf("signer missing: %v", err) } - XDPoS.Authorize(eb, wallet.SignText) + XDPoS.Authorize(eb, wallet.SignHash) } if local { // If local (CPU) mining is started, we can disable the transaction rejection diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index eb9cac622c..867c9e2d87 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -512,19 +512,6 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args Transactio return &SignTransactionResult{data, signed}, nil } -// signHash is a helper function that calculates a hash for the given message that can be -// safely used to calculate a signature from. -// -// The hash is calulcated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). -// -// This gives context to the signed message and prevents signing of transactions. -func signHash(data []byte) []byte { - msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) - return crypto.Keccak256([]byte(msg)) -} - // Sign calculates an Ethereum ECDSA signature for: // keccack256("\x19Ethereum Signed Message:\n" + len(message) + message)) // @@ -543,7 +530,7 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c return nil, err } // Assemble sign the data with the wallet - signature, err := wallet.SignTextWithPassphrase(account, passwd, signHash(data)) + signature, err := wallet.SignTextWithPassphrase(account, passwd, data) if err != nil { return nil, err } @@ -3292,7 +3279,7 @@ func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) return nil, err } // Sign the requested hash with the wallet - signature, err := wallet.SignText(account, signHash(data)) + signature, err := wallet.SignText(account, data) if err == nil { signature[crypto.RecoveryIDOffset] += 27 // Transform V from 0/1 to 27/28 according to the yellow paper } From 43e6c8ecdc582cf4ce7a8483ff6d8ce32469c616 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 043/280] accounts: implemented EIP191/712 (#17789) --- accounts/accounts.go | 29 +++++++++++++++++------------ accounts/keystore/wallet.go | 32 +++++++++++++++++++++----------- accounts/usbwallet/wallet.go | 7 +++++++ 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 78b63d3983..a599241bc3 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -35,6 +35,13 @@ type Account struct { URL URL `json:"url"` // Optional resource locator within a backend } +const ( + MimetypeTextWithValidator = "text/validator" + MimetypeTypedData = "data/typed" + MimetypeClique = "application/x-clique-header" + MimetypeTextPlain = "text/plain" +) + // Wallet represents a software or hardware wallet that might contain one or more // accounts (derived from the same seed). type Wallet interface { @@ -114,6 +121,12 @@ type Wallet interface { // the account in a keystore). SignData(account Account, mimeType string, data []byte) ([]byte, error) + // SignDataWithPassphrase is identical to SignData, but also takes a password + // NOTE: there's an chance that an erroneous call might mistake the two strings, and + // supply password in the mimetype field, or vice versa. Thus, an implementation + // should never echo the mimetype or return the mimetype in the error-response + SignDataWithPassphrase(account Account, passphrase, mimeType string, data []byte) ([]byte, error) + // SignText requests the wallet to sign the given hash. // // It looks up the account specified either solely via its address contained within, @@ -127,6 +140,9 @@ type Wallet interface { // the account in a keystore). SignText(account Account, text []byte) ([]byte, error) + // SignTextWithPassphrase is identical to Signtext, but also takes a password + SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) + // SignTx requests the wallet to sign the given transaction. // // It looks up the account specified either solely via its address contained within, @@ -140,18 +156,7 @@ type Wallet interface { // the account in a keystore). SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) - // SignTextWithPassphrase requests the wallet to sign the given hash with the - // given passphrase as extra authentication information. - // - // It looks up the account specified either solely via its address contained within, - // or optionally with the aid of any location metadata from the embedded URL field. - SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) - - // SignTxWithPassphrase requests the wallet to sign the given transaction, with the - // given passphrase as extra authentication information. - // - // It looks up the account specified either solely via its address contained within, - // or optionally with the aid of any location metadata from the embedded URL field. + // SignTxWithPassphrase is identical to SignTx, but also takes a password SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) } diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 602d640caa..6b44a66f4e 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -97,10 +97,31 @@ func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, dat return w.SignHash(account, crypto.Keccak256(data)) } +// SignDataWithPassphrase signs keccak256(data). The mimetype parameter describes the type of data being signed +func (w *keystoreWallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) +} + func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { return w.SignHash(account, accounts.TextHash(text)) } +// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the +// given hash with the given account using passphrase as extra authentication. +func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + // Make sure the requested account is contained within + if !w.Contains(account) { + return nil, accounts.ErrUnknownAccount + } + // Account seems valid, request the keystore to sign + return w.keystore.SignHashWithPassphrase(account, passphrase, accounts.TextHash(text)) +} + // SignTx implements accounts.Wallet, attempting to sign the given transaction // with the given account. If the wallet does not wrap this particular account, // an error is returned to avoid account leakage (even though in theory we may @@ -114,17 +135,6 @@ func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, return w.keystore.SignTx(account, tx, chainID) } -// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the -// given hash with the given account using passphrase as extra authentication. -func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignHashWithPassphrase(account, passphrase, accounts.TextHash(text)) -} - // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given // transaction with the given account using passphrase as extra authentication. func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 40dda2b410..1cbf7a75d7 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -507,6 +507,13 @@ func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte return w.SignHash(account, crypto.Keccak256(data)) } +// SignDataWithPassphrase implements accounts.Wallet, attempting to sign the given +// data with the given account using passphrase as extra authentication. +// Since USB wallets don't rely on passphrases, these are silently ignored. +func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + return w.SignData(account, mimeType, data) +} + func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { return w.SignHash(account, accounts.TextHash(text)) } From 99092ac54f78b923a89c1c446f739260aa3ce200 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 044/280] accounts/abi/bind/backends: add TransactionByHash to SimulatedBackend (#19026) --- accounts/abi/bind/backends/simulated.go | 34 +++++++--- accounts/abi/bind/backends/simulated_test.go | 70 +++++++++++++++++--- 2 files changed, 87 insertions(+), 17 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 15d7edc7e1..b78262d213 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -26,7 +26,7 @@ import ( "sync" "time" - "github.com/XinFinOrg/XDPoSChain" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/accounts" @@ -265,6 +265,24 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common return receipt, nil } +// TransactionByHash checks the pool of pending transactions in addition to the +// blockchain. The isPending return value indicates whether the transaction has been +// mined yet. Note that the transaction may not be part of the canonical chain even if +// it's not pending. +func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, isPending bool, err error) { + tx = b.pendingBlock.Transaction(txHash) + if tx != nil { + return tx, true, nil + } + + tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash) + if tx != nil { + return tx, false, nil + } + + return nil, false, ethereum.ErrNotFound +} + // HeaderByNumber returns a block header from the current canonical chain. If number is // nil, the latest known header is returned. func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) { @@ -287,7 +305,7 @@ func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Ad } // CallContract executes a contract call. -func (b *SimulatedBackend) CallContract(ctx context.Context, call XDPoSChain.CallMsg, blockNumber *big.Int) ([]byte, error) { +func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { b.mu.Lock() defer b.mu.Unlock() @@ -306,7 +324,7 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call XDPoSChain.Cal } // PendingCallContract executes a contract call on the pending state. -func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error) { +func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { b.mu.Lock() defer b.mu.Unlock() defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot()) @@ -344,7 +362,7 @@ func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, erro // EstimateGas executes the requested code against the currently pending block/state and // returns the used amount of gas. -func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.CallMsg) (uint64, error) { +func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) { b.mu.Lock() defer b.mu.Unlock() @@ -422,7 +440,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. -func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) { +func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) { // Gas prices post 1559 need to be initialized if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) { return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") @@ -523,7 +541,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa // returning all the results in one batch. // // TODO(karalabe): Deprecate when the subscription one can return past data too. -func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.FilterQuery) ([]types.Log, error) { +func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { var filter *filters.Filter if query.BlockHash != nil { // Block filter requested, construct a single-shot filter @@ -555,7 +573,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.Filt // SubscribeFilterLogs creates a background log filtering operation, returning a // subscription immediately, which can be used to stream the found events. -func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query XDPoSChain.FilterQuery, ch chan<- types.Log) (XDPoSChain.Subscription, error) { +func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { // Subscribe to contract events sink := make(chan []*types.Log) @@ -612,7 +630,7 @@ func (b *SimulatedBackend) GetBlockChain() *core.BlockChain { // callMsg implements core.Message to allow passing it as a transaction simulator. type callMsg struct { - XDPoSChain.CallMsg + ethereum.CallMsg } func (m callMsg) From() common.Address { return m.CallMsg.From } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 5681898523..8075552dc1 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -23,15 +23,67 @@ import ( "strings" "testing" - "github.com/XinFinOrg/XDPoSChain" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" ) +func TestSimulatedBackend(t *testing.T) { + var gasLimit uint64 = 8000029 + key, _ := crypto.GenerateKey() // nolint: gosec + auth := bind.NewKeyedTransactor(key) + genAlloc := make(core.GenesisAlloc) + genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} + + sim := NewSimulatedBackend(genAlloc, gasLimit) + + // should return an error if the tx is not found + txHash := common.HexToHash("2") + _, isPending, err := sim.TransactionByHash(context.Background(), txHash) + + if isPending { + t.Fatal("transaction should not be pending") + } + if err != ethereum.ErrNotFound { + t.Fatalf("err should be `ethereum.ErrNotFound` but received %v", err) + } + + // generate a transaction and confirm you can retrieve it + code := `6060604052600a8060106000396000f360606040526008565b00` + var gas uint64 = 3000000 + tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key) + + err = sim.SendTransaction(context.Background(), tx) + if err != nil { + t.Fatal("error sending transaction") + } + + txHash = tx.Hash() + _, isPending, err = sim.TransactionByHash(context.Background(), txHash) + if err != nil { + t.Fatalf("error getting transaction with hash: %v", txHash.String()) + } + if !isPending { + t.Fatal("transaction should have pending status") + } + + sim.Commit() + tx, isPending, err = sim.TransactionByHash(context.Background(), txHash) + if err != nil { + t.Fatalf("error getting transaction with hash: %v", txHash.String()) + } + if isPending { + t.Fatal("transaction should not have pending status") + } + +} + func TestSimulatedBackend_EstimateGas(t *testing.T) { /* pragma solidity ^0.6.4; @@ -69,11 +121,11 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { var cases = []struct { name string - message XDPoSChain.CallMsg + message ethereum.CallMsg expect uint64 expectError error }{ - {"plain transfer(valid)", XDPoSChain.CallMsg{ + {"plain transfer(valid)", ethereum.CallMsg{ From: addr, To: &addr, Gas: 0, @@ -82,7 +134,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: nil, }, params.TxGas, nil}, - {"plain transfer(invalid)", XDPoSChain.CallMsg{ + {"plain transfer(invalid)", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 0, @@ -91,7 +143,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: nil, }, 0, errors.New("always failing transaction (execution reverted)")}, - {"Revert", XDPoSChain.CallMsg{ + {"Revert", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 0, @@ -100,7 +152,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: common.Hex2Bytes("d8b98391"), }, 0, errors.New("always failing transaction (execution reverted) (revert reason)")}, - {"PureRevert", XDPoSChain.CallMsg{ + {"PureRevert", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 0, @@ -109,7 +161,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: common.Hex2Bytes("aa8b1d30"), }, 0, errors.New("always failing transaction (execution reverted)")}, - {"OOG", XDPoSChain.CallMsg{ + {"OOG", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 100000, @@ -118,7 +170,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: common.Hex2Bytes("50f6fe34"), }, 0, errors.New("gas required exceeds allowance (100000)")}, - {"Assert", XDPoSChain.CallMsg{ + {"Assert", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 100000, @@ -127,7 +179,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { Data: common.Hex2Bytes("b9b046f9"), }, 0, errors.New("always failing transaction (invalid opcode: INVALID)")}, - {"Valid", XDPoSChain.CallMsg{ + {"Valid", ethereum.CallMsg{ From: addr, To: &contractAddr, Gas: 100000, From 4b32073331e4c7ee245c0284d1548dcf941d9c83 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 045/280] accounts: fix typos (#19119) --- accounts/accounts.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index a599241bc3..94ba25d62a 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -117,7 +117,7 @@ type Wallet interface { // a password to decrypt the account, or a PIN code o verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing - // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock + // the needed details via SignDataWithPassphrase, or by other means (e.g. unlock // the account in a keystore). SignData(account Account, mimeType string, data []byte) ([]byte, error) @@ -127,13 +127,13 @@ type Wallet interface { // should never echo the mimetype or return the mimetype in the error-response SignDataWithPassphrase(account Account, passphrase, mimeType string, data []byte) ([]byte, error) - // SignText requests the wallet to sign the given hash. - // + // SignText requests the wallet to sign the hash of a given piece of data, prefixed + // by the Ethereum prefix scheme // It looks up the account specified either solely via its address contained within, // or optionally with the aid of any location metadata from the embedded URL field. // // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code to verify the transaction), + // a password to decrypt the account, or a PIN code o verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock From dcc3fc3ec33e355b8d33ac6a959e410222693482 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 046/280] accounts/abi: fix error message format (#19122) --- accounts/abi/abi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index defcca353a..fb7de7aa63 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -139,7 +139,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { // returns nil if none found func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { if len(sigdata) < 4 { - return nil, fmt.Errorf("data too short (% bytes) for abi method lookup", len(sigdata)) + return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata)) } for _, method := range abi.Methods { if bytes.Equal(method.Id(), sigdata[:4]) { From 5d0dea852ef56ec72bc968634622a4163a6458d1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 047/280] accounts/abi: mutex lock in TransactionByHash and code cleanup (#19133) --- accounts/abi/bind/backends/simulated.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index b78262d213..b129609e31 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -269,17 +269,18 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common // blockchain. The isPending return value indicates whether the transaction has been // mined yet. Note that the transaction may not be part of the canonical chain even if // it's not pending. -func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, isPending bool, err error) { - tx = b.pendingBlock.Transaction(txHash) +func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) { + b.mu.Lock() + defer b.mu.Unlock() + + tx := b.pendingBlock.Transaction(txHash) if tx != nil { return tx, true, nil } - tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash) if tx != nil { return tx, false, nil } - return nil, false, ethereum.ErrNotFound } From 4955476db45862abf984aaddb4166351891ffdf9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 048/280] accounts: prefer nil slices over zero-length slices (#19079) --- accounts/keystore/keystore.go | 6 ++++-- accounts/usbwallet/hub.go | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 617e8aa2fc..0f146a44d4 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -136,8 +136,10 @@ func (ks *KeyStore) refreshWallets() { accs := ks.cache.accounts() // Transform the current list of wallets into the new one - wallets := make([]accounts.Wallet, 0, len(accs)) - events := []accounts.WalletEvent{} + var ( + wallets = make([]accounts.Wallet, 0, len(accs)) + events []accounts.WalletEvent + ) for _, account := range accs { // Drop wallets while they were in front of the next account diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 2ec78d859d..9b3c5f89ab 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -150,8 +150,10 @@ func (hub *Hub) refreshWallets() { // Transform the current list of wallets into the new one hub.stateLock.Lock() - wallets := make([]accounts.Wallet, 0, len(devices)) - events := []accounts.WalletEvent{} + var ( + wallets = make([]accounts.Wallet, 0, len(devices)) + events []accounts.WalletEvent + ) for _, device := range devices { url := accounts.URL{Scheme: hub.scheme, Path: device.Path} From e7d8247fdacbefdfb2cd1a38381189389670398f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 049/280] usbwallet: check error returned by driver close (#18057) Although current two implementations(ledgerDriver, trezorDriver) of interface driver.Close do not actually return any error. Instead, they only return nil. But since the declaration of Close function returns error, it is better to check the returned error in case in future some new implementation of Close function returns error and we may forget to modify the function which invokes Close function at that time. --- accounts/usbwallet/wallet.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 1cbf7a75d7..99c5724fc7 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -274,9 +274,7 @@ func (w *wallet) close() error { w.device = nil w.accounts, w.paths = nil, nil - w.driver.Close() - - return nil + return w.driver.Close() } // Accounts implements accounts.Wallet, returning the list of accounts pinned to From e4d78ed594fa180581338de4d1b20aca339f2914 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 050/280] accounts/abi/bind: static byte arrays should be right-padded (#19269) --- accounts/abi/bind/bind_test.go | 41 +++++++++++- accounts/abi/bind/topics.go | 8 ++- accounts/abi/bind/topics_test.go | 103 +++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 accounts/abi/bind/topics_test.go diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 538dd3c38e..ed1d9f0c14 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -732,7 +732,7 @@ var bindTests = []struct { `Eventer`, ` contract Eventer { - event SimpleEvent ( + event SimpleEvent ( address indexed Addr, bytes32 indexed Id, bool indexed Flag, @@ -760,10 +760,18 @@ var bindTests = []struct { function raiseDynamicEvent(string str, bytes blob) { DynamicEvent(str, blob, str, blob); } + + event FixedBytesEvent ( + bytes24 indexed IndexedBytes, + bytes24 NonIndexedBytes + ); + function raiseFixedBytesEvent(bytes24 blob) { + FixedBytesEvent(blob, blob); + } } `, - []string{`6060604052341561000f57600080fd5b61042c8061001e6000396000f300606060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063528300ff1461005c578063630c31e2146100fc578063c7d116dd14610156575b600080fd5b341561006757600080fd5b6100fa600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091905050610194565b005b341561010757600080fd5b610154600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035600019169060200190919080351515906020019091908035906020019091905050610367565b005b341561016157600080fd5b610192600480803590602001909190803560010b90602001909190803563ffffffff169060200190919050506103c3565b005b806040518082805190602001908083835b6020831015156101ca57805182526020820191506020810190506020830392506101a5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020826040518082805190602001908083835b60208310151561022d5780518252602082019150602081019050602083039250610208565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561032757808201518184015260208101905061030c565b50505050905090810190601f1680156103545780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b81151583600019168573ffffffffffffffffffffffffffffffffffffffff167f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8846040518082815260200191505060405180910390a450505050565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820d1f8a8bbddbc5bb29f285891d6ae1eef8420c52afdc05e1573f6114d8e1714710029`}, - []string{`[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"}]`}, + []string{`608060405234801561001057600080fd5b5061043f806100206000396000f3006080604052600436106100615763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663528300ff8114610066578063630c31e2146100ff5780636cc6b94014610138578063c7d116dd1461015b575b600080fd5b34801561007257600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526100fd94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506101829650505050505050565b005b34801561010b57600080fd5b506100fd73ffffffffffffffffffffffffffffffffffffffff60043516602435604435151560643561033c565b34801561014457600080fd5b506100fd67ffffffffffffffff1960043516610394565b34801561016757600080fd5b506100fd60043560243560010b63ffffffff604435166103d6565b806040518082805190602001908083835b602083106101b25780518252601f199092019160209182019101610193565b51815160209384036101000a6000190180199092169116179052604051919093018190038120875190955087945090928392508401908083835b6020831061020b5780518252601f1990920191602091820191016101ec565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390207f3281fd4f5e152dd3385df49104a3f633706e21c9e80672e88d3bcddf33101f008484604051808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561029c578181015183820152602001610284565b50505050905090810190601f1680156102c95780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156102fc5781810151838201526020016102e4565b50505050905090810190601f1680156103295780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a35050565b60408051828152905183151591859173ffffffffffffffffffffffffffffffffffffffff8816917f1f097de4289df643bd9c11011cc61367aa12983405c021056e706eb5ba1250c8919081900360200190a450505050565b6040805167ffffffffffffffff19831680825291517fcdc4c1b1aed5524ffb4198d7a5839a34712baef5fa06884fac7559f4a5854e0a9181900360200190a250565b8063ffffffff168260010b847f3ca7f3a77e5e6e15e781850bc82e32adfa378a2a609370db24b4d0fae10da2c960405160405180910390a45050505600a165627a7a72305820468b5843bf653145bd924b323c64ef035d3dd922c170644b44d61aa666ea6eee0029`}, + []string{`[{"constant":false,"inputs":[{"name":"str","type":"string"},{"name":"blob","type":"bytes"}],"name":"raiseDynamicEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"id","type":"bytes32"},{"name":"flag","type":"bool"},{"name":"value","type":"uint256"}],"name":"raiseSimpleEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"blob","type":"bytes24"}],"name":"raiseFixedBytesEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"number","type":"uint256"},{"name":"short","type":"int16"},{"name":"long","type":"uint32"}],"name":"raiseNodataEvent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Addr","type":"address"},{"indexed":true,"name":"Id","type":"bytes32"},{"indexed":true,"name":"Flag","type":"bool"},{"indexed":false,"name":"Value","type":"uint256"}],"name":"SimpleEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"Number","type":"uint256"},{"indexed":true,"name":"Short","type":"int16"},{"indexed":true,"name":"Long","type":"uint32"}],"name":"NodataEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedString","type":"string"},{"indexed":true,"name":"IndexedBytes","type":"bytes"},{"indexed":false,"name":"NonIndexedString","type":"string"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes"}],"name":"DynamicEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"IndexedBytes","type":"bytes24"},{"indexed":false,"name":"NonIndexedBytes","type":"bytes24"}],"name":"FixedBytesEvent","type":"event"}]`}, ` "math/big" "time" @@ -875,6 +883,33 @@ var bindTests = []struct { if err = dit.Error(); err != nil { t.Fatalf("dynamic event iteration failed: %v", err) } + // Test raising and filtering for events with fixed bytes components + var fblob [24]byte + copy(fblob[:], []byte("Fixed Bytes")) + + if _, err := eventer.RaiseFixedBytesEvent(auth, fblob); err != nil { + t.Fatalf("failed to raise fixed bytes event: %v", err) + } + sim.Commit() + + fit, err := eventer.FilterFixedBytesEvent(nil, [][24]byte{fblob}) + if err != nil { + t.Fatalf("failed to filter for fixed bytes events: %v", err) + } + defer fit.Close() + + if !fit.Next() { + t.Fatalf("fixed bytes log not found: %v", fit.Error()) + } + if fit.Event.NonIndexedBytes != fblob || fit.Event.IndexedBytes != fblob { + t.Errorf("fixed bytes log content mismatch: have %v, want {'%x', '%x'}", fit.Event, fblob, fblob) + } + if fit.Next() { + t.Errorf("unexpected fixed bytes event found: %+v", fit.Event) + } + if err = fit.Error(); err != nil { + t.Fatalf("fixed bytes event iteration failed: %v", err) + } // Test subscribing to an event and raising it afterwards ch := make(chan *EventerSimpleEvent, 16) sub, err := eventer.WatchSimpleEvent(nil, ch, nil, nil, nil) diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index ca3ffb1e44..6c8f2ba4b4 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 0000000000..2bc1329482 --- /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 . + +package bind + +import ( + "reflect" + "testing" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/common" +) + +func TestMakeTopics(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 TestParseTopics(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) + } + }) + } +} From 36577396ec48028404df7ea3a59f31fdeba264e7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 051/280] accounts/abi: add the original name as json-structtag for tuples (#19340) --- accounts/abi/type.go | 1 + accounts/abi/type_test.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 325cd724e4..90ebb75ab2 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -187,6 +187,7 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { fields = append(fields, reflect.StructField{ Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field. Type: cType.Type, + Tag: reflect.StructTag("json:\"" + c.Name + "\""), }) elems = append(elems, &cType) names = append(names, c.Name) diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index fdedad0f66..2f663d51d7 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -95,8 +95,14 @@ func TestTypeRegexp(t *testing.T) { // {"fixed[2]", nil, Type{}}, // {"fixed128x128[]", nil, Type{}}, // {"fixed128x128[2]", nil, Type{}}, - {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct{ A int64 }{}), stringKind: "(int64)", + {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct { + A int64 `json:"a"` + }{}), stringKind: "(int64)", TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, + {"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct { + ATypicalParamName int64 `json:"aTypicalParamName"` + }{}), stringKind: "(int64)", + TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, } for _, tt := range tests { From 769a34bfb7c48da1a07bde857f81696069127626 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 052/280] accounts/abi: generic unpacking of event logs into map[string]interface{} (#18440) Add methods that allow for the unpacking of event logs into maps (allows for agnostic unpacking of logs) --- accounts/abi/abi.go | 34 +++- accounts/abi/abi_test.go | 186 ++++++++++++++++++++ accounts/abi/argument.go | 23 +++ accounts/abi/bind/base.go | 16 ++ accounts/abi/bind/base_test.go | 302 ++++++++++++++++++++++++++++++++- accounts/abi/bind/topics.go | 48 ++++++ accounts/abi/unpack.go | 2 +- 7 files changed, 599 insertions(+), 12 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index fb7de7aa63..537f6c0f59 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -75,19 +75,39 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { } // Unpack output in v according to the abi specification -func (abi ABI) Unpack(v interface{}, name string, output []byte) (err error) { - if len(output) == 0 { +func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { + if len(data) == 0 { return errors.New("abi: unmarshalling empty output") } // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event if method, ok := abi.Methods[name]; ok { - if len(output)%32 != 0 { - return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(output), output) + if len(data)%32 != 0 { + return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data) } - return method.Outputs.Unpack(v, output) - } else if event, ok := abi.Events[name]; ok { - return event.Inputs.Unpack(v, output) + return method.Outputs.Unpack(v, data) + } + if event, ok := abi.Events[name]; ok { + return event.Inputs.Unpack(v, data) + } + return fmt.Errorf("abi: could not locate named method or event") +} + +// UnpackIntoMap unpacks a log into the provided map[string]interface{} +func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) { + if len(data) == 0 { + return fmt.Errorf("abi: unmarshalling empty output") + } + // since there can't be naming collisions with contracts and events, + // we need to decide whether we're calling a method or an event + if method, ok := abi.Methods[name]; ok { + if len(data)%32 != 0 { + return fmt.Errorf("abi: improperly formatted output") + } + return method.Outputs.UnpackIntoMap(v, data) + } + if event, ok := abi.Events[name]; ok { + return event.Inputs.UnpackIntoMap(v, data) } return errors.New("abi: could not locate named method or event") } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index edb97e6850..bb7e61ae24 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -700,6 +700,192 @@ func TestUnpackEvent(t *testing.T) { } } +func TestUnpackEventIntoMap(t *testing.T) { + const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` + abi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + + const hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158` + data, err := hex.DecodeString(hexdata) + if err != nil { + t.Fatal(err) + } + if len(data)%32 == 0 { + t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) + } + + receivedMap := map[string]interface{}{} + expectedReceivedMap := map[string]interface{}{ + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := abi.UnpackIntoMap(receivedMap, "received", data); err != nil { + t.Error(err) + } + if len(receivedMap) != 3 { + t.Error("unpacked `received` map expected to have length 3") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked `received` map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked `received` map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked `received` map does not match expected map") + } + + receivedAddrMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(receivedAddrMap, "receivedAddr", data); err != nil { + t.Error(err) + } + if len(receivedAddrMap) != 1 { + t.Error("unpacked `receivedAddr` map expected to have length 1") + } + if receivedAddrMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked `receivedAddr` map does not match expected map") + } +} + +func TestUnpackMethodIntoMap(t *testing.T) { + const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]` + abi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + const hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001580000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000015800000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000158` + data, err := hex.DecodeString(hexdata) + if err != nil { + t.Fatal(err) + } + if len(data)%32 != 0 { + t.Errorf("len(data) is %d, want a multiple of 32", len(data)) + } + + // Tests a method with no outputs + receiveMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(receiveMap, "receive", data); err != nil { + t.Error(err) + } + if len(receiveMap) > 0 { + t.Error("unpacked `receive` map expected to have length 0") + } + + // Tests a method with only outputs + sendMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(sendMap, "send", data); err != nil { + t.Error(err) + } + if len(sendMap) != 1 { + t.Error("unpacked `send` map expected to have length 1") + } + if sendMap["amount"].(*big.Int).Cmp(big.NewInt(1)) != 0 { + t.Error("unpacked `send` map expected `amount` value of 1") + } + + // Tests a method with outputs and inputs + getMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(getMap, "get", data); err != nil { + t.Error(err) + } + if len(sendMap) != 1 { + t.Error("unpacked `get` map expected to have length 1") + } + expectedBytes := []byte{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, 96, 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, 88, 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, 96, 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, 88, 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, 96, 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, 88, 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, 96, 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, 88, 0} + if !bytes.Equal(getMap["hash"].([]byte), expectedBytes) { + t.Errorf("unpacked `get` map expected `hash` value of %v", expectedBytes) + } +} + +func TestUnpackIntoMapNamingConflict(t *testing.T) { + // Two methods have the same name + var abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"get","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]` + abi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + var hexdata = `00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158` + data, err := hex.DecodeString(hexdata) + if err != nil { + t.Fatal(err) + } + if len(data)%32 == 0 { + t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) + } + getMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(getMap, "get", data); err == nil { + t.Error("naming conflict between two methods; error expected") + } + + // Two events have the same name + abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"received","type":"event"}]` + abi, err = JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + hexdata = `000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158` + data, err = hex.DecodeString(hexdata) + if err != nil { + t.Fatal(err) + } + if len(data)%32 == 0 { + t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) + } + receivedMap := map[string]interface{}{} + if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil { + t.Error("naming conflict between two events; no error expected") + } + if len(receivedMap) != 1 { + t.Error("naming conflict between two events; event defined latest in the abi expected to be used") + } + + // Method and event have the same name + abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` + abi, err = JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + if len(data)%32 == 0 { + t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) + } + if err = abi.UnpackIntoMap(receivedMap, "received", data); err == nil { + t.Error("naming conflict between an event and a method; error expected") + } + + // Conflict is case sensitive + abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` + abi, err = JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + if len(data)%32 == 0 { + t.Errorf("len(data) is %d, want a non-multiple of 32", len(data)) + } + expectedReceivedMap := map[string]interface{}{ + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err = abi.UnpackIntoMap(receivedMap, "Received", data); err != nil { + t.Error(err) + } + if len(receivedMap) != 3 { + t.Error("unpacked `received` map expected to have length 3") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked `received` map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked `received` map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked `received` map does not match expected map") + } +} + func TestABI_MethodById(t *testing.T) { const abiJSON = `[ {"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"}, diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 99218904eb..ff1265a8cb 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -114,6 +114,16 @@ func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { return arguments.UnpackValues(data) } +// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value +func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { + marshalledValues, err := arguments.UnpackValues(data) + if err != nil { + return err + } + + return arguments.unpackIntoMap(v, marshalledValues) +} + // unpack sets the unmarshalled value to go format. // Note the dst here must be settable. func unpack(t *Type, dst interface{}, src interface{}) error { @@ -172,6 +182,19 @@ func unpack(t *Type, dst interface{}, src interface{}) error { return nil } +// unpackIntoMap unpacks marshalledValues into the provided map[string]interface{} +func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error { + // Make sure map is not nil + if v == nil { + return fmt.Errorf("abi: cannot unpack into a nil map") + } + + for i, arg := range arguments.NonIndexed() { + v[arg.Name] = marshalledValues[i] + } + return nil +} + // unpackAtomic unpacks ( hexdata -> go ) a single value func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { if arguments.LengthNonIndexed() == 0 { diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 1364000f85..79c4fd5581 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -456,6 +456,22 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) return parseTopics(out, indexed, log.Topics[1:]) } +// UnpackLogIntoMap unpacks a retrieved log into the provided map. +func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error { + if len(log.Data) > 0 { + if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil { + return err + } + } + var indexed abi.Arguments + for _, arg := range c.abi.Events[event].Inputs { + if arg.Indexed { + indexed = append(indexed, arg) + } + } + return parseTopicsIntoMap(out, indexed, log.Topics[1:]) +} + // ensureContext is a helper method to ensure a context is not nil, even if the // user specified it as such. func ensureContext(ctx context.Context) context.Context { diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 037f1d24e8..6fbbcdf727 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -17,15 +17,20 @@ package bind_test import ( + "bytes" "context" "math/big" + "strings" "testing" - "github.com/XinFinOrg/XDPoSChain" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/stretchr/testify/assert" ) @@ -61,7 +66,7 @@ func (mt *mockTransactor) SuggestGasTipCap(ctx context.Context) (*big.Int, error return mt.gasTipCap, nil } -func (mt *mockTransactor) EstimateGas(ctx context.Context, call XDPoSChain.CallMsg) (gas uint64, err error) { +func (mt *mockTransactor) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) { return 0, nil } @@ -81,7 +86,7 @@ func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, block return []byte{1, 2, 3}, nil } -func (mc *mockCaller) CallContract(ctx context.Context, call XDPoSChain.CallMsg, blockNumber *big.Int) ([]byte, error) { +func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { mc.callContractBlockNumber = blockNumber return nil, nil } @@ -91,10 +96,11 @@ func (mc *mockCaller) PendingCodeAt(ctx context.Context, contract common.Address return nil, nil } -func (mc *mockCaller) PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error) { +func (mc *mockCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { mc.pendingCallContractCalled = true return nil, nil } + func TestPassingBlockNumber(t *testing.T) { mc := &mockCaller{} @@ -175,3 +181,291 @@ func TestTransactGasFee(t *testing.T) { assert.Equal(big.NewInt(6), tx.GasPrice()) assert.True(mt.suggestGasPriceCalled) } + +const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158" + +func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { + hash := crypto.Keccak256Hash([]byte("testName")) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x0"), + hash, + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x0"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "name": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["name"] != expectedReceivedMap["name"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked map does not match expected map") + } +} + +func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { + sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) + if err != nil { + t.Fatal(err) + } + hash := crypto.Keccak256Hash(sliceBytes) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x0"), + hash, + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x0"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "names": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["names"] != expectedReceivedMap["names"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked map does not match expected map") + } +} + +func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { + arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")}) + if err != nil { + t.Fatal(err) + } + hash := crypto.Keccak256Hash(arrBytes) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x0"), + hash, + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x0"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "addresses": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["addresses"] != expectedReceivedMap["addresses"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked map does not match expected map") + } +} + +func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { + mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2") + addrBytes := mockAddress.Bytes() + hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)")) + functionSelector := hash[:4] + functionTyBytes := append(addrBytes, functionSelector...) + var functionTy [24]byte + copy(functionTy[:], functionTyBytes[0:24]) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + common.BytesToHash(functionTyBytes), + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "function": functionTy, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["function"] != expectedReceivedMap["function"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked map does not match expected map") + } +} + +func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { + byts := []byte{1, 2, 3, 4, 5} + hash := crypto.Keccak256Hash(byts) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + hash, + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + receivedMap := make(map[string]interface{}) + expectedReceivedMap := map[string]interface{}{ + "content": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + t.Error(err) + } + + if len(receivedMap) != 4 { + t.Fatal("unpacked map expected to have length 4") + } + if receivedMap["content"] != expectedReceivedMap["content"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["sender"] != expectedReceivedMap["sender"] { + t.Error("unpacked map does not match expected map") + } + if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { + t.Error("unpacked map does not match expected map") + } + if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { + t.Error("unpacked map does not match expected map") + } +} + +func TestUnpackIntoMapNamingConflict(t *testing.T) { + hash := crypto.Keccak256Hash([]byte("testName")) + mockLog := types.Log{ + Address: common.HexToAddress("0x0"), + Topics: []common.Hash{ + common.HexToHash("0x0"), + hash, + }, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: common.HexToHash("0x0"), + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, + } + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + receivedMap := make(map[string]interface{}) + if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err == nil { + t.Error("naming conflict between two events; error expected") + } +} diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index 6c8f2ba4b4..17265c9e14 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -17,6 +17,7 @@ package bind import ( + "encoding/binary" "errors" "fmt" "math/big" @@ -191,3 +192,50 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er } return nil } + +// parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs +func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error { + // Sanity check that the fields and topics match up + if len(fields) != len(topics) { + return errors.New("topic/field count mismatch") + } + // Iterate over all the fields and reconstruct them from topics + for _, arg := range fields { + if !arg.Indexed { + return errors.New("non-indexed field in topic reconstruction") + } + + switch arg.Type.T { + case abi.BoolTy: + out[arg.Name] = topics[0][common.HashLength-1] == 1 + case abi.IntTy, abi.UintTy: + num := new(big.Int).SetBytes(topics[0][:]) + out[arg.Name] = num + case abi.AddressTy: + var addr common.Address + copy(addr[:], topics[0][common.HashLength-common.AddressLength:]) + out[arg.Name] = addr + case abi.HashTy: + out[arg.Name] = topics[0] + case abi.FixedBytesTy: + out[arg.Name] = topics[0][:] + case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy: + // Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash + // whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash + out[arg.Name] = topics[0] + case abi.FunctionTy: + if garbage := binary.BigEndian.Uint64(topics[0][0:8]); garbage != 0 { + return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[0].Bytes()) + } + var tmp [24]byte + copy(tmp[:], topics[0][8:32]) + out[arg.Name] = tmp + default: // Not handling tuples + return fmt.Errorf("unsupported indexed type: %v", arg.Type) + } + + topics = topics[1:] + } + + return nil +} diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index a1c3c804b1..5a60a03ff4 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -270,7 +270,7 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err totalSize.Add(totalSize, bigOffsetEnd) totalSize.Add(totalSize, lengthBig) if totalSize.BitLen() > 63 { - return 0, 0, fmt.Errorf("abi length larger than int64: %v", totalSize) + return 0, 0, fmt.Errorf("abi: length larger than int64: %v", totalSize) } if totalSize.Cmp(outputLength) > 0 { From 1f9778bb9fb4f67c3523832c5cb0f3ceda94e27a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 053/280] accounts: disable unlock account on open HTTP (#17037) --- accounts/manager.go | 17 ++++++++++++++++- node/config.go | 5 ++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/accounts/manager.go b/accounts/manager.go index bf4fb9180a..200260cabc 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -24,9 +24,18 @@ import ( "github.com/XinFinOrg/XDPoSChain/event" ) +// Config contains the settings of the global account manager. +// +// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management +// is removed in favor of Clef. +type Config struct { + InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed +} + // Manager is an overarching account manager that can communicate with various // backends for signing transactions. type Manager struct { + config *Config // Global account manager configurations backends map[reflect.Type][]Backend // Index of backends currently registered updaters []event.Subscription // Wallet update subscriptions for all backends updates chan WalletEvent // Subscription sink for backend wallet changes @@ -40,7 +49,7 @@ type Manager struct { // NewManager creates a generic account manager to sign transaction via various // supported backends. -func NewManager(backends ...Backend) *Manager { +func NewManager(config *Config, backends ...Backend) *Manager { // Retrieve the initial list of wallets from the backends and sort by URL var wallets []Wallet for _, backend := range backends { @@ -55,6 +64,7 @@ func NewManager(backends ...Backend) *Manager { } // Assemble the account manager and return am := &Manager{ + config: config, backends: make(map[reflect.Type][]Backend), updaters: subs, updates: updates, @@ -77,6 +87,11 @@ func (am *Manager) Close() error { return <-errc } +// Config returns the configuration of account manager. +func (am *Manager) Config() *Config { + return am.config +} + // update is the wallet event loop listening for notifications from the backends // and updating the cache of wallets. func (am *Manager) update() { diff --git a/node/config.go b/node/config.go index 355f316a19..5e11ab7ce6 100644 --- a/node/config.go +++ b/node/config.go @@ -82,6 +82,9 @@ type Config struct { // scrypt KDF at the expense of security. UseLightweightKDF bool `toml:",omitempty"` + // InsecureUnlockAllowed allows user to unlock accounts in unsafe http environment. + InsecureUnlockAllowed bool `toml:",omitempty"` + // NoUSB disables hardware wallet monitoring and connectivity. NoUSB bool `toml:",omitempty"` @@ -439,5 +442,5 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { backends = append(backends, trezorhub) } } - return accounts.NewManager(backends...), ephemeral, nil + return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil } From 2999bea17f73a0c003518bc1cffb5c7fd8895aa9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 054/280] accounts: smartcard wallet without the dependency on libpcsclite (#19273) --- accounts/hd.go | 19 +- accounts/scwallet/README.md | 69 ++ accounts/scwallet/apdu.go | 87 +++ accounts/scwallet/hub.go | 302 ++++++++ accounts/scwallet/securechannel.go | 346 +++++++++ accounts/scwallet/wallet.go | 1074 ++++++++++++++++++++++++++++ accounts/sort.go | 31 + go.mod | 5 +- go.sum | 6 + 9 files changed, 1937 insertions(+), 2 deletions(-) create mode 100644 accounts/scwallet/README.md create mode 100644 accounts/scwallet/apdu.go create mode 100644 accounts/scwallet/hub.go create mode 100644 accounts/scwallet/securechannel.go create mode 100644 accounts/scwallet/wallet.go create mode 100644 accounts/sort.go diff --git a/accounts/hd.go b/accounts/hd.go index 6ed6318078..bddd8796c1 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -17,6 +17,7 @@ package accounts import ( + "encoding/json" "errors" "fmt" "math" @@ -45,7 +46,7 @@ var DefaultLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 // The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki // defines derivation paths to be of the form: // -// m / purpose' / coin_type' / account' / change / address_index +// m / purpose' / coin_type' / account' / change / address_index // // The BIP-44 spec https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki // defines that the `purpose` be 44' (or 0x8000002C) for crypto currencies, and @@ -133,3 +134,19 @@ func (path DerivationPath) String() string { } return result } + +// MarshalJSON turns a derivation path into its json-serialized string +func (path DerivationPath) MarshalJSON() ([]byte, error) { + return json.Marshal(path.String()) +} + +// UnmarshalJSON a json-serialized string back into a derivation path +func (path *DerivationPath) UnmarshalJSON(b []byte) error { + var dp string + var err error + if err = json.Unmarshal(b, &dp); err != nil { + return err + } + *path, err = ParseDerivationPath(dp) + return err +} diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md new file mode 100644 index 0000000000..740c2b28c1 --- /dev/null +++ b/accounts/scwallet/README.md @@ -0,0 +1,69 @@ +# Using the smartcard wallet + +## Requirements + + * A USB smartcard reader + * A keycard that supports the status app + * PCSCD version 4.3 running on your system **Only version 4.3 is currently supported** + +## Preparing the smartcard + + **WARNING: FOILLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** + + You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.1.1/keycard_v2.1.1.cap) + + You also need to make sure that the PCSC daemon is running on your system. + + Then, you can install the application to the card by typing: + + ``` + keycard install -a keycard_v2.1.cap + ``` + + Then you can initialize the application by typing: + + ``` + keycard init + ``` + + Then the card needs to be paired: + + ``` + keycard pair + ``` + + Finally, you need to have the card generate a new master key: + + ``` + keycard shell <. + +package scwallet + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +// commandAPDU represents an application data unit sent to a smartcard. +type commandAPDU struct { + Cla, Ins, P1, P2 uint8 // Class, Instruction, Parameter 1, Parameter 2 + Data []byte // Command data + Le uint8 // Command data length +} + +// serialize serializes a command APDU. +func (ca commandAPDU) serialize() ([]byte, error) { + buf := new(bytes.Buffer) + + if err := binary.Write(buf, binary.BigEndian, ca.Cla); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.Ins); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.P1); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.P2); err != nil { + return nil, err + } + if len(ca.Data) > 0 { + if err := binary.Write(buf, binary.BigEndian, uint8(len(ca.Data))); err != nil { + return nil, err + } + if err := binary.Write(buf, binary.BigEndian, ca.Data); err != nil { + return nil, err + } + } + if err := binary.Write(buf, binary.BigEndian, ca.Le); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// responseAPDU represents an application data unit received from a smart card. +type responseAPDU struct { + Data []byte // response data + Sw1, Sw2 uint8 // status words 1 and 2 +} + +// deserialize deserializes a response APDU. +func (ra *responseAPDU) deserialize(data []byte) error { + if len(data) < 2 { + return fmt.Errorf("can not deserialize data: payload too short (%d < 2)", len(data)) + } + + ra.Data = make([]byte, len(data)-2) + + buf := bytes.NewReader(data) + if err := binary.Read(buf, binary.BigEndian, &ra.Data); err != nil { + return err + } + if err := binary.Read(buf, binary.BigEndian, &ra.Sw1); err != nil { + return err + } + if err := binary.Read(buf, binary.BigEndian, &ra.Sw2); err != nil { + return err + } + return nil +} diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go new file mode 100644 index 0000000000..3e07533067 --- /dev/null +++ b/accounts/scwallet/hub.go @@ -0,0 +1,302 @@ +// 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 . + +// This package implements support for smartcard-based hardware wallets such as +// the one written by Status: https://github.com/status-im/hardware-wallet +// +// This implementation of smartcard wallets have a different interaction process +// to other types of hardware wallet. The process works like this: +// +// 1. (First use with a given client) Establish a pairing between hardware +// wallet and client. This requires a secret value called a 'pairing password'. +// You can pair with an unpaired wallet with `personal.openWallet(URI, pairing password)`. +// 2. (First use only) Initialize the wallet, which generates a keypair, stores +// it on the wallet, and returns it so the user can back it up. You can +// initialize a wallet with `personal.initializeWallet(URI)`. +// 3. Connect to the wallet using the pairing information established in step 1. +// You can connect to a paired wallet with `personal.openWallet(URI, PIN)`. +// 4. Interact with the wallet as normal. + +package scwallet + +import ( + "encoding/json" + "io" + "os" + "path/filepath" + "sort" + "sync" + "time" + + "github.com/XinFinOrg/XDPoSChain/accounts" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/event" + "github.com/XinFinOrg/XDPoSChain/log" + pcsc "github.com/gballet/go-libpcsclite" +) + +// Scheme is the URI prefix for smartcard wallets. +const Scheme = "pcsc" + +// refreshCycle is the maximum time between wallet refreshes (if USB hotplug +// notifications don't work). +const refreshCycle = time.Second + +// refreshThrottling is the minimum time between wallet refreshes to avoid thrashing. +const refreshThrottling = 500 * time.Millisecond + +// smartcardPairing contains information about a smart card we have paired with +// or might pair with the hub. +type smartcardPairing struct { + PublicKey []byte `json:"publicKey"` + PairingIndex uint8 `json:"pairingIndex"` + PairingKey []byte `json:"pairingKey"` + Accounts map[common.Address]accounts.DerivationPath `json:"accounts"` +} + +// Hub is a accounts.Backend that can find and handle generic PC/SC hardware wallets. +type Hub struct { + scheme string // Protocol scheme prefixing account and wallet URLs. + + context *pcsc.Client + datadir string + pairings map[string]smartcardPairing + + refreshed time.Time // Time instance when the list of wallets was last refreshed + wallets map[string]*Wallet // Mapping from reader names to wallet instances + updateFeed event.Feed // Event feed to notify wallet additions/removals + updateScope event.SubscriptionScope // Subscription scope tracking current live listeners + updating bool // Whether the event notification loop is running + + quit chan chan error + + stateLock sync.RWMutex // Protects the internals of the hub from racey access +} + +func (hub *Hub) readPairings() error { + hub.pairings = make(map[string]smartcardPairing) + pairingFile, err := os.Open(filepath.Join(hub.datadir, "smartcards.json")) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + pairingData, err := io.ReadAll(pairingFile) + if err != nil { + return err + } + var pairings []smartcardPairing + if err := json.Unmarshal(pairingData, &pairings); err != nil { + return err + } + + for _, pairing := range pairings { + hub.pairings[string(pairing.PublicKey)] = pairing + } + return nil +} + +func (hub *Hub) writePairings() error { + pairingFile, err := os.OpenFile(filepath.Join(hub.datadir, "smartcards.json"), os.O_RDWR|os.O_CREATE, 0755) + if err != nil { + return err + } + defer pairingFile.Close() + + pairings := make([]smartcardPairing, 0, len(hub.pairings)) + for _, pairing := range hub.pairings { + pairings = append(pairings, pairing) + } + + pairingData, err := json.Marshal(pairings) + if err != nil { + return err + } + + if _, err := pairingFile.Write(pairingData); err != nil { + return err + } + + return nil +} + +func (hub *Hub) pairing(wallet *Wallet) *smartcardPairing { + if pairing, ok := hub.pairings[string(wallet.PublicKey)]; ok { + return &pairing + } + return nil +} + +func (hub *Hub) setPairing(wallet *Wallet, pairing *smartcardPairing) error { + if pairing == nil { + delete(hub.pairings, string(wallet.PublicKey)) + } else { + hub.pairings[string(wallet.PublicKey)] = *pairing + } + return hub.writePairings() +} + +// NewHub creates a new hardware wallet manager for smartcards. +func NewHub(daemonPath string, scheme string, datadir string) (*Hub, error) { + context, err := pcsc.EstablishContext(daemonPath, pcsc.ScopeSystem) + if err != nil { + return nil, err + } + hub := &Hub{ + scheme: scheme, + context: context, + datadir: datadir, + wallets: make(map[string]*Wallet), + quit: make(chan chan error), + } + if err := hub.readPairings(); err != nil { + return nil, err + } + hub.refreshWallets() + return hub, nil +} + +// Wallets implements accounts.Backend, returning all the currently tracked smart +// cards that appear to be hardware wallets. +func (hub *Hub) Wallets() []accounts.Wallet { + // Make sure the list of wallets is up to date + hub.refreshWallets() + + hub.stateLock.RLock() + defer hub.stateLock.RUnlock() + + cpy := make([]accounts.Wallet, 0, len(hub.wallets)) + for _, wallet := range hub.wallets { + cpy = append(cpy, wallet) + } + sort.Sort(accounts.WalletsByURL(cpy)) + return cpy +} + +// refreshWallets scans the devices attached to the machine and updates the +// list of wallets based on the found devices. +func (hub *Hub) refreshWallets() { + // Don't scan the USB like crazy it the user fetches wallets in a loop + hub.stateLock.RLock() + elapsed := time.Since(hub.refreshed) + hub.stateLock.RUnlock() + + if elapsed < refreshThrottling { + return + } + // Retrieve all the smart card reader to check for cards + readers, err := hub.context.ListReaders() + if err != nil { + // This is a perverted hack, the scard library returns an error if no card + // readers are present instead of simply returning an empty list. We don't + // want to fill the user's log with errors, so filter those out. + if err.Error() != "scard: Cannot find a smart card reader." { + log.Error("Failed to enumerate smart card readers", "err", err) + return + } + } + // Transform the current list of wallets into the new one + hub.stateLock.Lock() + + events := []accounts.WalletEvent{} + seen := make(map[string]struct{}) + + for _, reader := range readers { + // Mark the reader as present + seen[reader] = struct{}{} + + // If we alreay know about this card, skip to the next reader, otherwise clean up + if wallet, ok := hub.wallets[reader]; ok { + if err := wallet.ping(); err == nil { + continue + } + wallet.Close() + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) + delete(hub.wallets, reader) + } + // New card detected, try to connect to it + card, err := hub.context.Connect(reader, pcsc.ShareShared, pcsc.ProtocolAny) + if err != nil { + log.Debug("Failed to open smart card", "reader", reader, "err", err) + continue + } + wallet := NewWallet(hub, card) + if err = wallet.connect(); err != nil { + log.Debug("Failed to connect to smart card", "reader", reader, "err", err) + card.Disconnect(pcsc.LeaveCard) + continue + } + // Card connected, start tracking in amongs the wallets + hub.wallets[reader] = wallet + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) + } + // Remove any wallets no longer present + for reader, wallet := range hub.wallets { + if _, ok := seen[reader]; !ok { + wallet.Close() + events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) + delete(hub.wallets, reader) + } + } + hub.refreshed = time.Now() + hub.stateLock.Unlock() + + for _, event := range events { + hub.updateFeed.Send(event) + } +} + +// Subscribe implements accounts.Backend, creating an async subscription to +// receive notifications on the addition or removal of smart card wallets. +func (hub *Hub) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { + // We need the mutex to reliably start/stop the update loop + hub.stateLock.Lock() + defer hub.stateLock.Unlock() + + // Subscribe the caller and track the subscriber count + sub := hub.updateScope.Track(hub.updateFeed.Subscribe(sink)) + + // Subscribers require an active notification loop, start it + if !hub.updating { + hub.updating = true + go hub.updater() + } + return sub +} + +// updater is responsible for maintaining an up-to-date list of wallets managed +// by the smart card hub, and for firing wallet addition/removal events. +func (hub *Hub) updater() { + for { + // TODO: Wait for a USB hotplug event (not supported yet) or a refresh timeout + // <-hub.changes + time.Sleep(refreshCycle) + + // Run the wallet refresher + hub.refreshWallets() + + // If all our subscribers left, stop the updater + hub.stateLock.Lock() + if hub.updateScope.Count() == 0 { + hub.updating = false + hub.stateLock.Unlock() + return + } + hub.stateLock.Unlock() + } +} diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go new file mode 100644 index 0000000000..c108689166 --- /dev/null +++ b/accounts/scwallet/securechannel.go @@ -0,0 +1,346 @@ +// 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 . + +package scwallet + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "crypto/sha512" + "fmt" + + "github.com/XinFinOrg/XDPoSChain/crypto" + pcsc "github.com/gballet/go-libpcsclite" + "github.com/wsddn/go-ecdh" + "golang.org/x/crypto/pbkdf2" + "golang.org/x/text/unicode/norm" +) + +const ( + maxPayloadSize = 223 + pairP1FirstStep = 0 + pairP1LastStep = 1 + + scSecretLength = 32 + scBlockSize = 16 + + insOpenSecureChannel = 0x10 + insMutuallyAuthenticate = 0x11 + insPair = 0x12 + insUnpair = 0x13 + + pairingSalt = "Keycard Pairing Password Salt" +) + +// SecureChannelSession enables secure communication with a hardware wallet. +type SecureChannelSession struct { + card *pcsc.Card // A handle to the smartcard for communication + secret []byte // A shared secret generated from our ECDSA keys + publicKey []byte // Our own ephemeral public key + PairingKey []byte // A permanent shared secret for a pairing, if present + sessionEncKey []byte // The current session encryption key + sessionMacKey []byte // The current session MAC key + iv []byte // The current IV + PairingIndex uint8 // The pairing index +} + +// NewSecureChannelSession creates a new secure channel for the given card and public key. +func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSession, error) { + // Generate an ECDSA keypair for ourselves + gen := ecdh.NewEllipticECDH(crypto.S256()) + private, public, err := gen.GenerateKey(rand.Reader) + if err != nil { + return nil, err + } + + cardPublic, ok := gen.Unmarshal(keyData) + if !ok { + return nil, fmt.Errorf("Could not unmarshal public key from card") + } + + secret, err := gen.GenerateSharedSecret(private, cardPublic) + if err != nil { + return nil, err + } + + return &SecureChannelSession{ + card: card, + secret: secret, + publicKey: gen.Marshal(public), + }, nil +} + +// Pair establishes a new pairing with the smartcard. +func (s *SecureChannelSession) Pair(pairingPassword []byte) error { + secretHash := pbkdf2.Key(norm.NFKD.Bytes(pairingPassword), norm.NFKD.Bytes([]byte(pairingSalt)), 50000, 32, sha256.New) + + challenge := make([]byte, 32) + if _, err := rand.Read(challenge); err != nil { + return err + } + + response, err := s.pair(pairP1FirstStep, challenge) + if err != nil { + return err + } + + md := sha256.New() + md.Write(secretHash[:]) + md.Write(challenge) + + expectedCryptogram := md.Sum(nil) + cardCryptogram := response.Data[:32] + cardChallenge := response.Data[32:64] + + if !bytes.Equal(expectedCryptogram, cardCryptogram) { + return fmt.Errorf("Invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram) + } + + md.Reset() + md.Write(secretHash[:]) + md.Write(cardChallenge) + response, err = s.pair(pairP1LastStep, md.Sum(nil)) + if err != nil { + return err + } + + md.Reset() + md.Write(secretHash[:]) + md.Write(response.Data[1:]) + s.PairingKey = md.Sum(nil) + s.PairingIndex = response.Data[0] + + return nil +} + +// Unpair disestablishes an existing pairing. +func (s *SecureChannelSession) Unpair() error { + if s.PairingKey == nil { + return fmt.Errorf("Cannot unpair: not paired") + } + + _, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{}) + if err != nil { + return err + } + s.PairingKey = nil + // Close channel + s.iv = nil + return nil +} + +// Open initializes the secure channel. +func (s *SecureChannelSession) Open() error { + if s.iv != nil { + return fmt.Errorf("Session already opened") + } + + response, err := s.open() + if err != nil { + return err + } + + // Generate the encryption/mac key by hashing our shared secret, + // pairing key, and the first bytes returned from the Open APDU. + md := sha512.New() + md.Write(s.secret) + md.Write(s.PairingKey) + md.Write(response.Data[:scSecretLength]) + keyData := md.Sum(nil) + s.sessionEncKey = keyData[:scSecretLength] + s.sessionMacKey = keyData[scSecretLength : scSecretLength*2] + + // The IV is the last bytes returned from the Open APDU. + s.iv = response.Data[scSecretLength:] + + return s.mutuallyAuthenticate() +} + +// mutuallyAuthenticate is an internal method to authenticate both ends of the +// connection. +func (s *SecureChannelSession) mutuallyAuthenticate() error { + data := make([]byte, scSecretLength) + if _, err := rand.Read(data); err != nil { + return err + } + + response, err := s.transmitEncrypted(claSCWallet, insMutuallyAuthenticate, 0, 0, data) + if err != nil { + return err + } + if response.Sw1 != 0x90 || response.Sw2 != 0x00 { + return fmt.Errorf("Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2) + } + + if len(response.Data) != scSecretLength { + return fmt.Errorf("Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength) + } + + return nil +} + +// open is an internal method that sends an open APDU. +func (s *SecureChannelSession) open() (*responseAPDU, error) { + return transmit(s.card, &commandAPDU{ + Cla: claSCWallet, + Ins: insOpenSecureChannel, + P1: s.PairingIndex, + P2: 0, + Data: s.publicKey, + Le: 0, + }) +} + +// pair is an internal method that sends a pair APDU. +func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error) { + return transmit(s.card, &commandAPDU{ + Cla: claSCWallet, + Ins: insPair, + P1: p1, + P2: 0, + Data: data, + Le: 0, + }) +} + +// transmitEncrypted sends an encrypted message, and decrypts and returns the response. +func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) { + if s.iv == nil { + return nil, fmt.Errorf("Channel not open") + } + + data, err := s.encryptAPDU(data) + if err != nil { + return nil, err + } + meta := [16]byte{cla, ins, p1, p2, byte(len(data) + scBlockSize)} + if err = s.updateIV(meta[:], data); err != nil { + return nil, err + } + + fulldata := make([]byte, len(s.iv)+len(data)) + copy(fulldata, s.iv) + copy(fulldata[len(s.iv):], data) + + response, err := transmit(s.card, &commandAPDU{ + Cla: cla, + Ins: ins, + P1: p1, + P2: p2, + Data: fulldata, + }) + if err != nil { + return nil, err + } + + rmeta := [16]byte{byte(len(response.Data))} + rmac := response.Data[:len(s.iv)] + rdata := response.Data[len(s.iv):] + plainData, err := s.decryptAPDU(rdata) + if err != nil { + return nil, err + } + + if err = s.updateIV(rmeta[:], rdata); err != nil { + return nil, err + } + if !bytes.Equal(s.iv, rmac) { + return nil, fmt.Errorf("Invalid MAC in response") + } + + rapdu := &responseAPDU{} + rapdu.deserialize(plainData) + + if rapdu.Sw1 != sw1Ok { + return nil, fmt.Errorf("Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) + } + + return rapdu, nil +} + +// encryptAPDU is an internal method that serializes and encrypts an APDU. +func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) { + if len(data) > maxPayloadSize { + return nil, fmt.Errorf("Payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize) + } + data = pad(data, 0x80) + + ret := make([]byte, len(data)) + + a, err := aes.NewCipher(s.sessionEncKey) + if err != nil { + return nil, err + } + crypter := cipher.NewCBCEncrypter(a, s.iv) + crypter.CryptBlocks(ret, data) + return ret, nil +} + +// pad applies message padding to a 16 byte boundary. +func pad(data []byte, terminator byte) []byte { + padded := make([]byte, (len(data)/16+1)*16) + copy(padded, data) + padded[len(data)] = terminator + return padded +} + +// decryptAPDU is an internal method that decrypts and deserializes an APDU. +func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) { + a, err := aes.NewCipher(s.sessionEncKey) + if err != nil { + return nil, err + } + + ret := make([]byte, len(data)) + + crypter := cipher.NewCBCDecrypter(a, s.iv) + crypter.CryptBlocks(ret, data) + return unpad(ret, 0x80) +} + +// unpad strips padding from a message. +func unpad(data []byte, terminator byte) ([]byte, error) { + for i := 1; i <= 16; i++ { + switch data[len(data)-i] { + case 0: + continue + case terminator: + return data[:len(data)-i], nil + default: + return nil, fmt.Errorf("Expected end of padding, got %d", data[len(data)-i]) + } + } + return nil, fmt.Errorf("Expected end of padding, got 0") +} + +// updateIV is an internal method that updates the initialization vector after +// each message exchanged. +func (s *SecureChannelSession) updateIV(meta, data []byte) error { + data = pad(data, 0) + a, err := aes.NewCipher(s.sessionMacKey) + if err != nil { + return err + } + crypter := cipher.NewCBCEncrypter(a, make([]byte, 16)) + crypter.CryptBlocks(meta, meta) + crypter.CryptBlocks(data, data) + // The first 16 bytes of the last block is the MAC + s.iv = data[len(data)-32 : len(data)-16] + return nil +} diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go new file mode 100644 index 0000000000..90ffb64d4f --- /dev/null +++ b/accounts/scwallet/wallet.go @@ -0,0 +1,1074 @@ +// 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 . + +package scwallet + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "encoding/asn1" + "encoding/binary" + "errors" + "fmt" + "math/big" + "sort" + "strings" + "sync" + "time" + + ethereum "github.com/XinFinOrg/XDPoSChain" + "github.com/XinFinOrg/XDPoSChain/accounts" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" + "github.com/XinFinOrg/XDPoSChain/log" + pcsc "github.com/gballet/go-libpcsclite" + "github.com/status-im/keycard-go/derivationpath" +) + +// ErrPairingPasswordNeeded is returned if opening the smart card requires pairing with a pairing +// password. In this case, the calling application should request user input to enter +// the pairing password and send it back. +var ErrPairingPasswordNeeded = errors.New("smartcard: pairing password needed") + +// ErrPINNeeded is returned if opening the smart card requires a PIN code. In +// this case, the calling application should request user input to enter the PIN +// and send it back. +var ErrPINNeeded = errors.New("smartcard: pin needed") + +// ErrPINUnblockNeeded is returned if opening the smart card requires a PIN code, +// but all PIN attempts have already been exhausted. In this case the calling +// application should request user input for the PUK and a new PIN code to set +// fo the card. +var ErrPINUnblockNeeded = errors.New("smartcard: pin unblock needed") + +// ErrAlreadyOpen is returned if the smart card is attempted to be opened, but +// there is already a paired and unlocked session. +var ErrAlreadyOpen = errors.New("smartcard: already open") + +// ErrPubkeyMismatch is returned if the public key recovered from a signature +// does not match the one expected by the user. +var ErrPubkeyMismatch = errors.New("smartcard: recovered public key mismatch") + +var ( + appletAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01, 0x01} + // DerivationSignatureHash is used to derive the public key from the signature of this hash + DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes()) +) + +// List of APDU command-related constants +const ( + claISO7816 = 0 + claSCWallet = 0x80 + + insSelect = 0xA4 + insGetResponse = 0xC0 + sw1GetResponse = 0x61 + sw1Ok = 0x90 + + insVerifyPin = 0x20 + insUnblockPin = 0x22 + insExportKey = 0xC2 + insSign = 0xC0 + insLoadKey = 0xD0 + insDeriveKey = 0xD1 + insStatus = 0xF2 +) + +// List of ADPU command parameters +const ( + P1DeriveKeyFromMaster = uint8(0x00) + P1DeriveKeyFromParent = uint8(0x01) + P1DeriveKeyFromCurrent = uint8(0x10) + statusP1WalletStatus = uint8(0x00) + statusP1Path = uint8(0x01) + signP1PrecomputedHash = uint8(0x01) + signP2OnlyBlock = uint8(0x81) + exportP1Any = uint8(0x00) + exportP2Pubkey = uint8(0x01) +) + +// Minimum time to wait between self derivation attempts, even it the user is +// requesting accounts like crazy. +const selfDeriveThrottling = time.Second + +// Wallet represents a smartcard wallet instance. +type Wallet struct { + Hub *Hub // A handle to the Hub that instantiated this wallet. + PublicKey []byte // The wallet's public key (used for communication and identification, not signing!) + + lock sync.Mutex // Lock that gates access to struct fields and communication with the card + card *pcsc.Card // A handle to the smartcard interface for the wallet. + session *Session // The secure communication session with the card + log log.Logger // Contextual logger to tag the base with its id + + deriveNextPath accounts.DerivationPath // Next derivation path for account auto-discovery + deriveNextAddr common.Address // Next derived account address for auto-discovery + deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with + deriveReq chan chan struct{} // Channel to request a self-derivation on + deriveQuit chan chan error // Channel to terminate the self-deriver with +} + +// NewWallet constructs and returns a new Wallet instance. +func NewWallet(hub *Hub, card *pcsc.Card) *Wallet { + wallet := &Wallet{ + Hub: hub, + card: card, + } + return wallet +} + +// transmit sends an APDU to the smartcard and receives and decodes the response. +// It automatically handles requests by the card to fetch the return data separately, +// and returns an error if the response status code is not success. +func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) { + data, err := command.serialize() + if err != nil { + return nil, err + } + + responseData, _, err := card.Transmit(data) + if err != nil { + return nil, err + } + + response := new(responseAPDU) + if err = response.deserialize(responseData); err != nil { + return nil, err + } + + // Are we being asked to fetch the response separately? + if response.Sw1 == sw1GetResponse && (command.Cla != claISO7816 || command.Ins != insGetResponse) { + return transmit(card, &commandAPDU{ + Cla: claISO7816, + Ins: insGetResponse, + P1: 0, + P2: 0, + Data: nil, + Le: response.Sw2, + }) + } + + if response.Sw1 != sw1Ok { + return nil, fmt.Errorf("Unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) + } + + return response, nil +} + +// applicationInfo encodes information about the smartcard application - its +// instance UID and public key. +type applicationInfo struct { + InstanceUID []byte `asn1:"tag:15"` + PublicKey []byte `asn1:"tag:0"` +} + +// connect connects to the wallet application and establishes a secure channel with it. +// must be called before any other interaction with the wallet. +func (w *Wallet) connect() error { + w.lock.Lock() + defer w.lock.Unlock() + + appinfo, err := w.doselect() + if err != nil { + return err + } + + channel, err := NewSecureChannelSession(w.card, appinfo.PublicKey) + if err != nil { + return err + } + + w.PublicKey = appinfo.PublicKey + w.log = log.New("url", w.URL()) + w.session = &Session{ + Wallet: w, + Channel: channel, + } + return nil +} + +// doselect is an internal (unlocked) function to send a SELECT APDU to the card. +func (w *Wallet) doselect() (*applicationInfo, error) { + response, err := transmit(w.card, &commandAPDU{ + Cla: claISO7816, + Ins: insSelect, + P1: 4, + P2: 0, + Data: appletAID, + }) + if err != nil { + return nil, err + } + + appinfo := new(applicationInfo) + if _, err := asn1.UnmarshalWithParams(response.Data, appinfo, "tag:4"); err != nil { + return nil, err + } + return appinfo, nil +} + +// ping checks the card's status and returns an error if unsuccessful. +func (w *Wallet) ping() error { + w.lock.Lock() + defer w.lock.Unlock() + + // We can't ping if not paired + if !w.session.paired() { + return nil + } + if _, err := w.session.walletStatus(); err != nil { + return err + } + return nil +} + +// release releases any resources held by an open wallet instance. +func (w *Wallet) release() error { + if w.session != nil { + return w.session.release() + } + return nil +} + +// pair is an internal (unlocked) function for establishing a new pairing +// with the wallet. +func (w *Wallet) pair(puk []byte) error { + if w.session.paired() { + return fmt.Errorf("Wallet already paired") + } + pairing, err := w.session.pair(puk) + if err != nil { + return err + } + if err = w.Hub.setPairing(w, &pairing); err != nil { + return err + } + return w.session.authenticate(pairing) +} + +// Unpair deletes an existing wallet pairing. +func (w *Wallet) Unpair(pin []byte) error { + w.lock.Lock() + defer w.lock.Unlock() + + if !w.session.paired() { + return fmt.Errorf("wallet %x not paired", w.PublicKey) + } + if err := w.session.verifyPin(pin); err != nil { + return fmt.Errorf("failed to verify pin: %s", err) + } + if err := w.session.unpair(); err != nil { + return fmt.Errorf("failed to unpair: %s", err) + } + if err := w.Hub.setPairing(w, nil); err != nil { + return err + } + return nil +} + +// URL retrieves the canonical path under which this wallet is reachable. It is +// user by upper layers to define a sorting order over all wallets from multiple +// backends. +func (w *Wallet) URL() accounts.URL { + return accounts.URL{ + Scheme: w.Hub.scheme, + Path: fmt.Sprintf("%x", w.PublicKey[1:5]), // Byte #0 isn't unique; 1:5 covers << 64K cards, bump to 1:9 for << 4M + } +} + +// Status returns a textual status to aid the user in the current state of the +// wallet. It also returns an error indicating any failure the wallet might have +// encountered. +func (w *Wallet) Status() (string, error) { + w.lock.Lock() + defer w.lock.Unlock() + + // If the card is not paired, we can only wait + if !w.session.paired() { + return "Unpaired, waiting for PUK", nil + } + // Yay, we have an encrypted session, retrieve the actual status + status, err := w.session.walletStatus() + if err != nil { + return fmt.Sprintf("Failed: %v", err), err + } + switch { + case !w.session.verified && status.PinRetryCount == 0: + return fmt.Sprintf("Blocked, waiting for PUK and new PIN"), nil + case !w.session.verified: + return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil + case !status.Initialized: + return fmt.Sprintf("Empty, waiting for initialization"), nil + default: + return fmt.Sprintf("Online"), nil + } +} + +// Open initializes access to a wallet instance. It is not meant to unlock or +// decrypt account keys, rather simply to establish a connection to hardware +// wallets and/or to access derivation seeds. +// +// The passphrase parameter may or may not be used by the implementation of a +// particular wallet instance. The reason there is no passwordless open method +// is to strive towards a uniform wallet handling, oblivious to the different +// backend providers. +// +// Please note, if you open a wallet, you must close it to release any allocated +// resources (especially important when working with hardware wallets). +func (w *Wallet) Open(passphrase string) error { + w.lock.Lock() + defer w.lock.Unlock() + + // If the session is already open, bail out + if w.session.verified { + return ErrAlreadyOpen + } + // If the smart card is not yet paired, attempt to do so either from a previous + // pairing key or form the supplied PUK code. + if !w.session.paired() { + // If a previous pairing exists, only ever try to use that + if pairing := w.Hub.pairing(w); pairing != nil { + if err := w.session.authenticate(*pairing); err != nil { + return fmt.Errorf("failed to authenticate card %x: %s", w.PublicKey[:4], err) + } + // Pairing still ok, fall through to PIN checks + } else { + // If no passphrase was supplied, request the PUK from the user + if passphrase == "" { + return ErrPairingPasswordNeeded + } + // Attempt to pair the smart card with the user supplied PUK + if err := w.pair([]byte(passphrase)); err != nil { + return err + } + // Pairing succeeded, fall through to PIN checks. This will of course fail, + // but we can't return ErrPINNeeded directly here becase we don't know whether + // a PIN check or a PIN reset is needed. + passphrase = "" + } + } + // The smart card was successfully paired, retrieve its status to check whether + // PIN verification or unblocking is needed. + status, err := w.session.walletStatus() + if err != nil { + return err + } + // Request the appropriate next authentication data, or use the one supplied + switch { + case passphrase == "" && status.PinRetryCount > 0: + return ErrPINNeeded + case passphrase == "": + return ErrPINUnblockNeeded + case status.PinRetryCount > 0: + if err := w.session.verifyPin([]byte(passphrase)); err != nil { + return err + } + default: + if err := w.session.unblockPin([]byte(passphrase)); err != nil { + return err + } + } + // Smart card paired and unlocked, initialize and register + w.deriveReq = make(chan chan struct{}) + w.deriveQuit = make(chan chan error) + + go w.selfDerive(0) + + // Notify anyone listening for wallet events that a new device is accessible + go w.Hub.updateFeed.Send(accounts.WalletEvent{Wallet: w, Kind: accounts.WalletOpened}) + + return nil +} + +// Close stops and closes the wallet, freeing any resources. +func (w *Wallet) Close() error { + // Ensure the wallet was opened + w.lock.Lock() + dQuit := w.deriveQuit + w.lock.Unlock() + + // Terminate the self-derivations + var derr error + if dQuit != nil { + errc := make(chan error) + dQuit <- errc + derr = <-errc // Save for later, we *must* close the USB + } + // Terminate the device connection + w.lock.Lock() + defer w.lock.Unlock() + + w.deriveQuit = nil + w.deriveReq = nil + + if err := w.release(); err != nil { + return err + } + return derr +} + +// selfDerive is an account derivation loop that upon request attempts to find +// new non-zero accounts. maxEmpty specifies the number of empty accounts that +// should be derived once an initial empty account has been found. +func (w *Wallet) selfDerive(maxEmpty int) { + w.log.Debug("Smart card wallet self-derivation started") + defer w.log.Debug("Smart card wallet self-derivation stopped") + + // Execute self-derivations until termination or error + var ( + reqc chan struct{} + errc chan error + err error + ) + for errc == nil && err == nil { + // Wait until either derivation or termination is requested + select { + case errc = <-w.deriveQuit: + // Termination requested + continue + case reqc = <-w.deriveReq: + // Account discovery requested + } + // Derivation needs a chain and device access, skip if either unavailable + w.lock.Lock() + if w.session == nil || w.deriveChain == nil { + w.lock.Unlock() + reqc <- struct{}{} + continue + } + pairing := w.Hub.pairing(w) + + // Device lock obtained, derive the next batch of accounts + var ( + paths []accounts.DerivationPath + nextAcc accounts.Account + + nextAddr = w.deriveNextAddr + nextPath = w.deriveNextPath + + context = context.Background() + ) + for empty, emptyCount := false, maxEmpty+1; !empty || emptyCount > 0; { + // Retrieve the next derived Ethereum account + if nextAddr == (common.Address{}) { + if nextAcc, err = w.session.derive(nextPath); err != nil { + w.log.Warn("Smartcard wallet account derivation failed", "err", err) + break + } + nextAddr = nextAcc.Address + } + // Check the account's status against the current chain state + var ( + balance *big.Int + nonce uint64 + ) + balance, err = w.deriveChain.BalanceAt(context, nextAddr, nil) + if err != nil { + w.log.Warn("Smartcard wallet balance retrieval failed", "err", err) + break + } + nonce, err = w.deriveChain.NonceAt(context, nextAddr, nil) + if err != nil { + w.log.Warn("Smartcard wallet nonce retrieval failed", "err", err) + break + } + // If the next account is empty and no more empty accounts are + // allowed, stop self-derivation. Add the current one nonetheless. + if balance.Sign() == 0 && nonce == 0 { + empty = true + emptyCount-- + } + // We've just self-derived a new account, start tracking it locally + path := make(accounts.DerivationPath, len(nextPath)) + copy(path[:], nextPath[:]) + paths = append(paths, path) + + // Display a log message to the user for new (or previously empty accounts) + if _, known := pairing.Accounts[nextAddr]; !known || !empty || nextAddr != w.deriveNextAddr { + w.log.Info("Smartcard wallet discovered new account", "address", nextAddr, "path", path, "balance", balance, "nonce", nonce) + } + pairing.Accounts[nextAddr] = path + + // Fetch the next potential account + if !empty || emptyCount > 0 { + nextAddr = common.Address{} + nextPath[len(nextPath)-1]++ + } + } + // If there are new accounts, write them out + if len(paths) > 0 { + err = w.Hub.setPairing(w, pairing) + } + // Shift the self-derivation forward + w.deriveNextAddr = nextAddr + w.deriveNextPath = nextPath + + // Self derivation complete, release device lock + w.lock.Unlock() + + // Notify the user of termination and loop after a bit of time (to avoid trashing) + reqc <- struct{}{} + if err == nil { + select { + case errc = <-w.deriveQuit: + // Termination requested, abort + case <-time.After(selfDeriveThrottling): + // Waited enough, willing to self-derive again + } + } + } + // In case of error, wait for termination + if err != nil { + w.log.Debug("Smartcard wallet self-derivation failed", "err", err) + errc = <-w.deriveQuit + } + errc <- err +} + +// Accounts retrieves the list of signing accounts the wallet is currently aware +// of. For hierarchical deterministic wallets, the list will not be exhaustive, +// rather only contain the accounts explicitly pinned during account derivation. +func (w *Wallet) Accounts() []accounts.Account { + // Attempt self-derivation if it's running + reqc := make(chan struct{}, 1) + select { + case w.deriveReq <- reqc: + // Self-derivation request accepted, wait for it + <-reqc + default: + // Self-derivation offline, throttled or busy, skip + } + + w.lock.Lock() + defer w.lock.Unlock() + + if pairing := w.Hub.pairing(w); pairing != nil { + ret := make([]accounts.Account, 0, len(pairing.Accounts)) + for address, path := range pairing.Accounts { + ret = append(ret, w.makeAccount(address, path)) + } + sort.Sort(accounts.AccountsByURL(ret)) + return ret + } + return nil +} + +func (w *Wallet) makeAccount(address common.Address, path accounts.DerivationPath) accounts.Account { + return accounts.Account{ + Address: address, + URL: accounts.URL{ + Scheme: w.Hub.scheme, + Path: fmt.Sprintf("%x/%s", w.PublicKey[1:3], path.String()), + }, + } +} + +// Contains returns whether an account is part of this particular wallet or not. +func (w *Wallet) Contains(account accounts.Account) bool { + if pairing := w.Hub.pairing(w); pairing != nil { + _, ok := pairing.Accounts[account.Address] + return ok + } + return false +} + +// Initialize installs a keypair generated from the provided key into the wallet. +func (w *Wallet) Initialize(seed []byte) error { + go w.selfDerive(0) + // DO NOT lock at this stage, as the initialize + // function relies on Status() + return w.session.initialize(seed) +} + +// Derive attempts to explicitly derive a hierarchical deterministic account at +// the specified derivation path. If requested, the derived account will be added +// to the wallet's tracked account list. +func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { + w.lock.Lock() + defer w.lock.Unlock() + + account, err := w.session.derive(path) + if err != nil { + return accounts.Account{}, err + } + + if pin { + pairing := w.Hub.pairing(w) + pairing.Accounts[account.Address] = path + if err := w.Hub.setPairing(w, pairing); err != nil { + return accounts.Account{}, err + } + } + + return account, nil +} + +// SelfDerive sets a base account derivation path from which the wallet attempts +// to discover non zero accounts and automatically add them to list of tracked +// accounts. +// +// Note, self derivaton will increment the last component of the specified path +// opposed to decending into a child path to allow discovering accounts starting +// from non zero components. +// +// You can disable automatic account discovery by calling SelfDerive with a nil +// chain state reader. +func (w *Wallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) { + w.lock.Lock() + defer w.lock.Unlock() + + w.deriveNextPath = make(accounts.DerivationPath, len(base)) + copy(w.deriveNextPath[:], base[:]) + + w.deriveNextAddr = common.Address{} + w.deriveChain = chain +} + +// SignData requests the wallet to sign the hash of the given data. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignDataWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { + return w.SignHash(account, crypto.Keccak256(data)) +} + +func (w *Wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) { + w.lock.Lock() + defer w.lock.Unlock() + + path, err := w.findAccountPath(account) + if err != nil { + return nil, err + } + + return w.session.sign(path, hash) +} + +// SignTx requests the wallet to sign the given transaction. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignTxWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + signer := types.NewEIP155Signer(chainID) + hash := signer.Hash(tx) + sig, err := w.SignHash(account, hash[:]) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, sig) +} + +// SignDataWithPassphrase requests the wallet to sign the given hash with the +// given passphrase as extra authentication information. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +func (w *Wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { + return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) +} + +func (w *Wallet) signHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { + if !w.session.verified { + if err := w.Open(passphrase); err != nil { + return nil, err + } + } + + return w.SignHash(account, hash) +} + +// SignText requests the wallet to sign the hash of a given piece of data, prefixed +// by the Ethereum prefix scheme +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +// +// If the wallet requires additional authentication to sign the request (e.g. +// a password to decrypt the account, or a PIN code o verify the transaction), +// an AuthNeededError instance will be returned, containing infos for the user +// about which fields or actions are needed. The user may retry by providing +// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock +// the account in a keystore). +func (w *Wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { + return w.SignHash(account, accounts.TextHash(text)) +} + +// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the +// given hash with the given account using passphrase as extra authentication +func (w *Wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { + return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(accounts.TextHash(text))) +} + +// SignTxWithPassphrase requests the wallet to sign the given transaction, with the +// given passphrase as extra authentication information. +// +// It looks up the account specified either solely via its address contained within, +// or optionally with the aid of any location metadata from the embedded URL field. +func (w *Wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { + if !w.session.verified { + if err := w.Open(passphrase); err != nil { + return nil, err + } + } + return w.SignTx(account, tx, chainID) +} + +// findAccountPath returns the derivation path for the provided account. +// It first checks for the address in the list of pinned accounts, and if it is +// not found, attempts to parse the derivation path from the account's URL. +func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) { + pairing := w.Hub.pairing(w) + if path, ok := pairing.Accounts[account.Address]; ok { + return path, nil + } + + // Look for the path in the URL + if account.URL.Scheme != w.Hub.scheme { + return nil, fmt.Errorf("Scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) + } + + parts := strings.SplitN(account.URL.Path, "/", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("Invalid URL format: %s", account.URL) + } + + if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) { + return nil, fmt.Errorf("URL %s is not for this wallet", account.URL) + } + + return accounts.ParseDerivationPath(parts[1]) +} + +// Session represents a secured communication session with the wallet. +type Session struct { + Wallet *Wallet // A handle to the wallet that opened the session + Channel *SecureChannelSession // A secure channel for encrypted messages + verified bool // Whether the pin has been verified in this session. +} + +// pair establishes a new pairing over this channel, using the provided secret. +func (s *Session) pair(secret []byte) (smartcardPairing, error) { + err := s.Channel.Pair(secret) + if err != nil { + return smartcardPairing{}, err + } + + return smartcardPairing{ + PublicKey: s.Wallet.PublicKey, + PairingIndex: s.Channel.PairingIndex, + PairingKey: s.Channel.PairingKey, + Accounts: make(map[common.Address]accounts.DerivationPath), + }, nil +} + +// unpair deletes an existing pairing. +func (s *Session) unpair() error { + if !s.verified { + return fmt.Errorf("Unpair requires that the PIN be verified") + } + return s.Channel.Unpair() +} + +// verifyPin unlocks a wallet with the provided pin. +func (s *Session) verifyPin(pin []byte) error { + if _, err := s.Channel.transmitEncrypted(claSCWallet, insVerifyPin, 0, 0, pin); err != nil { + return err + } + s.verified = true + return nil +} + +// unblockPin unblocks a wallet with the provided puk and resets the pin to the +// new one specified. +func (s *Session) unblockPin(pukpin []byte) error { + if _, err := s.Channel.transmitEncrypted(claSCWallet, insUnblockPin, 0, 0, pukpin); err != nil { + return err + } + s.verified = true + return nil +} + +// release releases resources associated with the channel. +func (s *Session) release() error { + return s.Wallet.card.Disconnect(pcsc.LeaveCard) +} + +// paired returns true if a valid pairing exists. +func (s *Session) paired() bool { + return s.Channel.PairingKey != nil +} + +// authenticate uses an existing pairing to establish a secure channel. +func (s *Session) authenticate(pairing smartcardPairing) error { + if !bytes.Equal(s.Wallet.PublicKey, pairing.PublicKey) { + return fmt.Errorf("Cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey) + } + s.Channel.PairingKey = pairing.PairingKey + s.Channel.PairingIndex = pairing.PairingIndex + return s.Channel.Open() +} + +// walletStatus describes a smartcard wallet's status information. +type walletStatus struct { + PinRetryCount int // Number of remaining PIN retries + PukRetryCount int // Number of remaining PUK retries + Initialized bool // Whether the card has been initialized with a private key +} + +// walletStatus fetches the wallet's status from the card. +func (s *Session) walletStatus() (*walletStatus, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1WalletStatus, 0, nil) + if err != nil { + return nil, err + } + + status := new(walletStatus) + if _, err := asn1.UnmarshalWithParams(response.Data, status, "tag:3"); err != nil { + return nil, err + } + return status, nil +} + +// derivationPath fetches the wallet's current derivation path from the card. +func (s *Session) derivationPath() (accounts.DerivationPath, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) + if err != nil { + return nil, err + } + buf := bytes.NewReader(response.Data) + path := make(accounts.DerivationPath, len(response.Data)/4) + return path, binary.Read(buf, binary.BigEndian, &path) +} + +// initializeData contains data needed to initialize the smartcard wallet. +type initializeData struct { + PublicKey []byte `asn1:"tag:0"` + PrivateKey []byte `asn1:"tag:1"` + ChainCode []byte `asn1:"tag:2"` +} + +// initialize initializes the card with new key data. +func (s *Session) initialize(seed []byte) error { + // Check that the wallet isn't currently initialized, + // otherwise the key would be overwritten. + status, err := s.Wallet.Status() + if err != nil { + return err + } + if status == "Online" { + return fmt.Errorf("card is already initialized, cowardly refusing to proceed") + } + + s.Wallet.lock.Lock() + defer s.Wallet.lock.Unlock() + + // HMAC the seed to produce the private key and chain code + mac := hmac.New(sha512.New, []byte("Bitcoin seed")) + mac.Write(seed) + seed = mac.Sum(nil) + + key, err := crypto.ToECDSA(seed[:32]) + if err != nil { + return err + } + + id := initializeData{} + id.PublicKey = crypto.FromECDSAPub(&key.PublicKey) + id.PrivateKey = seed[:32] + id.ChainCode = seed[32:] + data, err := asn1.Marshal(id) + if err != nil { + return err + } + + // Nasty hack to force the top-level struct tag to be context-specific + data[0] = 0xA1 + + _, err = s.Channel.transmitEncrypted(claSCWallet, insLoadKey, 0x02, 0, data) + return err +} + +// derive derives a new HD key path on the card. +func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) { + startingPoint, path, err := derivationpath.Decode(path.String()) + if err != nil { + return accounts.Account{}, err + } + + var p1 uint8 + switch startingPoint { + case derivationpath.StartingPointMaster: + p1 = P1DeriveKeyFromMaster + case derivationpath.StartingPointParent: + p1 = P1DeriveKeyFromParent + case derivationpath.StartingPointCurrent: + p1 = P1DeriveKeyFromCurrent + default: + return accounts.Account{}, fmt.Errorf("invalid startingPoint %d", startingPoint) + } + + data := new(bytes.Buffer) + for _, segment := range path { + if err := binary.Write(data, binary.BigEndian, segment); err != nil { + return accounts.Account{}, err + } + } + + _, err = s.Channel.transmitEncrypted(claSCWallet, insDeriveKey, p1, 0, data.Bytes()) + if err != nil { + return accounts.Account{}, err + } + + response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, 0, 0, DerivationSignatureHash[:]) + if err != nil { + return accounts.Account{}, err + } + + sigdata := new(signatureData) + if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { + return accounts.Account{}, err + } + rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() + sig := make([]byte, 65) + copy(sig[32-len(rbytes):32], rbytes) + copy(sig[64-len(sbytes):64], sbytes) + + pubkey, err := determinePublicKey(sig, sigdata.PublicKey) + if err != nil { + return accounts.Account{}, err + } + + pub, err := crypto.UnmarshalPubkey(pubkey) + if err != nil { + return accounts.Account{}, err + } + return s.Wallet.makeAccount(crypto.PubkeyToAddress(*pub), path), nil +} + +// keyExport contains information on an exported keypair. +type keyExport struct { + PublicKey []byte `asn1:"tag:0"` + PrivateKey []byte `asn1:"tag:1,optional"` +} + +// publicKey returns the public key for the current derivation path. +func (s *Session) publicKey() ([]byte, error) { + response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) + if err != nil { + return nil, err + } + keys := new(keyExport) + if _, err := asn1.UnmarshalWithParams(response.Data, keys, "tag:1"); err != nil { + return nil, err + } + return keys.PublicKey, nil +} + +// signatureData contains information on a signature - the signature itself and +// the corresponding public key. +type signatureData struct { + PublicKey []byte `asn1:"tag:0"` + Signature struct { + R *big.Int + S *big.Int + } +} + +// sign asks the card to sign a message, and returns a valid signature after +// recovering the v value. +func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error) { + startTime := time.Now() + _, err := s.derive(path) + if err != nil { + return nil, err + } + deriveTime := time.Now() + + response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, signP1PrecomputedHash, signP2OnlyBlock, hash) + if err != nil { + return nil, err + } + sigdata := new(signatureData) + if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { + return nil, err + } + // Serialize the signature + rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() + sig := make([]byte, 65) + copy(sig[32-len(rbytes):32], rbytes) + copy(sig[64-len(sbytes):64], sbytes) + + // Recover the V value. + sig, err = makeRecoverableSignature(hash, sig, sigdata.PublicKey) + if err != nil { + return nil, err + } + log.Debug("Signed using smartcard", "deriveTime", deriveTime.Sub(startTime), "signingTime", time.Since(deriveTime)) + + return sig, nil +} + +// determinePublicKey uses a signature and the X component of a public key to +// recover the entire public key. +func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) { + for v := 0; v < 2; v++ { + sig[64] = byte(v) + pubkey, err := crypto.Ecrecover(DerivationSignatureHash[:], sig) + if err == nil { + if bytes.Equal(pubkey, pubkeyX) { + return pubkey, nil + } + } else if v == 1 || err != secp256k1.ErrRecoverFailed { + return nil, err + } + } + return nil, ErrPubkeyMismatch +} + +// makeRecoverableSignature uses a signature and an expected public key to +// recover the v value and produce a recoverable signature. +func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) { + for v := 0; v < 2; v++ { + sig[64] = byte(v) + pubkey, err := crypto.Ecrecover(hash, sig) + if err == nil { + if bytes.Equal(pubkey, expectedPubkey) { + return sig, nil + } + } else if v == 1 || err != secp256k1.ErrRecoverFailed { + return nil, err + } + } + return nil, ErrPubkeyMismatch +} diff --git a/accounts/sort.go b/accounts/sort.go new file mode 100644 index 0000000000..f46762114a --- /dev/null +++ b/accounts/sort.go @@ -0,0 +1,31 @@ +// 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 . + +package accounts + +// AccountsByURL implements sort.Interface for []Account based on the URL field. +type AccountsByURL []Account + +func (a AccountsByURL) Len() int { return len(a) } +func (a AccountsByURL) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a AccountsByURL) Less(i, j int) bool { return a[i].URL.Cmp(a[j].URL) < 0 } + +// WalletsByURL implements sort.Interface for []Wallet based on the URL field. +type WalletsByURL []Wallet + +func (w WalletsByURL) Len() int { return len(w) } +func (w WalletsByURL) Swap(i, j int) { w[i], w[j] = w[j], w[i] } +func (w WalletsByURL) Less(i, j int) bool { return w[i].URL().Cmp(w[j].URL()) < 0 } diff --git a/go.mod b/go.mod index fdae1bfb7b..4fbdf262a5 100644 --- a/go.mod +++ b/go.mod @@ -50,6 +50,7 @@ require ( github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 github.com/go-yaml/yaml v2.1.0+incompatible github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c @@ -58,7 +59,10 @@ require ( github.com/mattn/go-isatty v0.0.17 github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible + github.com/status-im/keycard-go v0.3.3 github.com/urfave/cli/v2 v2.27.5 + github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 + golang.org/x/text v0.20.0 google.golang.org/protobuf v1.31.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -94,7 +98,6 @@ require ( golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/term v0.26.0 // indirect - golang.org/x/text v0.20.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools v2.2.0+incompatible // indirect diff --git a/go.sum b/go.sum index 83e3d080d1..738d5a7e35 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= @@ -193,6 +195,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/status-im/keycard-go v0.3.3 h1:qk/JHSkT9sMka+lVXrTOIVSgHIY7lDm46wrUqTsNa4s= +github.com/status-im/keycard-go v0.3.3/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= @@ -216,6 +220,8 @@ github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= +github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From 508ae8f155652da954e87380bf3537687c2f8445 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 055/280] accounts/scwallet: Update README for v2.2.1 support (#19425) Update the app download link to the latest version, as requested in #19418 --- accounts/scwallet/README.md | 63 ++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md index 740c2b28c1..20519e092d 100644 --- a/accounts/scwallet/README.md +++ b/accounts/scwallet/README.md @@ -10,40 +10,72 @@ **WARNING: FOILLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** - You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.1.1/keycard_v2.1.1.cap) + You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get _at least_ version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.2.1/keycard_v2.2.1.cap) You also need to make sure that the PCSC daemon is running on your system. Then, you can install the application to the card by typing: ``` - keycard install -a keycard_v2.1.cap + keycard install -a keycard_v2.2.1.cap && keycard init ``` - Then you can initialize the application by typing: + At the end of this process, you will be provided with a PIN, a PUK and a pairing password. Write them down, you'll need them shortly. + + Start `geth` with the `console` command. You will notice the following warning: ``` - keycard init + WARN [04-09|16:58:38.898] Failed to open wallet url=pcsc://044def09 err="smartcard: pairing password needed" ``` - Then the card needs to be paired: + Write down the URL (`pcsc://044def09` in this example). Then ask `geth` to open the wallet: ``` - keycard pair + > personal.openWallet("pcsc://044def09") + Please enter the pairing password: ``` - Finally, you need to have the card generate a new master key: + Enter the pairing password that you have received during card initialization. Same with the PIN that you will subsequently be + asked for. + + If everything goes well, you should see your new account when typing `personal` on the console: ``` - keycard shell < personal + WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=pcsc://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985" + { + listAccounts: [], + listWallets: [{ + status: "Empty, waiting for initialization", + url: "pcsc://044def09" + }], + ... + } ``` + So the communication with the card is working, but there is no key associated with this wallet. Let's create it: + + ``` + > personal.initializeWallet("pcsc://044def09") + "tilt ... impact" + ``` + + You should get a list of words, this is your seed so write them down. Your wallet should now be initialized: + + ``` + > personal.listWallets + [{ + accounts: [{ + address: "0x678b7cd55c61917defb23546a41803c5bfefbc7a", + url: "pcsc://044d/m/44'/60'/0'/0/0" + }], + status: "Online", + url: "pcsc://044def09" + }] + ``` + + You're all set! + ## Usage 1. Start `geth` with the `console` command @@ -66,4 +98,5 @@ personal.openWallet("pcsc://a4d73015") ## Known issues - * Starting geth with a valid card seems to make firefox crash. \ No newline at end of file + * Starting geth with a valid card seems to make firefox crash. + * PCSC version 4.4 should work, but is currently untested From 194a77505fc6b3532076d5b6479867b3e64c1256 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 056/280] accounts: switch Ledger derivation path to canonical one (#19438) --- accounts/accounts.go | 6 +- accounts/hd.go | 8 +- accounts/keystore/wallet.go | 3 +- accounts/scwallet/wallet.go | 128 +++++++++++++++++--------------- accounts/usbwallet/wallet.go | 137 ++++++++++++++++++++--------------- cmd/XDC/main.go | 8 +- 6 files changed, 161 insertions(+), 129 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 94ba25d62a..4677318372 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -92,9 +92,13 @@ type Wallet interface { // opposed to decending into a child path to allow discovering accounts starting // from non zero components. // + // Some hardware wallets switched derivation paths through their evolution, so + // this method supports providing multiple bases to discover old user accounts + // too. Only the last base will be used to derive the next empty account. + // // You can disable automatic account discovery by calling SelfDerive with a nil // chain state reader. - SelfDerive(base DerivationPath, chain ethereum.ChainStateReader) + SelfDerive(bases []DerivationPath, chain ethereum.ChainStateReader) // SignHash requests the wallet to sign the given hash. // diff --git a/accounts/hd.go b/accounts/hd.go index bddd8796c1..7727d1a851 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -35,10 +35,10 @@ var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, // at m/44'/60'/0'/0/1, etc. var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0} -// DefaultLedgerBaseDerivationPath is the base path from which custom derivation endpoints -// are incremented. As such, the first account will be at m/44'/60'/0'/0, the second -// at m/44'/60'/0'/1, etc. -var DefaultLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} +// LegacyLedgerBaseDerivationPath is the legacy base path from which custom derivation +// endpoints are incremented. As such, the first account will be at m/44'/60'/0'/0, the +// second at m/44'/60'/0'/1, etc. +var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} // DerivationPath represents the computer friendly version of a hierarchical // deterministic wallet account derivaion path. diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 6b44a66f4e..18ba31701b 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -77,7 +77,8 @@ func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (account // SelfDerive implements accounts.Wallet, but is a noop for plain wallets since // there is no notion of hierarchical account derivation for plain keystore accounts. -func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) {} +func (w *keystoreWallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { +} // SignHash attempts to sign the given hash with // the given account. If the wallet does not wrap this particular account, an diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 90ffb64d4f..6d76985df2 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -119,11 +119,11 @@ type Wallet struct { session *Session // The secure communication session with the card log log.Logger // Contextual logger to tag the base with its id - deriveNextPath accounts.DerivationPath // Next derivation path for account auto-discovery - deriveNextAddr common.Address // Next derived account address for auto-discovery - deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with - deriveReq chan chan struct{} // Channel to request a self-derivation on - deriveQuit chan chan error // Channel to terminate the self-deriver with + deriveNextPaths []accounts.DerivationPath // Next derivation paths for account auto-discovery (multiple bases supported) + deriveNextAddrs []common.Address // Next derived account addresses for auto-discovery (multiple bases supported) + deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with + deriveReq chan chan struct{} // Channel to request a self-derivation on + deriveQuit chan chan error // Channel to terminate the self-deriver with } // NewWallet constructs and returns a new Wallet instance. @@ -390,7 +390,7 @@ func (w *Wallet) Open(passphrase string) error { w.deriveReq = make(chan chan struct{}) w.deriveQuit = make(chan chan error) - go w.selfDerive(0) + go w.selfDerive() // Notify anyone listening for wallet events that a new device is accessible go w.Hub.updateFeed.Send(accounts.WalletEvent{Wallet: w, Kind: accounts.WalletOpened}) @@ -426,9 +426,8 @@ func (w *Wallet) Close() error { } // selfDerive is an account derivation loop that upon request attempts to find -// new non-zero accounts. maxEmpty specifies the number of empty accounts that -// should be derived once an initial empty account has been found. -func (w *Wallet) selfDerive(maxEmpty int) { +// new non-zero accounts. +func (w *Wallet) selfDerive() { w.log.Debug("Smart card wallet self-derivation started") defer w.log.Debug("Smart card wallet self-derivation stopped") @@ -461,56 +460,59 @@ func (w *Wallet) selfDerive(maxEmpty int) { paths []accounts.DerivationPath nextAcc accounts.Account - nextAddr = w.deriveNextAddr - nextPath = w.deriveNextPath + nextPaths = append([]accounts.DerivationPath{}, w.deriveNextPaths...) + nextAddrs = append([]common.Address{}, w.deriveNextAddrs...) context = context.Background() ) - for empty, emptyCount := false, maxEmpty+1; !empty || emptyCount > 0; { - // Retrieve the next derived Ethereum account - if nextAddr == (common.Address{}) { - if nextAcc, err = w.session.derive(nextPath); err != nil { - w.log.Warn("Smartcard wallet account derivation failed", "err", err) + for i := 0; i < len(nextAddrs); i++ { + for empty := false; !empty; { + // Retrieve the next derived Ethereum account + if nextAddrs[i] == (common.Address{}) { + if nextAcc, err = w.session.derive(nextPaths[i]); err != nil { + w.log.Warn("Smartcard wallet account derivation failed", "err", err) + break + } + nextAddrs[i] = nextAcc.Address + } + // Check the account's status against the current chain state + var ( + balance *big.Int + nonce uint64 + ) + balance, err = w.deriveChain.BalanceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("Smartcard wallet balance retrieval failed", "err", err) break } - nextAddr = nextAcc.Address - } - // Check the account's status against the current chain state - var ( - balance *big.Int - nonce uint64 - ) - balance, err = w.deriveChain.BalanceAt(context, nextAddr, nil) - if err != nil { - w.log.Warn("Smartcard wallet balance retrieval failed", "err", err) - break - } - nonce, err = w.deriveChain.NonceAt(context, nextAddr, nil) - if err != nil { - w.log.Warn("Smartcard wallet nonce retrieval failed", "err", err) - break - } - // If the next account is empty and no more empty accounts are - // allowed, stop self-derivation. Add the current one nonetheless. - if balance.Sign() == 0 && nonce == 0 { - empty = true - emptyCount-- - } - // We've just self-derived a new account, start tracking it locally - path := make(accounts.DerivationPath, len(nextPath)) - copy(path[:], nextPath[:]) - paths = append(paths, path) + nonce, err = w.deriveChain.NonceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("Smartcard wallet nonce retrieval failed", "err", err) + break + } + // If the next account is empty, stop self-derivation, but add for the last base path + if balance.Sign() == 0 && nonce == 0 { + empty = true + if i < len(nextAddrs)-1 { + break + } + } + // We've just self-derived a new account, start tracking it locally + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) + paths = append(paths, path) - // Display a log message to the user for new (or previously empty accounts) - if _, known := pairing.Accounts[nextAddr]; !known || !empty || nextAddr != w.deriveNextAddr { - w.log.Info("Smartcard wallet discovered new account", "address", nextAddr, "path", path, "balance", balance, "nonce", nonce) - } - pairing.Accounts[nextAddr] = path + // Display a log message to the user for new (or previously empty accounts) + if _, known := pairing.Accounts[nextAddrs[i]]; !known || !empty || nextAddrs[i] != w.deriveNextAddrs[i] { + w.log.Info("Smartcard wallet discovered new account", "address", nextAddrs[i], "path", path, "balance", balance, "nonce", nonce) + } + pairing.Accounts[nextAddrs[i]] = path - // Fetch the next potential account - if !empty || emptyCount > 0 { - nextAddr = common.Address{} - nextPath[len(nextPath)-1]++ + // Fetch the next potential account + if !empty { + nextAddrs[i] = common.Address{} + nextPaths[i][len(nextPaths[i])-1]++ + } } } // If there are new accounts, write them out @@ -518,8 +520,8 @@ func (w *Wallet) selfDerive(maxEmpty int) { err = w.Hub.setPairing(w, pairing) } // Shift the self-derivation forward - w.deriveNextAddr = nextAddr - w.deriveNextPath = nextPath + w.deriveNextAddrs = nextAddrs + w.deriveNextPaths = nextPaths // Self derivation complete, release device lock w.lock.Unlock() @@ -592,7 +594,7 @@ func (w *Wallet) Contains(account accounts.Account) bool { // Initialize installs a keypair generated from the provided key into the wallet. func (w *Wallet) Initialize(seed []byte) error { - go w.selfDerive(0) + go w.selfDerive() // DO NOT lock at this stage, as the initialize // function relies on Status() return w.session.initialize(seed) @@ -629,16 +631,22 @@ func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun // opposed to decending into a child path to allow discovering accounts starting // from non zero components. // +// Some hardware wallets switched derivation paths through their evolution, so +// this method supports providing multiple bases to discover old user accounts +// too. Only the last base will be used to derive the next empty account. +// // You can disable automatic account discovery by calling SelfDerive with a nil // chain state reader. -func (w *Wallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) { +func (w *Wallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { w.lock.Lock() defer w.lock.Unlock() - w.deriveNextPath = make(accounts.DerivationPath, len(base)) - copy(w.deriveNextPath[:], base[:]) - - w.deriveNextAddr = common.Address{} + w.deriveNextPaths = make([]accounts.DerivationPath, len(bases)) + for i, base := range bases { + w.deriveNextPaths[i] = make(accounts.DerivationPath, len(base)) + copy(w.deriveNextPaths[i][:], base[:]) + } + w.deriveNextAddrs = make([]common.Address, len(bases)) w.deriveChain = chain } diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 99c5724fc7..64d07e1aeb 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -83,11 +83,11 @@ type wallet struct { accounts []accounts.Account // List of derive accounts pinned on the hardware wallet paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations - deriveNextPath accounts.DerivationPath // Next derivation path for account auto-discovery - deriveNextAddr common.Address // Next derived account address for auto-discovery - deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with - deriveReq chan chan struct{} // Channel to request a self-derivation on - deriveQuit chan chan error // Channel to terminate the self-deriver with + deriveNextPaths []accounts.DerivationPath // Next derivation paths for account auto-discovery (multiple bases supported) + deriveNextAddrs []common.Address // Next derived account addresses for auto-discovery (multiple bases supported) + deriveChain ethereum.ChainStateReader // Blockchain state reader to discover used account with + deriveReq chan chan struct{} // Channel to request a self-derivation on + deriveQuit chan chan error // Channel to terminate the self-deriver with healthQuit chan chan error @@ -339,57 +339,62 @@ func (w *wallet) selfDerive() { accs []accounts.Account paths []accounts.DerivationPath - nextAddr = w.deriveNextAddr - nextPath = w.deriveNextPath + nextPaths = append([]accounts.DerivationPath{}, w.deriveNextPaths...) + nextAddrs = append([]common.Address{}, w.deriveNextAddrs...) context = context.Background() ) - for empty := false; !empty; { - // Retrieve the next derived Ethereum account - if nextAddr == (common.Address{}) { - if nextAddr, err = w.driver.Derive(nextPath); err != nil { - w.log.Warn("USB wallet account derivation failed", "err", err) + for i := 0; i < len(nextAddrs); i++ { + for empty := false; !empty; { + // Retrieve the next derived Ethereum account + if nextAddrs[i] == (common.Address{}) { + if nextAddrs[i], err = w.driver.Derive(nextPaths[i]); err != nil { + w.log.Warn("USB wallet account derivation failed", "err", err) + break + } + } + // Check the account's status against the current chain state + var ( + balance *big.Int + nonce uint64 + ) + balance, err = w.deriveChain.BalanceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("USB wallet balance retrieval failed", "err", err) break } - } - // Check the account's status against the current chain state - var ( - balance *big.Int - nonce uint64 - ) - balance, err = w.deriveChain.BalanceAt(context, nextAddr, nil) - if err != nil { - w.log.Warn("USB wallet balance retrieval failed", "err", err) - break - } - nonce, err = w.deriveChain.NonceAt(context, nextAddr, nil) - if err != nil { - w.log.Warn("USB wallet nonce retrieval failed", "err", err) - break - } - // If the next account is empty, stop self-derivation, but add it nonetheless - if balance.Sign() == 0 && nonce == 0 { - empty = true - } - // We've just self-derived a new account, start tracking it locally - path := make(accounts.DerivationPath, len(nextPath)) - copy(path[:], nextPath[:]) - paths = append(paths, path) + nonce, err = w.deriveChain.NonceAt(context, nextAddrs[i], nil) + if err != nil { + w.log.Warn("USB wallet nonce retrieval failed", "err", err) + break + } + // If the next account is empty, stop self-derivation, but add for the last base path + if balance.Sign() == 0 && nonce == 0 { + empty = true + if i < len(nextAddrs)-1 { + break + } + } + // We've just self-derived a new account, start tracking it locally + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) + paths = append(paths, path) - account := accounts.Account{ - Address: nextAddr, - URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, - } - accs = append(accs, account) + account := accounts.Account{ + Address: nextAddrs[i], + URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, + } + accs = append(accs, account) - // Display a log message to the user for new (or previously empty accounts) - if _, known := w.paths[nextAddr]; !known || (!empty && nextAddr == w.deriveNextAddr) { - w.log.Info("USB wallet discovered new account", "address", nextAddr, "path", path, "balance", balance, "nonce", nonce) - } - // Fetch the next potential account - if !empty { - nextAddr = common.Address{} - nextPath[len(nextPath)-1]++ + // Display a log message to the user for new (or previously empty accounts) + if _, known := w.paths[nextAddrs[i]]; !known || (!empty && nextAddrs[i] == w.deriveNextAddrs[i]) { + w.log.Info("USB wallet discovered new account", "address", nextAddrs[i], "path", path, "balance", balance, "nonce", nonce) + } + // Fetch the next potential account + if !empty { + nextAddrs[i] = common.Address{} + nextPaths[i][len(nextPaths[i])-1]++ + } } } // Self derivation complete, release device lock @@ -406,8 +411,8 @@ func (w *wallet) selfDerive() { } // Shift the self-derivation forward // TODO(karalabe): don't overwrite changes from wallet.SelfDerive - w.deriveNextAddr = nextAddr - w.deriveNextPath = nextPath + w.deriveNextAddrs = nextAddrs + w.deriveNextPaths = nextPaths w.stateLock.Unlock() // Notify the user of termination and loop after a bit of time (to avoid trashing) @@ -479,18 +484,30 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun return account, nil } -// SelfDerive implements accounts.Wallet, trying to discover accounts that the -// user used previously (based on the chain state), but ones that he/she did not -// explicitly pin to the wallet manually. To avoid chain head monitoring, self -// derivation only runs during account listing (and even then throttled). -func (w *wallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) { +// SelfDerive sets a base account derivation path from which the wallet attempts +// to discover non zero accounts and automatically add them to list of tracked +// accounts. +// +// Note, self derivaton will increment the last component of the specified path +// opposed to decending into a child path to allow discovering accounts starting +// from non zero components. +// +// Some hardware wallets switched derivation paths through their evolution, so +// this method supports providing multiple bases to discover old user accounts +// too. Only the last base will be used to derive the next empty account. +// +// You can disable automatic account discovery by calling SelfDerive with a nil +// chain state reader. +func (w *wallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) { w.stateLock.Lock() defer w.stateLock.Unlock() - w.deriveNextPath = make(accounts.DerivationPath, len(base)) - copy(w.deriveNextPath[:], base[:]) - - w.deriveNextAddr = common.Address{} + w.deriveNextPaths = make([]accounts.DerivationPath, len(bases)) + for i, base := range bases { + w.deriveNextPaths[i] = make(accounts.DerivationPath, len(base)) + copy(w.deriveNextPaths[i][:], base[:]) + } + w.deriveNextAddrs = make([]common.Address, len(bases)) w.deriveChain = chain } diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 21d8ee777a..bf09ad27d2 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -312,11 +312,13 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) { status, _ := event.Wallet.Status() log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) + var derivationPaths []accounts.DerivationPath if event.Wallet.URL().Scheme == "ledger" { - event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader) - } else { - event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) + derivationPaths = append(derivationPaths, accounts.LegacyLedgerBaseDerivationPath) } + derivationPaths = append(derivationPaths, accounts.DefaultBaseDerivationPath) + + event.Wallet.SelfDerive(derivationPaths, stateReader) case accounts.WalletDropped: log.Info("Old wallet dropped", "url", event.Wallet.URL()) From 44b6b146855cd3444fa9c3744afc716f6c51079e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 057/280] accounts/scwallet: fix card pairing instruction message (#19436) --- accounts/scwallet/wallet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 6d76985df2..37e2682136 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -303,7 +303,7 @@ func (w *Wallet) Status() (string, error) { // If the card is not paired, we can only wait if !w.session.paired() { - return "Unpaired, waiting for PUK", nil + return "Unpaired, waiting for pairing password", nil } // Yay, we have an encrypted session, retrieve the actual status status, err := w.session.walletStatus() From fa356147842ae78ef3cce360e80a92f954d54a1d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 058/280] accounts, cmd: add note about backing up the keystore (#19432) --- accounts/keystore/passphrase.go | 5 +++-- cmd/XDC/accountcmd.go | 10 ++++++++-- cmd/XDC/accountcmd_test.go | 14 +++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index 4577efee52..bf4446c7f7 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -37,6 +37,7 @@ import ( "os" "path/filepath" + "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -96,9 +97,9 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) } // StoreKey generates a key, encrypts with 'auth' and stores in the given directory -func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) { +func StoreKey(dir, auth string, scryptN, scryptP int) (accounts.Account, error) { _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP, false}, rand.Reader, auth) - return a.Address, err + return a, err } func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { diff --git a/cmd/XDC/accountcmd.go b/cmd/XDC/accountcmd.go index 46909bdf94..ae89a698ea 100644 --- a/cmd/XDC/accountcmd.go +++ b/cmd/XDC/accountcmd.go @@ -310,12 +310,18 @@ func accountCreate(ctx *cli.Context) error { password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) - address, err := keystore.StoreKey(keydir, password, scryptN, scryptP) + account, err := keystore.StoreKey(keydir, password, scryptN, scryptP) if err != nil { utils.Fatalf("Failed to create account: %v", err) } - fmt.Printf("Address: {xdc%x}\n", address) + fmt.Printf("\nYour new key was generated\n\n") + fmt.Printf("Public address of the key: %s\n", account.Address.Hex()) + fmt.Printf("Path of the secret key file: %s\n\n", account.URL.Path) + fmt.Printf("- You can share your public address with anyone. Others need it to interact with you.\n") + fmt.Printf("- You must NEVER share the secret key with anyone! The key controls access to your funds!\n") + fmt.Printf("- You must BACKUP your key file! Without the key, it's impossible to access account funds!\n") + fmt.Printf("- You must REMEMBER your password! Without the password, it's impossible to decrypt the key!\n\n") return nil } diff --git a/cmd/XDC/accountcmd_test.go b/cmd/XDC/accountcmd_test.go index 668739594d..dad6b45b69 100644 --- a/cmd/XDC/accountcmd_test.go +++ b/cmd/XDC/accountcmd_test.go @@ -79,8 +79,20 @@ Your new account is locked with a password. Please give a password. Do not forge !! Unsupported terminal, password will be echoed. Passphrase: {{.InputLine "foobar"}} Repeat passphrase: {{.InputLine "foobar"}} + +Your new key was generated + +`) + XDC.ExpectRegexp(` +Public address of the key: xdc[0-9a-fA-F]{40} +Path of the secret key file: .*UTC--.+--xdc[0-9a-fA-F]{40} + +- You can share your public address with anyone. Others need it to interact with you. +- You must NEVER share the secret key with anyone! The key controls access to your funds! +- You must BACKUP your key file! Without the key, it's impossible to access account funds! +- You must REMEMBER your password! Without the password, it's impossible to decrypt the key! + `) - XDC.ExpectRegexp(`Address: \{xdc[0-9a-f]{40}\}\n`) } func TestAccountNewBadRepeat(t *testing.T) { From b5ace996242eeb1d5719c85395be1a4cfbf54e97 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 059/280] accounts/usbwallet: fix a comment typo in trezor driver (#19535) --- accounts/usbwallet/trezor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 3b63a9f234..b64db3863f 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -86,7 +86,7 @@ func (w *trezorDriver) Status() (string, error) { // Open implements usbwallet.driver, attempting to initialize the connection to // the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation: // - The first phase is to initialize the connection and read the wallet's -// features. This phase is invoked is the provided passphrase is empty. The +// features. This phase is invoked if the provided passphrase is empty. The // device will display the pinpad as a result and will return an appropriate // error to notify the user that a second open phase is needed. // - The second phase is to unlock access to the Trezor, which is done by the From 44d58cb8dcc3aea364a356aaf2c240785e025424 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 060/280] accounts/abi: fix documentation (#19568) --- accounts/abi/method.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 370bac004b..6037ddf220 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -27,9 +27,9 @@ import ( // If the method is `Const` no transaction needs to be created for this // particular Method call. It can easily be simulated using a local VM. // For example a `Balance()` method only needs to retrieve something -// from the storage and therefor requires no Tx to be send to the +// from the storage and therefore requires no Tx to be send to the // network. A method such as `Transact` does require a Tx and thus will -// be flagged `true`. +// be flagged `false`. // Input specifies the required input parameters for this gives method. type Method struct { Name string From b75f946081022cfc0a66449ceba6e0bea9c0f0fa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:08 +0800 Subject: [PATCH 061/280] accounts: better support for EIP-191 intended validator (#19523) --- accounts/accounts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 4677318372..5fdf271ae0 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -36,7 +36,7 @@ type Account struct { } const ( - MimetypeTextWithValidator = "text/validator" + MimetypeDataWithValidator = "data/validator" MimetypeTypedData = "data/typed" MimetypeClique = "application/x-clique-header" MimetypeTextPlain = "text/plain" From 316d2f80527834717674252256b8672bca783016 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 062/280] accounts/abi: fix TestUnpackMethodIntoMap (#19484) --- accounts/abi/abi_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index bb7e61ae24..01a9fb33da 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -791,7 +791,7 @@ func TestUnpackMethodIntoMap(t *testing.T) { if err = abi.UnpackIntoMap(getMap, "get", data); err != nil { t.Error(err) } - if len(sendMap) != 1 { + if len(getMap) != 1 { t.Error("unpacked `get` map expected to have length 1") } expectedBytes := []byte{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, 96, 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, 88, 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, 96, 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, 88, 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, 96, 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, 88, 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, 96, 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, 88, 0} From 7c8707f03edf5dbe0fecdbf1f94ecbec0c3ef927 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 063/280] accounts, p2p: make CGO_ENABLED=0 build again (#19593) --- accounts/scwallet/wallet.go | 25 ++++++++----------------- p2p/discover/node.go | 11 +++++------ p2p/rlpx.go | 3 +-- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 37e2682136..bc7a1c553c 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -37,7 +37,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" "github.com/XinFinOrg/XDPoSChain/log" pcsc "github.com/gballet/go-libpcsclite" "github.com/status-im/keycard-go/derivationpath" @@ -1050,33 +1049,25 @@ func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error // determinePublicKey uses a signature and the X component of a public key to // recover the entire public key. func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) { - for v := 0; v < 2; v++ { - sig[64] = byte(v) - pubkey, err := crypto.Ecrecover(DerivationSignatureHash[:], sig) - if err == nil { - if bytes.Equal(pubkey, pubkeyX) { - return pubkey, nil - } - } else if v == 1 || err != secp256k1.ErrRecoverFailed { - return nil, err - } - } - return nil, ErrPubkeyMismatch + return makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkeyX) } // makeRecoverableSignature uses a signature and an expected public key to // recover the v value and produce a recoverable signature. func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) { + var libraryError error for v := 0; v < 2; v++ { sig[64] = byte(v) - pubkey, err := crypto.Ecrecover(hash, sig) - if err == nil { + if pubkey, err := crypto.Ecrecover(hash, sig); err == nil { if bytes.Equal(pubkey, expectedPubkey) { return sig, nil } - } else if v == 1 || err != secp256k1.ErrRecoverFailed { - return nil, err + } else { + libraryError = err } } + if libraryError != nil { + return nil, libraryError + } return nil, ErrPubkeyMismatch } diff --git a/p2p/discover/node.go b/p2p/discover/node.go index 48fc2edd1b..a748e6b151 100644 --- a/p2p/discover/node.go +++ b/p2p/discover/node.go @@ -33,7 +33,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" ) const NodeIDBits = 512 @@ -125,8 +124,8 @@ var incompleteNodeURL = regexp.MustCompile("(?i)^(?:enode://)?([0-9a-f]+)$") // // For incomplete nodes, the designator must look like one of these // -// enode:// -// +// enode:// +// // // For complete nodes, the node ID is encoded in the username portion // of the URL, separated from the host by an @ sign. The hostname can @@ -139,7 +138,7 @@ var incompleteNodeURL = regexp.MustCompile("(?i)^(?:enode://)?([0-9a-f]+)$") // a node with IP address 10.3.58.6, TCP listening port 30303 // and UDP discovery port 30301. // -// enode://@10.3.58.6:30303?discport=30301 +// enode://@10.3.58.6:30303?discport=30301 func ParseNode(rawurl string) (*Node, error) { if m := incompleteNodeURL.FindStringSubmatch(rawurl); m != nil { id, err := HexID(m[1]) @@ -323,7 +322,7 @@ func (id NodeID) Pubkey() (*ecdsa.PublicKey, error) { p.X.SetBytes(id[:half]) p.Y.SetBytes(id[half:]) if !p.Curve.IsOnCurve(p.X, p.Y) { - return nil, errors.New("id is invalid secp256k1 curve point") + return nil, errors.New("invalid secp256k1 curve point") } return p, nil } @@ -331,7 +330,7 @@ func (id NodeID) Pubkey() (*ecdsa.PublicKey, error) { // recoverNodeID computes the public key used to sign the // given hash from the signature. func recoverNodeID(hash, sig []byte) (id NodeID, err error) { - pubkey, err := secp256k1.RecoverPubkey(hash, sig) + pubkey, err := crypto.Ecrecover(hash, sig) if err != nil { return id, err } diff --git a/p2p/rlpx.go b/p2p/rlpx.go index 640e7ce3f2..ad422d5ebd 100644 --- a/p2p/rlpx.go +++ b/p2p/rlpx.go @@ -36,7 +36,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto/ecies" - "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" "github.com/XinFinOrg/XDPoSChain/p2p/discover" "github.com/XinFinOrg/XDPoSChain/rlp" "github.com/golang/snappy" @@ -408,7 +407,7 @@ func (h *encHandshake) handleAuthMsg(msg *authMsgV4, prv *ecdsa.PrivateKey) erro return err } signedMsg := xor(token, h.initNonce) - remoteRandomPub, err := secp256k1.RecoverPubkey(signedMsg, msg.Signature[:]) + remoteRandomPub, err := crypto.Ecrecover(signedMsg, msg.Signature[:]) if err != nil { return err } From b2a9e1cb67c96dfa2acf9daf5ebd6cd5bcaff1f3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 064/280] accounts/usbwallet: enable the Nano X and upcoming Ledger IDs (#19623) --- accounts/usbwallet/hub.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 9b3c5f89ab..b409f19a07 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -68,7 +68,20 @@ type Hub struct { // NewLedgerHub creates a new hardware wallet manager for Ledger devices. func NewLedgerHub() (*Hub, error) { - return newHub(LedgerScheme, 0x2c97, []uint16{0x0000 /* Ledger Blue */, 0x0001 /* Ledger Nano S */}, 0xffa0, 0, newLedgerDriver) + return newHub(LedgerScheme, 0x2c97, []uint16{ + // Original product IDs + 0x0000, /* Ledger Blue */ + 0x0001, /* Ledger Nano S */ + 0x0004, /* Ledger Nano X */ + + // Upcoming product IDs: https://www.ledger.com/2019/05/17/windows-10-update-sunsetting-u2f-tunnel-transport-for-ledger-devices/ + 0x0015, /* HID + U2F + WebUSB Ledger Blue */ + 0x1015, /* HID + U2F + WebUSB Ledger Nano S */ + 0x4015, /* HID + U2F + WebUSB Ledger Nano X */ + 0x0011, /* HID + WebUSB Ledger Blue */ + 0x1011, /* HID + WebUSB Ledger Nano S */ + 0x4011, /* HID + WebUSB Ledger Nano X */ + }, 0xffa0, 0, newLedgerDriver) } // NewTrezorHub creates a new hardware wallet manager for Trezor devices. From 00fbe17f2e0659d3b777ca8d2a3012a82076b422 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 065/280] accounts/keystore: enable fallback for darwin,!cgo (#19614) Without this, accounts/keystore fails to build for Darwin with CGO_ENABLED=0. --- accounts/keystore/watch.go | 2 +- accounts/keystore/watch_fallback.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index 8f1c9dac0d..0a2d142bd9 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// +build darwin,!ios freebsd linux,!arm64 netbsd solaris +// +build darwin,!ios,cgo freebsd linux,!arm64 netbsd solaris package keystore diff --git a/accounts/keystore/watch_fallback.go b/accounts/keystore/watch_fallback.go index 7c5e9cb2e2..de0e87f8a5 100644 --- a/accounts/keystore/watch_fallback.go +++ b/accounts/keystore/watch_fallback.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -// +build ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris +// +build darwin,!cgo ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris // This is the fallback implementation of directory watching. // It is used on unsupported platforms. From f80a00b6fa9423a998977114f873dda7f14693a1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 066/280] accounts/scwallet: display PUK retry count, validate PIN/PUK length (#19524) --- accounts/scwallet/wallet.go | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index bc7a1c553c..5948e9b30b 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -27,6 +27,7 @@ import ( "errors" "fmt" "math/big" + "regexp" "sort" "strings" "sync" @@ -310,8 +311,10 @@ func (w *Wallet) Status() (string, error) { return fmt.Sprintf("Failed: %v", err), err } switch { + case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0: + return fmt.Sprintf("Bricked, waiting for full wipe"), nil case !w.session.verified && status.PinRetryCount == 0: - return fmt.Sprintf("Blocked, waiting for PUK and new PIN"), nil + return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil case !w.session.verified: return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil case !status.Initialized: @@ -377,10 +380,18 @@ func (w *Wallet) Open(passphrase string) error { case passphrase == "": return ErrPINUnblockNeeded case status.PinRetryCount > 0: + if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) { + w.log.Error("PIN needs to be at least 6 digits") + return ErrPINNeeded + } if err := w.session.verifyPin([]byte(passphrase)); err != nil { return err } default: + if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) { + w.log.Error("PUK needs to be at least 12 digits") + return ErrPINUnblockNeeded + } if err := w.session.unblockPin([]byte(passphrase)); err != nil { return err } @@ -971,12 +982,10 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) copy(sig[32-len(rbytes):32], rbytes) copy(sig[64-len(sbytes):64], sbytes) - pubkey, err := determinePublicKey(sig, sigdata.PublicKey) - if err != nil { + if err := confirmPublicKey(sig, sigdata.PublicKey); err != nil { return accounts.Account{}, err } - - pub, err := crypto.UnmarshalPubkey(pubkey) + pub, err := crypto.UnmarshalPubkey(sigdata.PublicKey) if err != nil { return accounts.Account{}, err } @@ -1046,10 +1055,10 @@ func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error return sig, nil } -// determinePublicKey uses a signature and the X component of a public key to -// recover the entire public key. -func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) { - return makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkeyX) +// confirmPublicKey confirms that the given signature belongs to the specified key. +func confirmPublicKey(sig, pubkey []byte) error { + _, err := makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkey) + return err } // makeRecoverableSignature uses a signature and an expected public key to From fb35c54280ab212c1ecf3b214578585730887498 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 067/280] accounts/scwallet: change sc url scheme to keycard (#19632) --- accounts/scwallet/README.md | 20 ++++++++++---------- accounts/scwallet/hub.go | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md index 20519e092d..cfca916b3a 100644 --- a/accounts/scwallet/README.md +++ b/accounts/scwallet/README.md @@ -25,13 +25,13 @@ Start `geth` with the `console` command. You will notice the following warning: ``` - WARN [04-09|16:58:38.898] Failed to open wallet url=pcsc://044def09 err="smartcard: pairing password needed" + WARN [04-09|16:58:38.898] Failed to open wallet url=keycard://044def09 err="smartcard: pairing password needed" ``` - Write down the URL (`pcsc://044def09` in this example). Then ask `geth` to open the wallet: + Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet: ``` - > personal.openWallet("pcsc://044def09") + > personal.openWallet("keycard://044def09") Please enter the pairing password: ``` @@ -42,12 +42,12 @@ ``` > personal - WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=pcsc://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985" + WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=keycard://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985" { listAccounts: [], listWallets: [{ status: "Empty, waiting for initialization", - url: "pcsc://044def09" + url: "keycard://044def09" }], ... } @@ -56,7 +56,7 @@ So the communication with the card is working, but there is no key associated with this wallet. Let's create it: ``` - > personal.initializeWallet("pcsc://044def09") + > personal.initializeWallet("keycard://044def09") "tilt ... impact" ``` @@ -67,10 +67,10 @@ [{ accounts: [{ address: "0x678b7cd55c61917defb23546a41803c5bfefbc7a", - url: "pcsc://044d/m/44'/60'/0'/0/0" + url: "keycard://044d/m/44'/60'/0'/0/0" }], status: "Online", - url: "pcsc://044def09" + url: "keycard://044def09" }] ``` @@ -84,14 +84,14 @@ ``` listWallets: [{ status: "Online, can derive public keys", - url: "pcsc://a4d73015" + url: "keycard://a4d73015" }] ``` 3. Open the wallet, you will be prompted for your pairing password, then PIN: ``` -personal.openWallet("pcsc://a4d73015") +personal.openWallet("keycard://a4d73015") ``` 4. Check that creation was successful by typing e.g. `personal`. Then use it like a regular wallet. diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index 3e07533067..93267984f0 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -49,7 +49,7 @@ import ( ) // Scheme is the URI prefix for smartcard wallets. -const Scheme = "pcsc" +const Scheme = "keycard" // refreshCycle is the maximum time between wallet refreshes (if USB hotplug // notifications don't work). From 100ea1c8e05ee9cc49022e6e6378f32585c0655f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 068/280] accounts/scwallet: add a switch to specify path to sc daemon (#19439) --- cmd/XDC/main.go | 1 + cmd/utils/flags.go | 28 ++++++++++++++++++++++++++++ node/config.go | 46 ++++++++++++++++++++++++++++++++-------------- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index bf09ad27d2..ea6db1d893 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -63,6 +63,7 @@ var ( utils.DataDirFlag, utils.KeyStoreDirFlag, //utils.NoUSBFlag, + utils.SmartCardDaemonPathFlag, //utils.EthashCacheDirFlag, //utils.EthashCachesInMemoryFlag, //utils.EthashCachesOnDiskFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 029cf73242..0b3d9a32b0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -63,6 +63,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/p2p/netutil" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rpc" + pcsclite "github.com/gballet/go-libpcsclite" gopsutil "github.com/shirou/gopsutil/mem" "github.com/urfave/cli/v2" ) @@ -87,6 +88,12 @@ var ( Usage: "Directory for the keystore (default = inside the datadir)", Category: flags.AccountCategory, } + SmartCardDaemonPathFlag = &cli.StringFlag{ + Name: "pcscdpath", + Usage: "Path to the smartcard daemon (pcscd) socket file", + Value: pcsclite.PCSCDSockName, + Category: flags.AccountCategory, + } NetworkIdFlag = &cli.Uint64Flag{ Name: "networkid", Usage: "Network identifier (integer, 89=XDPoSChain)", @@ -1194,6 +1201,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { setWS(ctx, cfg) setNodeUserIdent(ctx, cfg) setPrefix(ctx, cfg) + setSmartCard(ctx, cfg) switch { case ctx.IsSet(DataDirFlag.Name): @@ -1227,6 +1235,26 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { } } +func setSmartCard(ctx *cli.Context, cfg *node.Config) { + // Skip enabling smartcards if no path is set + path := ctx.String(SmartCardDaemonPathFlag.Name) + if path == "" { + return + } + // Sanity check that the smartcard path is valid + fi, err := os.Stat(path) + if err != nil { + log.Info("Smartcard socket not found, disabling", "err", err) + return + } + if fi.Mode()&os.ModeType != os.ModeSocket { + log.Error("Invalid smartcard daemon path", "path", path, "type", fi.Mode().String()) + return + } + // Smartcard daemon path exists and is a socket, enable it + cfg.SmartCardDaemonPath = path +} + func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { // If we are running the light client, apply another group // settings for gas oracle. diff --git a/node/config.go b/node/config.go index 5e11ab7ce6..086053aad8 100644 --- a/node/config.go +++ b/node/config.go @@ -26,6 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts/keystore" + "github.com/XinFinOrg/XDPoSChain/accounts/scwallet" "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -88,6 +89,9 @@ type Config struct { // NoUSB disables hardware wallet monitoring and connectivity. NoUSB bool `toml:",omitempty"` + // SmartCardDaemonPath is the path to the smartcard daemon's socket. + SmartCardDaemonPath string `toml:",omitempty"` + // IPCPath is the requested location to place the IPC endpoint. If the path is // a simple file name, it is placed inside the data directory (or on the root // pipe path on Windows), whereas if it's a resolvable path name (absolute or @@ -425,22 +429,36 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { return nil, "", err } // Assemble the account manager and supported backends - backends := []accounts.Backend{ - keystore.NewKeyStore(keydir, scryptN, scryptP), - } - if !conf.NoUSB { - // Start a USB hub for Ledger hardware wallets - if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { - log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) - } else { - backends = append(backends, ledgerhub) + var backends []accounts.Backend + if len(backends) == 0 { + // For now, we're using EITHER external signer OR local signers. + // If/when we implement some form of lockfile for USB and keystore wallets, + // we can have both, but it's very confusing for the user to see the same + // accounts in both externally and locally, plus very racey. + backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP)) + if !conf.NoUSB { + // Start a USB hub for Ledger hardware wallets + if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) + } else { + backends = append(backends, ledgerhub) + } + // Start a USB hub for Trezor hardware wallets + if trezorhub, err := usbwallet.NewTrezorHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + } } - // Start a USB hub for Trezor hardware wallets - if trezorhub, err := usbwallet.NewTrezorHub(); err != nil { - log.Warn(fmt.Sprintf("Failed to start Trezor hub, disabling: %v", err)) - } else { - backends = append(backends, trezorhub) + if len(conf.SmartCardDaemonPath) > 0 { + // Start a smart card hub + if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + backends = append(backends, schub) + } } } + return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil } From 2e21b9610145a3f070423813e55c499ad1e5d49a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 069/280] accounts/usbwallet: add webusb trezor support (#19588) --- accounts/usbwallet/hub.go | 30 +- accounts/usbwallet/trezor.go | 13 +- .../usbwallet/trezor/messages-common.pb.go | 811 ++++ .../usbwallet/trezor/messages-common.proto | 147 + .../usbwallet/trezor/messages-ethereum.pb.go | 698 +++ .../usbwallet/trezor/messages-ethereum.proto | 131 + .../trezor/messages-management.pb.go | 1621 +++++++ .../trezor/messages-management.proto | 289 ++ accounts/usbwallet/trezor/messages.pb.go | 3782 ++++------------- accounts/usbwallet/trezor/messages.proto | 1131 ++--- accounts/usbwallet/trezor/trezor.go | 32 +- accounts/usbwallet/trezor/types.pb.go | 1333 ------ accounts/usbwallet/trezor/types.proto | 278 -- accounts/usbwallet/wallet.go | 6 +- go.mod | 2 +- go.sum | 4 +- node/config.go | 12 +- 17 files changed, 4814 insertions(+), 5506 deletions(-) create mode 100644 accounts/usbwallet/trezor/messages-common.pb.go create mode 100644 accounts/usbwallet/trezor/messages-common.proto create mode 100644 accounts/usbwallet/trezor/messages-ethereum.pb.go create mode 100644 accounts/usbwallet/trezor/messages-ethereum.proto create mode 100644 accounts/usbwallet/trezor/messages-management.pb.go create mode 100644 accounts/usbwallet/trezor/messages-management.proto delete mode 100644 accounts/usbwallet/trezor/types.pb.go delete mode 100644 accounts/usbwallet/trezor/types.proto diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index b409f19a07..f2656bdf47 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -25,7 +25,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/karalabe/hid" + "github.com/karalabe/usb" ) // LedgerScheme is the protocol scheme prefixing account and wallet URLs. @@ -84,14 +84,20 @@ func NewLedgerHub() (*Hub, error) { }, 0xffa0, 0, newLedgerDriver) } -// NewTrezorHub creates a new hardware wallet manager for Trezor devices. -func NewTrezorHub() (*Hub, error) { - return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor 1 */}, 0xff00, 0, newTrezorDriver) +// NewTrezorHubWithHID creates a new hardware wallet manager for Trezor devices. +func NewTrezorHubWithHID() (*Hub, error) { + return newHub(TrezorScheme, 0x534c, []uint16{0x0001 /* Trezor HID */}, 0xff00, 0, newTrezorDriver) +} + +// NewTrezorHubWithWebUSB creates a new hardware wallet manager for Trezor devices with +// firmware version > 1.8.0 +func NewTrezorHubWithWebUSB() (*Hub, error) { + return newHub(TrezorScheme, 0x1209, []uint16{0x53c1 /* Trezor WebUSB */}, 0xffff /* No usage id on webusb, don't match unset (0) */, 0, newTrezorDriver) } // newHub creates a new hardware wallet manager for generic USB devices. func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) { - if !hid.Supported() { + if !usb.Supported() { return nil, errors.New("unsupported platform") } hub := &Hub{ @@ -133,7 +139,7 @@ func (hub *Hub) refreshWallets() { return } // Retrieve the current list of USB wallet devices - var devices []hid.DeviceInfo + var devices []usb.DeviceInfo if runtime.GOOS == "linux" { // hidapi on Linux opens the device during enumeration to retrieve some infos, @@ -148,8 +154,18 @@ func (hub *Hub) refreshWallets() { return } } - for _, info := range hid.Enumerate(hub.vendorID, 0) { + infos, err := usb.Enumerate(hub.vendorID, 0) + if err != nil { + if runtime.GOOS == "linux" { + // See rationale before the enumeration why this is needed and only on Linux. + hub.commsLock.Unlock() + } + log.Error("error enumerating USB enumeration: ", "code", err) + return + } + for _, info := range infos { for _, id := range hub.productIDs { + // Windows and Macos use UsageID matching, Linux uses Interface matching if info.ProductID == id && (info.UsagePage == hub.usageID || info.Interface == hub.endpointID) { devices = append(devices, info) break diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index b64db3863f..cfc44fbba3 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -193,7 +193,13 @@ func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, er if _, err := w.trezorExchange(&trezor.EthereumGetAddress{AddressN: derivationPath}, address); err != nil { return common.Address{}, err } - return common.BytesToAddress(address.GetAddress()), nil + if addr := address.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary fomats + return common.BytesToAddress(addr), nil + } + if addr := address.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal fomats + return common.HexToAddress(addr), nil + } + return common.Address{}, errors.New("missing derived address") } // trezorSign sends the transaction to the Trezor wallet, and waits for the user @@ -212,7 +218,10 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction DataLength: &length, } if to := tx.To(); to != nil { - request.To = (*to)[:] // Non contract deploy, set recipient explicitly + // Non contract deploy, set recipient explicitly + hex := to.Hex() + request.ToHex = &hex // Newer firmwares (old will ignore) + request.ToBin = (*to)[:] // Older firmwares (new will ignore) } if length > 1024 { // Send the data chunked if that was requested request.DataInitialChunk, data = data[:1024], data[1024:] diff --git a/accounts/usbwallet/trezor/messages-common.pb.go b/accounts/usbwallet/trezor/messages-common.pb.go new file mode 100644 index 0000000000..304bec0e36 --- /dev/null +++ b/accounts/usbwallet/trezor/messages-common.pb.go @@ -0,0 +1,811 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-common.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Failure_FailureType int32 + +const ( + Failure_Failure_UnexpectedMessage Failure_FailureType = 1 + Failure_Failure_ButtonExpected Failure_FailureType = 2 + Failure_Failure_DataError Failure_FailureType = 3 + Failure_Failure_ActionCancelled Failure_FailureType = 4 + Failure_Failure_PinExpected Failure_FailureType = 5 + Failure_Failure_PinCancelled Failure_FailureType = 6 + Failure_Failure_PinInvalid Failure_FailureType = 7 + Failure_Failure_InvalidSignature Failure_FailureType = 8 + Failure_Failure_ProcessError Failure_FailureType = 9 + Failure_Failure_NotEnoughFunds Failure_FailureType = 10 + Failure_Failure_NotInitialized Failure_FailureType = 11 + Failure_Failure_PinMismatch Failure_FailureType = 12 + Failure_Failure_FirmwareError Failure_FailureType = 99 +) + +var Failure_FailureType_name = map[int32]string{ + 1: "Failure_UnexpectedMessage", + 2: "Failure_ButtonExpected", + 3: "Failure_DataError", + 4: "Failure_ActionCancelled", + 5: "Failure_PinExpected", + 6: "Failure_PinCancelled", + 7: "Failure_PinInvalid", + 8: "Failure_InvalidSignature", + 9: "Failure_ProcessError", + 10: "Failure_NotEnoughFunds", + 11: "Failure_NotInitialized", + 12: "Failure_PinMismatch", + 99: "Failure_FirmwareError", +} + +var Failure_FailureType_value = map[string]int32{ + "Failure_UnexpectedMessage": 1, + "Failure_ButtonExpected": 2, + "Failure_DataError": 3, + "Failure_ActionCancelled": 4, + "Failure_PinExpected": 5, + "Failure_PinCancelled": 6, + "Failure_PinInvalid": 7, + "Failure_InvalidSignature": 8, + "Failure_ProcessError": 9, + "Failure_NotEnoughFunds": 10, + "Failure_NotInitialized": 11, + "Failure_PinMismatch": 12, + "Failure_FirmwareError": 99, +} + +func (x Failure_FailureType) Enum() *Failure_FailureType { + p := new(Failure_FailureType) + *p = x + return p +} + +func (x Failure_FailureType) String() string { + return proto.EnumName(Failure_FailureType_name, int32(x)) +} + +func (x *Failure_FailureType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Failure_FailureType_value, data, "Failure_FailureType") + if err != nil { + return err + } + *x = Failure_FailureType(value) + return nil +} + +func (Failure_FailureType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{1, 0} +} + +//* +// Type of button request +type ButtonRequest_ButtonRequestType int32 + +const ( + ButtonRequest_ButtonRequest_Other ButtonRequest_ButtonRequestType = 1 + ButtonRequest_ButtonRequest_FeeOverThreshold ButtonRequest_ButtonRequestType = 2 + ButtonRequest_ButtonRequest_ConfirmOutput ButtonRequest_ButtonRequestType = 3 + ButtonRequest_ButtonRequest_ResetDevice ButtonRequest_ButtonRequestType = 4 + ButtonRequest_ButtonRequest_ConfirmWord ButtonRequest_ButtonRequestType = 5 + ButtonRequest_ButtonRequest_WipeDevice ButtonRequest_ButtonRequestType = 6 + ButtonRequest_ButtonRequest_ProtectCall ButtonRequest_ButtonRequestType = 7 + ButtonRequest_ButtonRequest_SignTx ButtonRequest_ButtonRequestType = 8 + ButtonRequest_ButtonRequest_FirmwareCheck ButtonRequest_ButtonRequestType = 9 + ButtonRequest_ButtonRequest_Address ButtonRequest_ButtonRequestType = 10 + ButtonRequest_ButtonRequest_PublicKey ButtonRequest_ButtonRequestType = 11 + ButtonRequest_ButtonRequest_MnemonicWordCount ButtonRequest_ButtonRequestType = 12 + ButtonRequest_ButtonRequest_MnemonicInput ButtonRequest_ButtonRequestType = 13 + ButtonRequest_ButtonRequest_PassphraseType ButtonRequest_ButtonRequestType = 14 + ButtonRequest_ButtonRequest_UnknownDerivationPath ButtonRequest_ButtonRequestType = 15 +) + +var ButtonRequest_ButtonRequestType_name = map[int32]string{ + 1: "ButtonRequest_Other", + 2: "ButtonRequest_FeeOverThreshold", + 3: "ButtonRequest_ConfirmOutput", + 4: "ButtonRequest_ResetDevice", + 5: "ButtonRequest_ConfirmWord", + 6: "ButtonRequest_WipeDevice", + 7: "ButtonRequest_ProtectCall", + 8: "ButtonRequest_SignTx", + 9: "ButtonRequest_FirmwareCheck", + 10: "ButtonRequest_Address", + 11: "ButtonRequest_PublicKey", + 12: "ButtonRequest_MnemonicWordCount", + 13: "ButtonRequest_MnemonicInput", + 14: "ButtonRequest_PassphraseType", + 15: "ButtonRequest_UnknownDerivationPath", +} + +var ButtonRequest_ButtonRequestType_value = map[string]int32{ + "ButtonRequest_Other": 1, + "ButtonRequest_FeeOverThreshold": 2, + "ButtonRequest_ConfirmOutput": 3, + "ButtonRequest_ResetDevice": 4, + "ButtonRequest_ConfirmWord": 5, + "ButtonRequest_WipeDevice": 6, + "ButtonRequest_ProtectCall": 7, + "ButtonRequest_SignTx": 8, + "ButtonRequest_FirmwareCheck": 9, + "ButtonRequest_Address": 10, + "ButtonRequest_PublicKey": 11, + "ButtonRequest_MnemonicWordCount": 12, + "ButtonRequest_MnemonicInput": 13, + "ButtonRequest_PassphraseType": 14, + "ButtonRequest_UnknownDerivationPath": 15, +} + +func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType { + p := new(ButtonRequest_ButtonRequestType) + *p = x + return p +} + +func (x ButtonRequest_ButtonRequestType) String() string { + return proto.EnumName(ButtonRequest_ButtonRequestType_name, int32(x)) +} + +func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ButtonRequest_ButtonRequestType_value, data, "ButtonRequest_ButtonRequestType") + if err != nil { + return err + } + *x = ButtonRequest_ButtonRequestType(value) + return nil +} + +func (ButtonRequest_ButtonRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{2, 0} +} + +//* +// Type of PIN request +type PinMatrixRequest_PinMatrixRequestType int32 + +const ( + PinMatrixRequest_PinMatrixRequestType_Current PinMatrixRequest_PinMatrixRequestType = 1 + PinMatrixRequest_PinMatrixRequestType_NewFirst PinMatrixRequest_PinMatrixRequestType = 2 + PinMatrixRequest_PinMatrixRequestType_NewSecond PinMatrixRequest_PinMatrixRequestType = 3 +) + +var PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ + 1: "PinMatrixRequestType_Current", + 2: "PinMatrixRequestType_NewFirst", + 3: "PinMatrixRequestType_NewSecond", +} + +var PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ + "PinMatrixRequestType_Current": 1, + "PinMatrixRequestType_NewFirst": 2, + "PinMatrixRequestType_NewSecond": 3, +} + +func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatrixRequestType { + p := new(PinMatrixRequest_PinMatrixRequestType) + *p = x + return p +} + +func (x PinMatrixRequest_PinMatrixRequestType) String() string { + return proto.EnumName(PinMatrixRequest_PinMatrixRequestType_name, int32(x)) +} + +func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(PinMatrixRequest_PinMatrixRequestType_value, data, "PinMatrixRequest_PinMatrixRequestType") + if err != nil { + return err + } + *x = PinMatrixRequest_PinMatrixRequestType(value) + return nil +} + +func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{4, 0} +} + +//* +// Response: Success of the previous request +// @end +type Success struct { + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Success) Reset() { *m = Success{} } +func (m *Success) String() string { return proto.CompactTextString(m) } +func (*Success) ProtoMessage() {} +func (*Success) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{0} +} + +func (m *Success) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Success.Unmarshal(m, b) +} +func (m *Success) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Success.Marshal(b, m, deterministic) +} +func (m *Success) XXX_Merge(src proto.Message) { + xxx_messageInfo_Success.Merge(m, src) +} +func (m *Success) XXX_Size() int { + return xxx_messageInfo_Success.Size(m) +} +func (m *Success) XXX_DiscardUnknown() { + xxx_messageInfo_Success.DiscardUnknown(m) +} + +var xxx_messageInfo_Success proto.InternalMessageInfo + +func (m *Success) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +//* +// Response: Failure of the previous request +// @end +type Failure struct { + Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` + Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Failure) Reset() { *m = Failure{} } +func (m *Failure) String() string { return proto.CompactTextString(m) } +func (*Failure) ProtoMessage() {} +func (*Failure) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{1} +} + +func (m *Failure) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Failure.Unmarshal(m, b) +} +func (m *Failure) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Failure.Marshal(b, m, deterministic) +} +func (m *Failure) XXX_Merge(src proto.Message) { + xxx_messageInfo_Failure.Merge(m, src) +} +func (m *Failure) XXX_Size() int { + return xxx_messageInfo_Failure.Size(m) +} +func (m *Failure) XXX_DiscardUnknown() { + xxx_messageInfo_Failure.DiscardUnknown(m) +} + +var xxx_messageInfo_Failure proto.InternalMessageInfo + +func (m *Failure) GetCode() Failure_FailureType { + if m != nil && m.Code != nil { + return *m.Code + } + return Failure_Failure_UnexpectedMessage +} + +func (m *Failure) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +//* +// Response: Device is waiting for HW button press. +// @auxstart +// @next ButtonAck +type ButtonRequest struct { + Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` + Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } +func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } +func (*ButtonRequest) ProtoMessage() {} +func (*ButtonRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{2} +} + +func (m *ButtonRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ButtonRequest.Unmarshal(m, b) +} +func (m *ButtonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ButtonRequest.Marshal(b, m, deterministic) +} +func (m *ButtonRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ButtonRequest.Merge(m, src) +} +func (m *ButtonRequest) XXX_Size() int { + return xxx_messageInfo_ButtonRequest.Size(m) +} +func (m *ButtonRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ButtonRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ButtonRequest proto.InternalMessageInfo + +func (m *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { + if m != nil && m.Code != nil { + return *m.Code + } + return ButtonRequest_ButtonRequest_Other +} + +func (m *ButtonRequest) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +//* +// Request: Computer agrees to wait for HW button press +// @auxend +type ButtonAck struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ButtonAck) Reset() { *m = ButtonAck{} } +func (m *ButtonAck) String() string { return proto.CompactTextString(m) } +func (*ButtonAck) ProtoMessage() {} +func (*ButtonAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{3} +} + +func (m *ButtonAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ButtonAck.Unmarshal(m, b) +} +func (m *ButtonAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ButtonAck.Marshal(b, m, deterministic) +} +func (m *ButtonAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_ButtonAck.Merge(m, src) +} +func (m *ButtonAck) XXX_Size() int { + return xxx_messageInfo_ButtonAck.Size(m) +} +func (m *ButtonAck) XXX_DiscardUnknown() { + xxx_messageInfo_ButtonAck.DiscardUnknown(m) +} + +var xxx_messageInfo_ButtonAck proto.InternalMessageInfo + +//* +// Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme +// @auxstart +// @next PinMatrixAck +type PinMatrixRequest struct { + Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } +func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } +func (*PinMatrixRequest) ProtoMessage() {} +func (*PinMatrixRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{4} +} + +func (m *PinMatrixRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PinMatrixRequest.Unmarshal(m, b) +} +func (m *PinMatrixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PinMatrixRequest.Marshal(b, m, deterministic) +} +func (m *PinMatrixRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PinMatrixRequest.Merge(m, src) +} +func (m *PinMatrixRequest) XXX_Size() int { + return xxx_messageInfo_PinMatrixRequest.Size(m) +} +func (m *PinMatrixRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PinMatrixRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PinMatrixRequest proto.InternalMessageInfo + +func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { + if m != nil && m.Type != nil { + return *m.Type + } + return PinMatrixRequest_PinMatrixRequestType_Current +} + +//* +// Request: Computer responds with encoded PIN +// @auxend +type PinMatrixAck struct { + Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } +func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } +func (*PinMatrixAck) ProtoMessage() {} +func (*PinMatrixAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{5} +} + +func (m *PinMatrixAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PinMatrixAck.Unmarshal(m, b) +} +func (m *PinMatrixAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PinMatrixAck.Marshal(b, m, deterministic) +} +func (m *PinMatrixAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PinMatrixAck.Merge(m, src) +} +func (m *PinMatrixAck) XXX_Size() int { + return xxx_messageInfo_PinMatrixAck.Size(m) +} +func (m *PinMatrixAck) XXX_DiscardUnknown() { + xxx_messageInfo_PinMatrixAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PinMatrixAck proto.InternalMessageInfo + +func (m *PinMatrixAck) GetPin() string { + if m != nil && m.Pin != nil { + return *m.Pin + } + return "" +} + +//* +// Response: Device awaits encryption passphrase +// @auxstart +// @next PassphraseAck +type PassphraseRequest struct { + OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } +func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } +func (*PassphraseRequest) ProtoMessage() {} +func (*PassphraseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{6} +} + +func (m *PassphraseRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseRequest.Unmarshal(m, b) +} +func (m *PassphraseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseRequest.Marshal(b, m, deterministic) +} +func (m *PassphraseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseRequest.Merge(m, src) +} +func (m *PassphraseRequest) XXX_Size() int { + return xxx_messageInfo_PassphraseRequest.Size(m) +} +func (m *PassphraseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseRequest proto.InternalMessageInfo + +func (m *PassphraseRequest) GetOnDevice() bool { + if m != nil && m.OnDevice != nil { + return *m.OnDevice + } + return false +} + +//* +// Request: Send passphrase back +// @next PassphraseStateRequest +type PassphraseAck struct { + Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } +func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } +func (*PassphraseAck) ProtoMessage() {} +func (*PassphraseAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{7} +} + +func (m *PassphraseAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseAck.Unmarshal(m, b) +} +func (m *PassphraseAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseAck.Marshal(b, m, deterministic) +} +func (m *PassphraseAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseAck.Merge(m, src) +} +func (m *PassphraseAck) XXX_Size() int { + return xxx_messageInfo_PassphraseAck.Size(m) +} +func (m *PassphraseAck) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseAck proto.InternalMessageInfo + +func (m *PassphraseAck) GetPassphrase() string { + if m != nil && m.Passphrase != nil { + return *m.Passphrase + } + return "" +} + +func (m *PassphraseAck) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +//* +// Response: Device awaits passphrase state +// @next PassphraseStateAck +type PassphraseStateRequest struct { + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseStateRequest) Reset() { *m = PassphraseStateRequest{} } +func (m *PassphraseStateRequest) String() string { return proto.CompactTextString(m) } +func (*PassphraseStateRequest) ProtoMessage() {} +func (*PassphraseStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{8} +} + +func (m *PassphraseStateRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseStateRequest.Unmarshal(m, b) +} +func (m *PassphraseStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseStateRequest.Marshal(b, m, deterministic) +} +func (m *PassphraseStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseStateRequest.Merge(m, src) +} +func (m *PassphraseStateRequest) XXX_Size() int { + return xxx_messageInfo_PassphraseStateRequest.Size(m) +} +func (m *PassphraseStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseStateRequest proto.InternalMessageInfo + +func (m *PassphraseStateRequest) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +//* +// Request: Send passphrase state back +// @auxend +type PassphraseStateAck struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PassphraseStateAck) Reset() { *m = PassphraseStateAck{} } +func (m *PassphraseStateAck) String() string { return proto.CompactTextString(m) } +func (*PassphraseStateAck) ProtoMessage() {} +func (*PassphraseStateAck) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{9} +} + +func (m *PassphraseStateAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PassphraseStateAck.Unmarshal(m, b) +} +func (m *PassphraseStateAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PassphraseStateAck.Marshal(b, m, deterministic) +} +func (m *PassphraseStateAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_PassphraseStateAck.Merge(m, src) +} +func (m *PassphraseStateAck) XXX_Size() int { + return xxx_messageInfo_PassphraseStateAck.Size(m) +} +func (m *PassphraseStateAck) XXX_DiscardUnknown() { + xxx_messageInfo_PassphraseStateAck.DiscardUnknown(m) +} + +var xxx_messageInfo_PassphraseStateAck proto.InternalMessageInfo + +//* +// Structure representing BIP32 (hierarchical deterministic) node +// Used for imports of private key into the device and exporting public key out of device +// @embed +type HDNodeType struct { + Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` + Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` + ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` + ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` + PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` + PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HDNodeType) Reset() { *m = HDNodeType{} } +func (m *HDNodeType) String() string { return proto.CompactTextString(m) } +func (*HDNodeType) ProtoMessage() {} +func (*HDNodeType) Descriptor() ([]byte, []int) { + return fileDescriptor_aaf30d059fdbc38d, []int{10} +} + +func (m *HDNodeType) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HDNodeType.Unmarshal(m, b) +} +func (m *HDNodeType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HDNodeType.Marshal(b, m, deterministic) +} +func (m *HDNodeType) XXX_Merge(src proto.Message) { + xxx_messageInfo_HDNodeType.Merge(m, src) +} +func (m *HDNodeType) XXX_Size() int { + return xxx_messageInfo_HDNodeType.Size(m) +} +func (m *HDNodeType) XXX_DiscardUnknown() { + xxx_messageInfo_HDNodeType.DiscardUnknown(m) +} + +var xxx_messageInfo_HDNodeType proto.InternalMessageInfo + +func (m *HDNodeType) GetDepth() uint32 { + if m != nil && m.Depth != nil { + return *m.Depth + } + return 0 +} + +func (m *HDNodeType) GetFingerprint() uint32 { + if m != nil && m.Fingerprint != nil { + return *m.Fingerprint + } + return 0 +} + +func (m *HDNodeType) GetChildNum() uint32 { + if m != nil && m.ChildNum != nil { + return *m.ChildNum + } + return 0 +} + +func (m *HDNodeType) GetChainCode() []byte { + if m != nil { + return m.ChainCode + } + return nil +} + +func (m *HDNodeType) GetPrivateKey() []byte { + if m != nil { + return m.PrivateKey + } + return nil +} + +func (m *HDNodeType) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func init() { + proto.RegisterEnum("hw.trezor.messages.common.Failure_FailureType", Failure_FailureType_name, Failure_FailureType_value) + proto.RegisterEnum("hw.trezor.messages.common.ButtonRequest_ButtonRequestType", ButtonRequest_ButtonRequestType_name, ButtonRequest_ButtonRequestType_value) + proto.RegisterEnum("hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType", PinMatrixRequest_PinMatrixRequestType_name, PinMatrixRequest_PinMatrixRequestType_value) + proto.RegisterType((*Success)(nil), "hw.trezor.messages.common.Success") + proto.RegisterType((*Failure)(nil), "hw.trezor.messages.common.Failure") + proto.RegisterType((*ButtonRequest)(nil), "hw.trezor.messages.common.ButtonRequest") + proto.RegisterType((*ButtonAck)(nil), "hw.trezor.messages.common.ButtonAck") + proto.RegisterType((*PinMatrixRequest)(nil), "hw.trezor.messages.common.PinMatrixRequest") + proto.RegisterType((*PinMatrixAck)(nil), "hw.trezor.messages.common.PinMatrixAck") + proto.RegisterType((*PassphraseRequest)(nil), "hw.trezor.messages.common.PassphraseRequest") + proto.RegisterType((*PassphraseAck)(nil), "hw.trezor.messages.common.PassphraseAck") + proto.RegisterType((*PassphraseStateRequest)(nil), "hw.trezor.messages.common.PassphraseStateRequest") + proto.RegisterType((*PassphraseStateAck)(nil), "hw.trezor.messages.common.PassphraseStateAck") + proto.RegisterType((*HDNodeType)(nil), "hw.trezor.messages.common.HDNodeType") +} + +func init() { proto.RegisterFile("messages-common.proto", fileDescriptor_aaf30d059fdbc38d) } + +var fileDescriptor_aaf30d059fdbc38d = []byte{ + // 846 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x52, 0x23, 0x37, + 0x10, 0x2e, 0xff, 0x80, 0xed, 0xb6, 0xd9, 0x08, 0xc5, 0x80, 0x09, 0xb0, 0x38, 0xc3, 0x21, 0x5c, + 0xe2, 0x4a, 0xe5, 0x98, 0x53, 0x58, 0x83, 0x2b, 0xd4, 0x16, 0x86, 0x1a, 0xd8, 0xda, 0xa3, 0x4b, + 0xd1, 0xf4, 0x32, 0x2a, 0xcf, 0x48, 0x13, 0x8d, 0x06, 0xf0, 0x5e, 0xf2, 0x6a, 0x79, 0x89, 0xbc, + 0x42, 0xaa, 0x52, 0xb9, 0xe4, 0x11, 0xb6, 0x34, 0x3f, 0x78, 0xc6, 0x66, 0x39, 0xcd, 0xe8, 0xfb, + 0xbe, 0xee, 0x96, 0xba, 0x3f, 0x09, 0x76, 0x42, 0x8c, 0x63, 0x76, 0x8f, 0xf1, 0x8f, 0x5c, 0x85, + 0xa1, 0x92, 0xa3, 0x48, 0x2b, 0xa3, 0xe8, 0xbe, 0xff, 0x38, 0x32, 0x1a, 0x3f, 0x2b, 0x3d, 0x2a, + 0x04, 0xa3, 0x4c, 0xe0, 0x9c, 0x40, 0xeb, 0x36, 0xe1, 0x1c, 0xe3, 0x98, 0x0e, 0xa0, 0x95, 0xb3, + 0x83, 0xda, 0xb0, 0x76, 0xda, 0x71, 0x8b, 0xa5, 0xf3, 0x77, 0x03, 0x5a, 0x13, 0x26, 0x82, 0x44, + 0x23, 0x7d, 0x07, 0x4d, 0xae, 0xbc, 0x4c, 0xf2, 0xe6, 0xe7, 0xd1, 0xe8, 0xab, 0xa9, 0x47, 0x79, + 0x44, 0xf1, 0xbd, 0x5b, 0x44, 0xe8, 0xa6, 0xb1, 0xe5, 0x4a, 0xf5, 0x6a, 0xa5, 0xff, 0xea, 0xd0, + 0x2d, 0xe9, 0xe9, 0x11, 0xec, 0xe7, 0xcb, 0xd9, 0x07, 0x89, 0x4f, 0x11, 0x72, 0x83, 0xde, 0x55, + 0x26, 0x26, 0x35, 0xfa, 0x1d, 0xec, 0x16, 0xf4, 0xbb, 0xc4, 0x18, 0x25, 0x2f, 0x72, 0x09, 0xa9, + 0xd3, 0x1d, 0xd8, 0x2e, 0xb8, 0x73, 0x66, 0xd8, 0x85, 0xd6, 0x4a, 0x93, 0x06, 0x3d, 0x80, 0xbd, + 0x02, 0x3e, 0xe3, 0x46, 0x28, 0x39, 0x66, 0x92, 0x63, 0x10, 0xa0, 0x47, 0x9a, 0x74, 0x0f, 0xbe, + 0x2d, 0xc8, 0x1b, 0xb1, 0x4c, 0xb6, 0x41, 0x07, 0xd0, 0x2f, 0x11, 0xcb, 0x90, 0x4d, 0xba, 0x0b, + 0xb4, 0xc4, 0x5c, 0xca, 0x07, 0x16, 0x08, 0x8f, 0xb4, 0xe8, 0x21, 0x0c, 0x0a, 0x3c, 0x07, 0x6f, + 0xc5, 0xbd, 0x64, 0x26, 0xd1, 0x48, 0xda, 0x95, 0x7c, 0x5a, 0xd9, 0xf6, 0x67, 0xfb, 0xeb, 0x94, + 0x8f, 0x34, 0x55, 0xe6, 0x42, 0xaa, 0xe4, 0xde, 0x9f, 0x24, 0xd2, 0x8b, 0x09, 0xac, 0x70, 0x97, + 0x52, 0x18, 0xc1, 0x02, 0xf1, 0x19, 0x3d, 0xd2, 0x5d, 0xd9, 0xfa, 0x95, 0x88, 0x43, 0x66, 0xb8, + 0x4f, 0x7a, 0x74, 0x1f, 0x76, 0x0a, 0x62, 0x22, 0x74, 0xf8, 0xc8, 0x34, 0x66, 0xb5, 0xb8, 0xf3, + 0x4f, 0x13, 0xb6, 0xb2, 0xbe, 0xb9, 0xf8, 0x47, 0x82, 0xb1, 0xa1, 0xd3, 0xca, 0x74, 0x7f, 0x79, + 0x65, 0xba, 0x95, 0xb8, 0xea, 0xaa, 0x34, 0x69, 0x0a, 0x4d, 0x8f, 0x19, 0x96, 0x8f, 0x39, 0xfd, + 0x77, 0xfe, 0x6f, 0xc0, 0xf6, 0x9a, 0xde, 0xee, 0xbf, 0x02, 0xce, 0xae, 0x8d, 0x8f, 0x9a, 0xd4, + 0xa8, 0x03, 0x6f, 0xab, 0xc4, 0x04, 0xf1, 0xfa, 0x01, 0xf5, 0x9d, 0xaf, 0x31, 0xf6, 0x55, 0x60, + 0x67, 0x7d, 0x0c, 0x07, 0x55, 0xcd, 0x58, 0xc9, 0x4f, 0x42, 0x87, 0xd7, 0x89, 0x89, 0x12, 0x43, + 0x1a, 0xd6, 0x47, 0x55, 0x81, 0x8b, 0x31, 0x9a, 0x73, 0x7c, 0x10, 0x1c, 0x49, 0x73, 0x9d, 0xce, + 0xe3, 0x3f, 0x2a, 0x6d, 0xa7, 0x7f, 0x08, 0x83, 0x2a, 0xfd, 0x51, 0x44, 0x98, 0x07, 0x6f, 0xae, + 0x07, 0xdf, 0x68, 0x65, 0x90, 0x9b, 0x31, 0x0b, 0x02, 0xd2, 0xb2, 0xa3, 0xae, 0xd2, 0xd6, 0x07, + 0x77, 0x4f, 0xa4, 0xbd, 0xbe, 0xeb, 0x62, 0x3e, 0x63, 0x1f, 0xf9, 0x9c, 0x74, 0xec, 0xe8, 0xaa, + 0x82, 0x33, 0xcf, 0xd3, 0x18, 0x5b, 0x2b, 0x1c, 0xc0, 0xde, 0x4a, 0xd1, 0xe4, 0xf7, 0x40, 0xf0, + 0xf7, 0xb8, 0x20, 0x5d, 0x7a, 0x02, 0xc7, 0x55, 0xf2, 0x4a, 0x62, 0xa8, 0xa4, 0xe0, 0xf6, 0x3c, + 0x63, 0x95, 0x48, 0x43, 0x7a, 0xeb, 0xd5, 0x0b, 0xd1, 0xa5, 0xb4, 0x3d, 0xdb, 0xa2, 0x43, 0x38, + 0x5c, 0x29, 0xc1, 0xe2, 0x38, 0xf2, 0x35, 0x8b, 0xd3, 0xbb, 0x49, 0xde, 0xd0, 0x1f, 0xe0, 0xa4, + 0xaa, 0xf8, 0x20, 0xe7, 0x52, 0x3d, 0xca, 0x73, 0xd4, 0xe2, 0x81, 0xd9, 0xcb, 0x75, 0xc3, 0x8c, + 0x4f, 0xbe, 0x71, 0xba, 0xd0, 0xc9, 0x84, 0x67, 0x7c, 0xee, 0xfc, 0x5b, 0x03, 0x62, 0x2d, 0xca, + 0x8c, 0x16, 0x4f, 0x85, 0xf1, 0xee, 0xa0, 0x69, 0x16, 0x51, 0x61, 0xbc, 0x5f, 0x5f, 0x31, 0xde, + 0x6a, 0xe8, 0x1a, 0x90, 0xd9, 0xcf, 0x66, 0x73, 0xfe, 0x84, 0xfe, 0x4b, 0xac, 0x3d, 0xda, 0x4b, + 0xf8, 0x6c, 0x9c, 0x68, 0x8d, 0xd2, 0x90, 0x1a, 0xfd, 0x1e, 0x8e, 0x5e, 0x54, 0x4c, 0xf1, 0x71, + 0x22, 0x74, 0x6c, 0x48, 0xdd, 0x1a, 0xf3, 0x6b, 0x92, 0x5b, 0xe4, 0x4a, 0x7a, 0xa4, 0xe1, 0x0c, + 0xa1, 0xf7, 0xac, 0x39, 0xe3, 0x73, 0x4a, 0xa0, 0x11, 0x09, 0x39, 0xa8, 0x0d, 0xeb, 0xa7, 0x1d, + 0xd7, 0xfe, 0x3a, 0x3f, 0xc1, 0xf6, 0xb2, 0xaf, 0x45, 0x37, 0x0e, 0xa0, 0xa3, 0xe4, 0xcc, 0x4b, + 0x1d, 0x96, 0xb6, 0xa4, 0xed, 0xb6, 0x95, 0xcc, 0x1c, 0xe7, 0x5c, 0xc0, 0xd6, 0x32, 0xc2, 0x26, + 0x7d, 0x0b, 0x10, 0x3d, 0x03, 0xf9, 0xdb, 0x5d, 0x42, 0x68, 0x1f, 0x36, 0x62, 0xc3, 0x4c, 0xf6, + 0xd8, 0xf6, 0xdc, 0x6c, 0xe1, 0x8c, 0x60, 0x77, 0x99, 0xe6, 0xd6, 0x42, 0x45, 0xf5, 0x67, 0x7d, + 0xad, 0xac, 0xef, 0x03, 0x5d, 0xd1, 0xdb, 0x61, 0xfe, 0x55, 0x03, 0xf8, 0xed, 0x7c, 0xaa, 0xbc, + 0xec, 0xbd, 0xee, 0xc3, 0x86, 0x87, 0x91, 0xf1, 0xd3, 0x13, 0x6e, 0xb9, 0xd9, 0x82, 0x0e, 0xa1, + 0xfb, 0x49, 0xc8, 0x7b, 0xd4, 0x91, 0x16, 0xd2, 0x0c, 0xea, 0x29, 0x57, 0x86, 0xec, 0x81, 0xb9, + 0x2f, 0x02, 0x6f, 0x26, 0x93, 0x70, 0xd0, 0x48, 0xf9, 0x76, 0x0a, 0x4c, 0x93, 0x90, 0x1e, 0x01, + 0x70, 0x9f, 0x09, 0x39, 0x4b, 0x9f, 0xa6, 0xe6, 0xb0, 0x7e, 0xda, 0x73, 0x3b, 0x29, 0x32, 0xb6, + 0x6f, 0xcc, 0x31, 0x74, 0xa3, 0xd4, 0x6f, 0x38, 0x9b, 0xe3, 0x62, 0xb0, 0x91, 0x6e, 0x1a, 0x72, + 0xe8, 0x3d, 0x2e, 0x6c, 0x7c, 0x94, 0xde, 0x8e, 0x94, 0xdf, 0x4c, 0xf9, 0x4e, 0x54, 0xdc, 0x97, + 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x7d, 0x20, 0xa6, 0x35, 0x07, 0x00, 0x00, +} diff --git a/accounts/usbwallet/trezor/messages-common.proto b/accounts/usbwallet/trezor/messages-common.proto new file mode 100644 index 0000000000..75a983b0a3 --- /dev/null +++ b/accounts/usbwallet/trezor/messages-common.proto @@ -0,0 +1,147 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.common; + +/** + * Response: Success of the previous request + * @end + */ +message Success { + optional string message = 1; // human readable description of action or request-specific payload +} + +/** + * Response: Failure of the previous request + * @end + */ +message Failure { + optional FailureType code = 1; // computer-readable definition of the error state + optional string message = 2; // human-readable message of the error state + enum FailureType { + Failure_UnexpectedMessage = 1; + Failure_ButtonExpected = 2; + Failure_DataError = 3; + Failure_ActionCancelled = 4; + Failure_PinExpected = 5; + Failure_PinCancelled = 6; + Failure_PinInvalid = 7; + Failure_InvalidSignature = 8; + Failure_ProcessError = 9; + Failure_NotEnoughFunds = 10; + Failure_NotInitialized = 11; + Failure_PinMismatch = 12; + Failure_FirmwareError = 99; + } +} + +/** + * Response: Device is waiting for HW button press. + * @auxstart + * @next ButtonAck + */ +message ButtonRequest { + optional ButtonRequestType code = 1; + optional string data = 2; + /** + * Type of button request + */ + enum ButtonRequestType { + ButtonRequest_Other = 1; + ButtonRequest_FeeOverThreshold = 2; + ButtonRequest_ConfirmOutput = 3; + ButtonRequest_ResetDevice = 4; + ButtonRequest_ConfirmWord = 5; + ButtonRequest_WipeDevice = 6; + ButtonRequest_ProtectCall = 7; + ButtonRequest_SignTx = 8; + ButtonRequest_FirmwareCheck = 9; + ButtonRequest_Address = 10; + ButtonRequest_PublicKey = 11; + ButtonRequest_MnemonicWordCount = 12; + ButtonRequest_MnemonicInput = 13; + ButtonRequest_PassphraseType = 14; + ButtonRequest_UnknownDerivationPath = 15; + } +} + +/** + * Request: Computer agrees to wait for HW button press + * @auxend + */ +message ButtonAck { +} + +/** + * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme + * @auxstart + * @next PinMatrixAck + */ +message PinMatrixRequest { + optional PinMatrixRequestType type = 1; + /** + * Type of PIN request + */ + enum PinMatrixRequestType { + PinMatrixRequestType_Current = 1; + PinMatrixRequestType_NewFirst = 2; + PinMatrixRequestType_NewSecond = 3; + } +} + +/** + * Request: Computer responds with encoded PIN + * @auxend + */ +message PinMatrixAck { + required string pin = 1; // matrix encoded PIN entered by user +} + +/** + * Response: Device awaits encryption passphrase + * @auxstart + * @next PassphraseAck + */ +message PassphraseRequest { + optional bool on_device = 1; // passphrase is being entered on the device +} + +/** + * Request: Send passphrase back + * @next PassphraseStateRequest + */ +message PassphraseAck { + optional string passphrase = 1; + optional bytes state = 2; // expected device state +} + +/** + * Response: Device awaits passphrase state + * @next PassphraseStateAck + */ +message PassphraseStateRequest { + optional bytes state = 1; // actual device state +} + +/** + * Request: Send passphrase state back + * @auxend + */ +message PassphraseStateAck { +} + +/** + * Structure representing BIP32 (hierarchical deterministic) node + * Used for imports of private key into the device and exporting public key out of device + * @embed + */ +message HDNodeType { + required uint32 depth = 1; + required uint32 fingerprint = 2; + required uint32 child_num = 3; + required bytes chain_code = 4; + optional bytes private_key = 5; + optional bytes public_key = 6; +} diff --git a/accounts/usbwallet/trezor/messages-ethereum.pb.go b/accounts/usbwallet/trezor/messages-ethereum.pb.go new file mode 100644 index 0000000000..5d664f5ba4 --- /dev/null +++ b/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -0,0 +1,698 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-ethereum.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Request: Ask device for public key corresponding to address_n path +// @start +// @next EthereumPublicKey +// @next Failure +type EthereumGetPublicKey struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumGetPublicKey) Reset() { *m = EthereumGetPublicKey{} } +func (m *EthereumGetPublicKey) String() string { return proto.CompactTextString(m) } +func (*EthereumGetPublicKey) ProtoMessage() {} +func (*EthereumGetPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{0} +} + +func (m *EthereumGetPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumGetPublicKey.Unmarshal(m, b) +} +func (m *EthereumGetPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumGetPublicKey.Marshal(b, m, deterministic) +} +func (m *EthereumGetPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumGetPublicKey.Merge(m, src) +} +func (m *EthereumGetPublicKey) XXX_Size() int { + return xxx_messageInfo_EthereumGetPublicKey.Size(m) +} +func (m *EthereumGetPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumGetPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumGetPublicKey proto.InternalMessageInfo + +func (m *EthereumGetPublicKey) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumGetPublicKey) GetShowDisplay() bool { + if m != nil && m.ShowDisplay != nil { + return *m.ShowDisplay + } + return false +} + +//* +// Response: Contains public key derived from device private seed +// @end +type EthereumPublicKey struct { + Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` + Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumPublicKey) Reset() { *m = EthereumPublicKey{} } +func (m *EthereumPublicKey) String() string { return proto.CompactTextString(m) } +func (*EthereumPublicKey) ProtoMessage() {} +func (*EthereumPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{1} +} + +func (m *EthereumPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumPublicKey.Unmarshal(m, b) +} +func (m *EthereumPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumPublicKey.Marshal(b, m, deterministic) +} +func (m *EthereumPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumPublicKey.Merge(m, src) +} +func (m *EthereumPublicKey) XXX_Size() int { + return xxx_messageInfo_EthereumPublicKey.Size(m) +} +func (m *EthereumPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumPublicKey proto.InternalMessageInfo + +func (m *EthereumPublicKey) GetNode() *HDNodeType { + if m != nil { + return m.Node + } + return nil +} + +func (m *EthereumPublicKey) GetXpub() string { + if m != nil && m.Xpub != nil { + return *m.Xpub + } + return "" +} + +//* +// Request: Ask device for Ethereum address corresponding to address_n path +// @start +// @next EthereumAddress +// @next Failure +type EthereumGetAddress struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } +func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } +func (*EthereumGetAddress) ProtoMessage() {} +func (*EthereumGetAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{2} +} + +func (m *EthereumGetAddress) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumGetAddress.Unmarshal(m, b) +} +func (m *EthereumGetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumGetAddress.Marshal(b, m, deterministic) +} +func (m *EthereumGetAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumGetAddress.Merge(m, src) +} +func (m *EthereumGetAddress) XXX_Size() int { + return xxx_messageInfo_EthereumGetAddress.Size(m) +} +func (m *EthereumGetAddress) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumGetAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumGetAddress proto.InternalMessageInfo + +func (m *EthereumGetAddress) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumGetAddress) GetShowDisplay() bool { + if m != nil && m.ShowDisplay != nil { + return *m.ShowDisplay + } + return false +} + +//* +// Response: Contains an Ethereum address derived from device private seed +// @end +type EthereumAddress struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } +func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } +func (*EthereumAddress) ProtoMessage() {} +func (*EthereumAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{3} +} + +func (m *EthereumAddress) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumAddress.Unmarshal(m, b) +} +func (m *EthereumAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumAddress.Marshal(b, m, deterministic) +} +func (m *EthereumAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumAddress.Merge(m, src) +} +func (m *EthereumAddress) XXX_Size() int { + return xxx_messageInfo_EthereumAddress.Size(m) +} +func (m *EthereumAddress) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumAddress proto.InternalMessageInfo + +func (m *EthereumAddress) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumAddress) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +//* +// Request: Ask device to sign transaction +// All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. +// Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. +// @start +// @next EthereumTxRequest +// @next Failure +type EthereumSignTx struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` + GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` + GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` + ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` + ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` + Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` + DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` + DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` + ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` + TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } +func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } +func (*EthereumSignTx) ProtoMessage() {} +func (*EthereumSignTx) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{4} +} + +func (m *EthereumSignTx) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumSignTx.Unmarshal(m, b) +} +func (m *EthereumSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumSignTx.Marshal(b, m, deterministic) +} +func (m *EthereumSignTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumSignTx.Merge(m, src) +} +func (m *EthereumSignTx) XXX_Size() int { + return xxx_messageInfo_EthereumSignTx.Size(m) +} +func (m *EthereumSignTx) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumSignTx.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumSignTx proto.InternalMessageInfo + +func (m *EthereumSignTx) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumSignTx) GetNonce() []byte { + if m != nil { + return m.Nonce + } + return nil +} + +func (m *EthereumSignTx) GetGasPrice() []byte { + if m != nil { + return m.GasPrice + } + return nil +} + +func (m *EthereumSignTx) GetGasLimit() []byte { + if m != nil { + return m.GasLimit + } + return nil +} + +func (m *EthereumSignTx) GetToBin() []byte { + if m != nil { + return m.ToBin + } + return nil +} + +func (m *EthereumSignTx) GetToHex() string { + if m != nil && m.ToHex != nil { + return *m.ToHex + } + return "" +} + +func (m *EthereumSignTx) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *EthereumSignTx) GetDataInitialChunk() []byte { + if m != nil { + return m.DataInitialChunk + } + return nil +} + +func (m *EthereumSignTx) GetDataLength() uint32 { + if m != nil && m.DataLength != nil { + return *m.DataLength + } + return 0 +} + +func (m *EthereumSignTx) GetChainId() uint32 { + if m != nil && m.ChainId != nil { + return *m.ChainId + } + return 0 +} + +func (m *EthereumSignTx) GetTxType() uint32 { + if m != nil && m.TxType != nil { + return *m.TxType + } + return 0 +} + +//* +// Response: Device asks for more data from transaction payload, or returns the signature. +// If data_length is set, device awaits that many more bytes of payload. +// Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. +// @end +// @next EthereumTxAck +type EthereumTxRequest struct { + DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` + SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` + SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` + SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } +func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } +func (*EthereumTxRequest) ProtoMessage() {} +func (*EthereumTxRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{5} +} + +func (m *EthereumTxRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumTxRequest.Unmarshal(m, b) +} +func (m *EthereumTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumTxRequest.Marshal(b, m, deterministic) +} +func (m *EthereumTxRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumTxRequest.Merge(m, src) +} +func (m *EthereumTxRequest) XXX_Size() int { + return xxx_messageInfo_EthereumTxRequest.Size(m) +} +func (m *EthereumTxRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumTxRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumTxRequest proto.InternalMessageInfo + +func (m *EthereumTxRequest) GetDataLength() uint32 { + if m != nil && m.DataLength != nil { + return *m.DataLength + } + return 0 +} + +func (m *EthereumTxRequest) GetSignatureV() uint32 { + if m != nil && m.SignatureV != nil { + return *m.SignatureV + } + return 0 +} + +func (m *EthereumTxRequest) GetSignatureR() []byte { + if m != nil { + return m.SignatureR + } + return nil +} + +func (m *EthereumTxRequest) GetSignatureS() []byte { + if m != nil { + return m.SignatureS + } + return nil +} + +//* +// Request: Transaction payload data. +// @next EthereumTxRequest +type EthereumTxAck struct { + DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } +func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } +func (*EthereumTxAck) ProtoMessage() {} +func (*EthereumTxAck) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{6} +} + +func (m *EthereumTxAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumTxAck.Unmarshal(m, b) +} +func (m *EthereumTxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumTxAck.Marshal(b, m, deterministic) +} +func (m *EthereumTxAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumTxAck.Merge(m, src) +} +func (m *EthereumTxAck) XXX_Size() int { + return xxx_messageInfo_EthereumTxAck.Size(m) +} +func (m *EthereumTxAck) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumTxAck.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumTxAck proto.InternalMessageInfo + +func (m *EthereumTxAck) GetDataChunk() []byte { + if m != nil { + return m.DataChunk + } + return nil +} + +//* +// Request: Ask device to sign message +// @start +// @next EthereumMessageSignature +// @next Failure +type EthereumSignMessage struct { + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` + Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } +func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } +func (*EthereumSignMessage) ProtoMessage() {} +func (*EthereumSignMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{7} +} + +func (m *EthereumSignMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumSignMessage.Unmarshal(m, b) +} +func (m *EthereumSignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumSignMessage.Marshal(b, m, deterministic) +} +func (m *EthereumSignMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumSignMessage.Merge(m, src) +} +func (m *EthereumSignMessage) XXX_Size() int { + return xxx_messageInfo_EthereumSignMessage.Size(m) +} +func (m *EthereumSignMessage) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumSignMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumSignMessage proto.InternalMessageInfo + +func (m *EthereumSignMessage) GetAddressN() []uint32 { + if m != nil { + return m.AddressN + } + return nil +} + +func (m *EthereumSignMessage) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +//* +// Response: Signed message +// @end +type EthereumMessageSignature struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } +func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } +func (*EthereumMessageSignature) ProtoMessage() {} +func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{8} +} + +func (m *EthereumMessageSignature) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumMessageSignature.Unmarshal(m, b) +} +func (m *EthereumMessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumMessageSignature.Marshal(b, m, deterministic) +} +func (m *EthereumMessageSignature) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumMessageSignature.Merge(m, src) +} +func (m *EthereumMessageSignature) XXX_Size() int { + return xxx_messageInfo_EthereumMessageSignature.Size(m) +} +func (m *EthereumMessageSignature) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumMessageSignature.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumMessageSignature proto.InternalMessageInfo + +func (m *EthereumMessageSignature) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumMessageSignature) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *EthereumMessageSignature) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +//* +// Request: Ask device to verify message +// @start +// @next Success +// @next Failure +type EthereumVerifyMessage struct { + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` + AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } +func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } +func (*EthereumVerifyMessage) ProtoMessage() {} +func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_cb33f46ba915f15c, []int{9} +} + +func (m *EthereumVerifyMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EthereumVerifyMessage.Unmarshal(m, b) +} +func (m *EthereumVerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EthereumVerifyMessage.Marshal(b, m, deterministic) +} +func (m *EthereumVerifyMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_EthereumVerifyMessage.Merge(m, src) +} +func (m *EthereumVerifyMessage) XXX_Size() int { + return xxx_messageInfo_EthereumVerifyMessage.Size(m) +} +func (m *EthereumVerifyMessage) XXX_DiscardUnknown() { + xxx_messageInfo_EthereumVerifyMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_EthereumVerifyMessage proto.InternalMessageInfo + +func (m *EthereumVerifyMessage) GetAddressBin() []byte { + if m != nil { + return m.AddressBin + } + return nil +} + +func (m *EthereumVerifyMessage) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *EthereumVerifyMessage) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (m *EthereumVerifyMessage) GetAddressHex() string { + if m != nil && m.AddressHex != nil { + return *m.AddressHex + } + return "" +} + +func init() { + proto.RegisterType((*EthereumGetPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumGetPublicKey") + proto.RegisterType((*EthereumPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumPublicKey") + proto.RegisterType((*EthereumGetAddress)(nil), "hw.trezor.messages.ethereum.EthereumGetAddress") + proto.RegisterType((*EthereumAddress)(nil), "hw.trezor.messages.ethereum.EthereumAddress") + proto.RegisterType((*EthereumSignTx)(nil), "hw.trezor.messages.ethereum.EthereumSignTx") + proto.RegisterType((*EthereumTxRequest)(nil), "hw.trezor.messages.ethereum.EthereumTxRequest") + proto.RegisterType((*EthereumTxAck)(nil), "hw.trezor.messages.ethereum.EthereumTxAck") + proto.RegisterType((*EthereumSignMessage)(nil), "hw.trezor.messages.ethereum.EthereumSignMessage") + proto.RegisterType((*EthereumMessageSignature)(nil), "hw.trezor.messages.ethereum.EthereumMessageSignature") + proto.RegisterType((*EthereumVerifyMessage)(nil), "hw.trezor.messages.ethereum.EthereumVerifyMessage") +} + +func init() { proto.RegisterFile("messages-ethereum.proto", fileDescriptor_cb33f46ba915f15c) } + +var fileDescriptor_cb33f46ba915f15c = []byte{ + // 593 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, + 0x10, 0x95, 0x9b, 0xb4, 0x49, 0x26, 0x0d, 0x1f, 0xa6, 0x55, 0x17, 0x0a, 0x34, 0x18, 0x21, 0xe5, + 0x00, 0x3e, 0x70, 0x43, 0xe2, 0xd2, 0x52, 0x44, 0x2b, 0x4a, 0x55, 0xdc, 0xa8, 0x57, 0x6b, 0x63, + 0x6f, 0xe3, 0x55, 0x9d, 0xdd, 0xe0, 0x5d, 0xb7, 0x0e, 0x7f, 0x82, 0x23, 0xff, 0x87, 0x5f, 0x86, + 0xf6, 0x2b, 0x71, 0x52, 0x54, 0x0e, 0xbd, 0x65, 0xde, 0xbc, 0x7d, 0xf3, 0x66, 0xf4, 0x62, 0xd8, + 0x99, 0x10, 0x21, 0xf0, 0x98, 0x88, 0x77, 0x44, 0x66, 0xa4, 0x20, 0xe5, 0x24, 0x9c, 0x16, 0x5c, + 0x72, 0x7f, 0x37, 0xbb, 0x09, 0x65, 0x41, 0x7e, 0xf2, 0x22, 0x74, 0x94, 0xd0, 0x51, 0x9e, 0x6d, + 0xcf, 0x5f, 0x25, 0x7c, 0x32, 0xe1, 0xcc, 0xbc, 0x09, 0x2e, 0x60, 0xeb, 0xb3, 0xa5, 0x7c, 0x21, + 0xf2, 0xac, 0x1c, 0xe5, 0x34, 0xf9, 0x4a, 0x66, 0xfe, 0x2e, 0x74, 0x70, 0x9a, 0x16, 0x44, 0x88, + 0x98, 0x21, 0xaf, 0xdf, 0x18, 0xf4, 0xa2, 0xb6, 0x05, 0x4e, 0xfd, 0x57, 0xb0, 0x29, 0x32, 0x7e, + 0x13, 0xa7, 0x54, 0x4c, 0x73, 0x3c, 0x43, 0x6b, 0x7d, 0x6f, 0xd0, 0x8e, 0xba, 0x0a, 0x3b, 0x34, + 0x50, 0x30, 0x82, 0xc7, 0x4e, 0x77, 0x21, 0xfa, 0x01, 0x9a, 0x8c, 0xa7, 0x04, 0x79, 0x7d, 0x6f, + 0xd0, 0x7d, 0xff, 0x26, 0xfc, 0x87, 0x5f, 0x6b, 0xee, 0xe8, 0xf0, 0x94, 0xa7, 0x64, 0x38, 0x9b, + 0x92, 0x48, 0x3f, 0xf1, 0x7d, 0x68, 0x56, 0xd3, 0x72, 0xa4, 0x47, 0x75, 0x22, 0xfd, 0x3b, 0x18, + 0x82, 0x5f, 0xf3, 0xbe, 0x6f, 0xdc, 0xdd, 0xdb, 0xf9, 0x77, 0x78, 0xe8, 0x54, 0x9d, 0xe4, 0x4b, + 0x00, 0xab, 0x70, 0x40, 0x99, 0x76, 0xbf, 0x19, 0xd5, 0x90, 0x5a, 0xff, 0x88, 0x54, 0xd6, 0x62, + 0x0d, 0x09, 0xfe, 0xac, 0xc1, 0x03, 0xa7, 0x79, 0x4e, 0xc7, 0x6c, 0x58, 0xdd, 0xed, 0x72, 0x0b, + 0xd6, 0x19, 0x67, 0x09, 0xd1, 0x52, 0x9b, 0x91, 0x29, 0xd4, 0x93, 0x31, 0x16, 0xf1, 0xb4, 0xa0, + 0x09, 0x41, 0x0d, 0xdd, 0x69, 0x8f, 0xb1, 0x38, 0x53, 0xb5, 0x6b, 0xe6, 0x74, 0x42, 0x25, 0x6a, + 0xce, 0x9b, 0x27, 0xaa, 0x56, 0x7a, 0x92, 0x2b, 0xeb, 0xeb, 0x46, 0x4f, 0x17, 0x06, 0x55, 0x86, + 0xbb, 0xda, 0xb0, 0x29, 0x14, 0x7a, 0x8d, 0xf3, 0x92, 0xa0, 0x0d, 0xc3, 0xd5, 0x85, 0xff, 0x16, + 0xfc, 0x14, 0x4b, 0x1c, 0x53, 0x46, 0x25, 0xc5, 0x79, 0x9c, 0x64, 0x25, 0xbb, 0x42, 0x2d, 0x4d, + 0x79, 0xa4, 0x3a, 0xc7, 0xa6, 0xf1, 0x49, 0xe1, 0xfe, 0x1e, 0x74, 0x35, 0x3b, 0x27, 0x6c, 0x2c, + 0x33, 0xd4, 0xee, 0x7b, 0x83, 0x5e, 0x04, 0x0a, 0x3a, 0xd1, 0x88, 0xff, 0x14, 0xda, 0x49, 0x86, + 0x29, 0x8b, 0x69, 0x8a, 0x3a, 0xba, 0xdb, 0xd2, 0xf5, 0x71, 0xea, 0xef, 0x40, 0x4b, 0x56, 0xb1, + 0x9c, 0x4d, 0x09, 0x02, 0xdd, 0xd9, 0x90, 0x95, 0xca, 0x41, 0xf0, 0xdb, 0x5b, 0x44, 0x6a, 0x58, + 0x45, 0xe4, 0x47, 0x49, 0x84, 0x5c, 0x1d, 0xe5, 0xdd, 0x1a, 0xb5, 0x07, 0x5d, 0x41, 0xc7, 0x0c, + 0xcb, 0xb2, 0x20, 0xf1, 0xb5, 0xbe, 0x68, 0x2f, 0x82, 0x39, 0x74, 0xb1, 0x4c, 0x28, 0xec, 0x61, + 0x17, 0x84, 0x68, 0x99, 0x20, 0xec, 0x71, 0x17, 0x84, 0xf3, 0x20, 0x84, 0xde, 0xc2, 0xd8, 0x7e, + 0x72, 0xe5, 0xbf, 0x00, 0xed, 0xc0, 0x5e, 0xc9, 0xe4, 0xa5, 0xa3, 0x10, 0x7d, 0x9e, 0xe0, 0x04, + 0x9e, 0xd4, 0xd3, 0xf0, 0xcd, 0x64, 0xff, 0xee, 0x48, 0x20, 0x68, 0xd9, 0xff, 0x88, 0x0d, 0x85, + 0x2b, 0x83, 0x0a, 0x90, 0x53, 0xb3, 0x4a, 0xe7, 0xce, 0xda, 0x7f, 0x83, 0xfb, 0x1c, 0x3a, 0xf3, + 0x3d, 0xac, 0xee, 0x02, 0x58, 0x89, 0x75, 0xe3, 0x56, 0xac, 0x7f, 0x79, 0xb0, 0xed, 0x46, 0x5f, + 0x90, 0x82, 0x5e, 0xce, 0xdc, 0x2a, 0xf7, 0x9b, 0x5b, 0xdb, 0xb5, 0xb1, 0xb4, 0xeb, 0x8a, 0xa3, + 0xe6, 0xaa, 0xa3, 0x83, 0x8f, 0xf0, 0x3a, 0xe1, 0x93, 0x50, 0x60, 0xc9, 0x45, 0x46, 0x73, 0x3c, + 0x12, 0xee, 0x03, 0x93, 0xd3, 0x91, 0xf9, 0xe2, 0x8d, 0xca, 0xcb, 0x83, 0xed, 0xa1, 0x06, 0xad, + 0x5b, 0xb7, 0xc2, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xce, 0x81, 0xc8, 0x59, 0x05, 0x00, + 0x00, +} diff --git a/accounts/usbwallet/trezor/messages-ethereum.proto b/accounts/usbwallet/trezor/messages-ethereum.proto new file mode 100644 index 0000000000..096bed2e4a --- /dev/null +++ b/accounts/usbwallet/trezor/messages-ethereum.proto @@ -0,0 +1,131 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.ethereum; + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessageEthereum"; + +import "messages-common.proto"; + + +/** + * Request: Ask device for public key corresponding to address_n path + * @start + * @next EthereumPublicKey + * @next Failure + */ +message EthereumGetPublicKey { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains public key derived from device private seed + * @end + */ +message EthereumPublicKey { + optional hw.trezor.messages.common.HDNodeType node = 1; // BIP32 public node + optional string xpub = 2; // serialized form of public node +} + +/** + * Request: Ask device for Ethereum address corresponding to address_n path + * @start + * @next EthereumAddress + * @next Failure + */ +message EthereumGetAddress { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bool show_display = 2; // optionally show on display before sending the result +} + +/** + * Response: Contains an Ethereum address derived from device private seed + * @end + */ +message EthereumAddress { + optional bytes addressBin = 1; // Ethereum address as 20 bytes (legacy firmwares) + optional string addressHex = 2; // Ethereum address as hex string (newer firmwares) +} + +/** + * Request: Ask device to sign transaction + * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. + * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. + * @start + * @next EthereumTxRequest + * @next Failure + */ +message EthereumSignTx { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes nonce = 2; // <=256 bit unsigned big endian + optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) + optional bytes gas_limit = 4; // <=256 bit unsigned big endian + optional bytes toBin = 5; // recipient address (20 bytes, legacy firmware) + optional string toHex = 11; // recipient address (hex string, newer firmware) + optional bytes value = 6; // <=256 bit unsigned big endian (in wei) + optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) + optional uint32 data_length = 8; // Length of transaction payload + optional uint32 chain_id = 9; // Chain Id for EIP 155 + optional uint32 tx_type = 10; // (only for Wanchain) +} + +/** + * Response: Device asks for more data from transaction payload, or returns the signature. + * If data_length is set, device awaits that many more bytes of payload. + * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. + * @end + * @next EthereumTxAck + */ +message EthereumTxRequest { + optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) + optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) + optional bytes signature_r = 3; // Computed signature R component (256 bit) + optional bytes signature_s = 4; // Computed signature S component (256 bit) +} + +/** + * Request: Transaction payload data. + * @next EthereumTxRequest + */ +message EthereumTxAck { + optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) +} + +/** + * Request: Ask device to sign message + * @start + * @next EthereumMessageSignature + * @next Failure + */ +message EthereumSignMessage { + repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node + optional bytes message = 2; // message to be signed +} + +/** + * Response: Signed message + * @end + */ +message EthereumMessageSignature { + optional bytes addressBin = 1; // address used to sign the message (20 bytes, legacy firmware) + optional bytes signature = 2; // signature of the message + optional string addressHex = 3; // address used to sign the message (hex string, newer firmware) +} + +/** + * Request: Ask device to verify message + * @start + * @next Success + * @next Failure + */ +message EthereumVerifyMessage { + optional bytes addressBin = 1; // address to verify (20 bytes, legacy firmware) + optional bytes signature = 2; // signature to verify + optional bytes message = 3; // message to verify + optional string addressHex = 4; // address to verify (hex string, newer firmware) +} diff --git a/accounts/usbwallet/trezor/messages-management.pb.go b/accounts/usbwallet/trezor/messages-management.pb.go new file mode 100644 index 0000000000..f5c872f1fb --- /dev/null +++ b/accounts/usbwallet/trezor/messages-management.pb.go @@ -0,0 +1,1621 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: messages-management.proto + +package trezor + +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Structure representing passphrase source +type ApplySettings_PassphraseSourceType int32 + +const ( + ApplySettings_ASK ApplySettings_PassphraseSourceType = 0 + ApplySettings_DEVICE ApplySettings_PassphraseSourceType = 1 + ApplySettings_HOST ApplySettings_PassphraseSourceType = 2 +) + +var ApplySettings_PassphraseSourceType_name = map[int32]string{ + 0: "ASK", + 1: "DEVICE", + 2: "HOST", +} + +var ApplySettings_PassphraseSourceType_value = map[string]int32{ + "ASK": 0, + "DEVICE": 1, + "HOST": 2, +} + +func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSourceType { + p := new(ApplySettings_PassphraseSourceType) + *p = x + return p +} + +func (x ApplySettings_PassphraseSourceType) String() string { + return proto.EnumName(ApplySettings_PassphraseSourceType_name, int32(x)) +} + +func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(ApplySettings_PassphraseSourceType_value, data, "ApplySettings_PassphraseSourceType") + if err != nil { + return err + } + *x = ApplySettings_PassphraseSourceType(value) + return nil +} + +func (ApplySettings_PassphraseSourceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{4, 0} +} + +//* +// Type of recovery procedure. These should be used as bitmask, e.g., +// `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` +// listing every method supported by the host computer. +// +// Note that ScrambledWords must be supported by every implementation +// for backward compatibility; there is no way to not support it. +type RecoveryDevice_RecoveryDeviceType int32 + +const ( + // use powers of two when extending this field + RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 + RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 +) + +var RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ + 0: "RecoveryDeviceType_ScrambledWords", + 1: "RecoveryDeviceType_Matrix", +} + +var RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ + "RecoveryDeviceType_ScrambledWords": 0, + "RecoveryDeviceType_Matrix": 1, +} + +func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDeviceType { + p := new(RecoveryDevice_RecoveryDeviceType) + *p = x + return p +} + +func (x RecoveryDevice_RecoveryDeviceType) String() string { + return proto.EnumName(RecoveryDevice_RecoveryDeviceType_name, int32(x)) +} + +func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RecoveryDevice_RecoveryDeviceType_value, data, "RecoveryDevice_RecoveryDeviceType") + if err != nil { + return err + } + *x = RecoveryDevice_RecoveryDeviceType(value) + return nil +} + +func (RecoveryDevice_RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{17, 0} +} + +//* +// Type of Recovery Word request +type WordRequest_WordRequestType int32 + +const ( + WordRequest_WordRequestType_Plain WordRequest_WordRequestType = 0 + WordRequest_WordRequestType_Matrix9 WordRequest_WordRequestType = 1 + WordRequest_WordRequestType_Matrix6 WordRequest_WordRequestType = 2 +) + +var WordRequest_WordRequestType_name = map[int32]string{ + 0: "WordRequestType_Plain", + 1: "WordRequestType_Matrix9", + 2: "WordRequestType_Matrix6", +} + +var WordRequest_WordRequestType_value = map[string]int32{ + "WordRequestType_Plain": 0, + "WordRequestType_Matrix9": 1, + "WordRequestType_Matrix6": 2, +} + +func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { + p := new(WordRequest_WordRequestType) + *p = x + return p +} + +func (x WordRequest_WordRequestType) String() string { + return proto.EnumName(WordRequest_WordRequestType_name, int32(x)) +} + +func (x *WordRequest_WordRequestType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(WordRequest_WordRequestType_value, data, "WordRequest_WordRequestType") + if err != nil { + return err + } + *x = WordRequest_WordRequestType(value) + return nil +} + +func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{18, 0} +} + +//* +// Request: Reset device to default state and ask for device details +// @start +// @next Features +type Initialize struct { + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` + SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Initialize) Reset() { *m = Initialize{} } +func (m *Initialize) String() string { return proto.CompactTextString(m) } +func (*Initialize) ProtoMessage() {} +func (*Initialize) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{0} +} + +func (m *Initialize) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Initialize.Unmarshal(m, b) +} +func (m *Initialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Initialize.Marshal(b, m, deterministic) +} +func (m *Initialize) XXX_Merge(src proto.Message) { + xxx_messageInfo_Initialize.Merge(m, src) +} +func (m *Initialize) XXX_Size() int { + return xxx_messageInfo_Initialize.Size(m) +} +func (m *Initialize) XXX_DiscardUnknown() { + xxx_messageInfo_Initialize.DiscardUnknown(m) +} + +var xxx_messageInfo_Initialize proto.InternalMessageInfo + +func (m *Initialize) GetState() []byte { + if m != nil { + return m.State + } + return nil +} + +func (m *Initialize) GetSkipPassphrase() bool { + if m != nil && m.SkipPassphrase != nil { + return *m.SkipPassphrase + } + return false +} + +//* +// Request: Ask for device details (no device reset) +// @start +// @next Features +type GetFeatures struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetFeatures) Reset() { *m = GetFeatures{} } +func (m *GetFeatures) String() string { return proto.CompactTextString(m) } +func (*GetFeatures) ProtoMessage() {} +func (*GetFeatures) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{1} +} + +func (m *GetFeatures) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetFeatures.Unmarshal(m, b) +} +func (m *GetFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetFeatures.Marshal(b, m, deterministic) +} +func (m *GetFeatures) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetFeatures.Merge(m, src) +} +func (m *GetFeatures) XXX_Size() int { + return xxx_messageInfo_GetFeatures.Size(m) +} +func (m *GetFeatures) XXX_DiscardUnknown() { + xxx_messageInfo_GetFeatures.DiscardUnknown(m) +} + +var xxx_messageInfo_GetFeatures proto.InternalMessageInfo + +//* +// Response: Reports various information about the device +// @end +type Features struct { + Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` + MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` + MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` + PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` + BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` + DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` + PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` + Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` + Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` + BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` + Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` + PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` + PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` + FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` + NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` + Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` + Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` + FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` + FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` + FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` + FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` + FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` + UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` + NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Features) Reset() { *m = Features{} } +func (m *Features) String() string { return proto.CompactTextString(m) } +func (*Features) ProtoMessage() {} +func (*Features) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{2} +} + +func (m *Features) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Features.Unmarshal(m, b) +} +func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Features.Marshal(b, m, deterministic) +} +func (m *Features) XXX_Merge(src proto.Message) { + xxx_messageInfo_Features.Merge(m, src) +} +func (m *Features) XXX_Size() int { + return xxx_messageInfo_Features.Size(m) +} +func (m *Features) XXX_DiscardUnknown() { + xxx_messageInfo_Features.DiscardUnknown(m) +} + +var xxx_messageInfo_Features proto.InternalMessageInfo + +func (m *Features) GetVendor() string { + if m != nil && m.Vendor != nil { + return *m.Vendor + } + return "" +} + +func (m *Features) GetMajorVersion() uint32 { + if m != nil && m.MajorVersion != nil { + return *m.MajorVersion + } + return 0 +} + +func (m *Features) GetMinorVersion() uint32 { + if m != nil && m.MinorVersion != nil { + return *m.MinorVersion + } + return 0 +} + +func (m *Features) GetPatchVersion() uint32 { + if m != nil && m.PatchVersion != nil { + return *m.PatchVersion + } + return 0 +} + +func (m *Features) GetBootloaderMode() bool { + if m != nil && m.BootloaderMode != nil { + return *m.BootloaderMode + } + return false +} + +func (m *Features) GetDeviceId() string { + if m != nil && m.DeviceId != nil { + return *m.DeviceId + } + return "" +} + +func (m *Features) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *Features) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *Features) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return "" +} + +func (m *Features) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *Features) GetInitialized() bool { + if m != nil && m.Initialized != nil { + return *m.Initialized + } + return false +} + +func (m *Features) GetRevision() []byte { + if m != nil { + return m.Revision + } + return nil +} + +func (m *Features) GetBootloaderHash() []byte { + if m != nil { + return m.BootloaderHash + } + return nil +} + +func (m *Features) GetImported() bool { + if m != nil && m.Imported != nil { + return *m.Imported + } + return false +} + +func (m *Features) GetPinCached() bool { + if m != nil && m.PinCached != nil { + return *m.PinCached + } + return false +} + +func (m *Features) GetPassphraseCached() bool { + if m != nil && m.PassphraseCached != nil { + return *m.PassphraseCached + } + return false +} + +func (m *Features) GetFirmwarePresent() bool { + if m != nil && m.FirmwarePresent != nil { + return *m.FirmwarePresent + } + return false +} + +func (m *Features) GetNeedsBackup() bool { + if m != nil && m.NeedsBackup != nil { + return *m.NeedsBackup + } + return false +} + +func (m *Features) GetFlags() uint32 { + if m != nil && m.Flags != nil { + return *m.Flags + } + return 0 +} + +func (m *Features) GetModel() string { + if m != nil && m.Model != nil { + return *m.Model + } + return "" +} + +func (m *Features) GetFwMajor() uint32 { + if m != nil && m.FwMajor != nil { + return *m.FwMajor + } + return 0 +} + +func (m *Features) GetFwMinor() uint32 { + if m != nil && m.FwMinor != nil { + return *m.FwMinor + } + return 0 +} + +func (m *Features) GetFwPatch() uint32 { + if m != nil && m.FwPatch != nil { + return *m.FwPatch + } + return 0 +} + +func (m *Features) GetFwVendor() string { + if m != nil && m.FwVendor != nil { + return *m.FwVendor + } + return "" +} + +func (m *Features) GetFwVendorKeys() []byte { + if m != nil { + return m.FwVendorKeys + } + return nil +} + +func (m *Features) GetUnfinishedBackup() bool { + if m != nil && m.UnfinishedBackup != nil { + return *m.UnfinishedBackup + } + return false +} + +func (m *Features) GetNoBackup() bool { + if m != nil && m.NoBackup != nil { + return *m.NoBackup + } + return false +} + +//* +// Request: clear session (removes cached PIN, passphrase, etc). +// @start +// @next Success +type ClearSession struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ClearSession) Reset() { *m = ClearSession{} } +func (m *ClearSession) String() string { return proto.CompactTextString(m) } +func (*ClearSession) ProtoMessage() {} +func (*ClearSession) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{3} +} + +func (m *ClearSession) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ClearSession.Unmarshal(m, b) +} +func (m *ClearSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ClearSession.Marshal(b, m, deterministic) +} +func (m *ClearSession) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClearSession.Merge(m, src) +} +func (m *ClearSession) XXX_Size() int { + return xxx_messageInfo_ClearSession.Size(m) +} +func (m *ClearSession) XXX_DiscardUnknown() { + xxx_messageInfo_ClearSession.DiscardUnknown(m) +} + +var xxx_messageInfo_ClearSession proto.InternalMessageInfo + +//* +// Request: change language and/or label of the device +// @start +// @next Success +// @next Failure +type ApplySettings struct { + Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` + UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` + Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` + PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` + AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` + DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplySettings) Reset() { *m = ApplySettings{} } +func (m *ApplySettings) String() string { return proto.CompactTextString(m) } +func (*ApplySettings) ProtoMessage() {} +func (*ApplySettings) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{4} +} + +func (m *ApplySettings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApplySettings.Unmarshal(m, b) +} +func (m *ApplySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApplySettings.Marshal(b, m, deterministic) +} +func (m *ApplySettings) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplySettings.Merge(m, src) +} +func (m *ApplySettings) XXX_Size() int { + return xxx_messageInfo_ApplySettings.Size(m) +} +func (m *ApplySettings) XXX_DiscardUnknown() { + xxx_messageInfo_ApplySettings.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplySettings proto.InternalMessageInfo + +func (m *ApplySettings) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return "" +} + +func (m *ApplySettings) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *ApplySettings) GetUsePassphrase() bool { + if m != nil && m.UsePassphrase != nil { + return *m.UsePassphrase + } + return false +} + +func (m *ApplySettings) GetHomescreen() []byte { + if m != nil { + return m.Homescreen + } + return nil +} + +func (m *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { + if m != nil && m.PassphraseSource != nil { + return *m.PassphraseSource + } + return ApplySettings_ASK +} + +func (m *ApplySettings) GetAutoLockDelayMs() uint32 { + if m != nil && m.AutoLockDelayMs != nil { + return *m.AutoLockDelayMs + } + return 0 +} + +func (m *ApplySettings) GetDisplayRotation() uint32 { + if m != nil && m.DisplayRotation != nil { + return *m.DisplayRotation + } + return 0 +} + +//* +// Request: set flags of the device +// @start +// @next Success +// @next Failure +type ApplyFlags struct { + Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } +func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } +func (*ApplyFlags) ProtoMessage() {} +func (*ApplyFlags) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{5} +} + +func (m *ApplyFlags) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ApplyFlags.Unmarshal(m, b) +} +func (m *ApplyFlags) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ApplyFlags.Marshal(b, m, deterministic) +} +func (m *ApplyFlags) XXX_Merge(src proto.Message) { + xxx_messageInfo_ApplyFlags.Merge(m, src) +} +func (m *ApplyFlags) XXX_Size() int { + return xxx_messageInfo_ApplyFlags.Size(m) +} +func (m *ApplyFlags) XXX_DiscardUnknown() { + xxx_messageInfo_ApplyFlags.DiscardUnknown(m) +} + +var xxx_messageInfo_ApplyFlags proto.InternalMessageInfo + +func (m *ApplyFlags) GetFlags() uint32 { + if m != nil && m.Flags != nil { + return *m.Flags + } + return 0 +} + +//* +// Request: Starts workflow for setting/changing/removing the PIN +// @start +// @next Success +// @next Failure +type ChangePin struct { + Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ChangePin) Reset() { *m = ChangePin{} } +func (m *ChangePin) String() string { return proto.CompactTextString(m) } +func (*ChangePin) ProtoMessage() {} +func (*ChangePin) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{6} +} + +func (m *ChangePin) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ChangePin.Unmarshal(m, b) +} +func (m *ChangePin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ChangePin.Marshal(b, m, deterministic) +} +func (m *ChangePin) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChangePin.Merge(m, src) +} +func (m *ChangePin) XXX_Size() int { + return xxx_messageInfo_ChangePin.Size(m) +} +func (m *ChangePin) XXX_DiscardUnknown() { + xxx_messageInfo_ChangePin.DiscardUnknown(m) +} + +var xxx_messageInfo_ChangePin proto.InternalMessageInfo + +func (m *ChangePin) GetRemove() bool { + if m != nil && m.Remove != nil { + return *m.Remove + } + return false +} + +//* +// Request: Test if the device is alive, device sends back the message in Success response +// @start +// @next Success +type Ping struct { + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ping) Reset() { *m = Ping{} } +func (m *Ping) String() string { return proto.CompactTextString(m) } +func (*Ping) ProtoMessage() {} +func (*Ping) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{7} +} + +func (m *Ping) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ping.Unmarshal(m, b) +} +func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ping.Marshal(b, m, deterministic) +} +func (m *Ping) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ping.Merge(m, src) +} +func (m *Ping) XXX_Size() int { + return xxx_messageInfo_Ping.Size(m) +} +func (m *Ping) XXX_DiscardUnknown() { + xxx_messageInfo_Ping.DiscardUnknown(m) +} + +var xxx_messageInfo_Ping proto.InternalMessageInfo + +func (m *Ping) GetMessage() string { + if m != nil && m.Message != nil { + return *m.Message + } + return "" +} + +func (m *Ping) GetButtonProtection() bool { + if m != nil && m.ButtonProtection != nil { + return *m.ButtonProtection + } + return false +} + +func (m *Ping) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *Ping) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +//* +// Request: Abort last operation that required user interaction +// @start +// @next Failure +type Cancel struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Cancel) Reset() { *m = Cancel{} } +func (m *Cancel) String() string { return proto.CompactTextString(m) } +func (*Cancel) ProtoMessage() {} +func (*Cancel) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{8} +} + +func (m *Cancel) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Cancel.Unmarshal(m, b) +} +func (m *Cancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Cancel.Marshal(b, m, deterministic) +} +func (m *Cancel) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cancel.Merge(m, src) +} +func (m *Cancel) XXX_Size() int { + return xxx_messageInfo_Cancel.Size(m) +} +func (m *Cancel) XXX_DiscardUnknown() { + xxx_messageInfo_Cancel.DiscardUnknown(m) +} + +var xxx_messageInfo_Cancel proto.InternalMessageInfo + +//* +// Request: Request a sample of random data generated by hardware RNG. May be used for testing. +// @start +// @next Entropy +// @next Failure +type GetEntropy struct { + Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetEntropy) Reset() { *m = GetEntropy{} } +func (m *GetEntropy) String() string { return proto.CompactTextString(m) } +func (*GetEntropy) ProtoMessage() {} +func (*GetEntropy) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{9} +} + +func (m *GetEntropy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetEntropy.Unmarshal(m, b) +} +func (m *GetEntropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetEntropy.Marshal(b, m, deterministic) +} +func (m *GetEntropy) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetEntropy.Merge(m, src) +} +func (m *GetEntropy) XXX_Size() int { + return xxx_messageInfo_GetEntropy.Size(m) +} +func (m *GetEntropy) XXX_DiscardUnknown() { + xxx_messageInfo_GetEntropy.DiscardUnknown(m) +} + +var xxx_messageInfo_GetEntropy proto.InternalMessageInfo + +func (m *GetEntropy) GetSize() uint32 { + if m != nil && m.Size != nil { + return *m.Size + } + return 0 +} + +//* +// Response: Reply with random data generated by internal RNG +// @end +type Entropy struct { + Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Entropy) Reset() { *m = Entropy{} } +func (m *Entropy) String() string { return proto.CompactTextString(m) } +func (*Entropy) ProtoMessage() {} +func (*Entropy) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{10} +} + +func (m *Entropy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Entropy.Unmarshal(m, b) +} +func (m *Entropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Entropy.Marshal(b, m, deterministic) +} +func (m *Entropy) XXX_Merge(src proto.Message) { + xxx_messageInfo_Entropy.Merge(m, src) +} +func (m *Entropy) XXX_Size() int { + return xxx_messageInfo_Entropy.Size(m) +} +func (m *Entropy) XXX_DiscardUnknown() { + xxx_messageInfo_Entropy.DiscardUnknown(m) +} + +var xxx_messageInfo_Entropy proto.InternalMessageInfo + +func (m *Entropy) GetEntropy() []byte { + if m != nil { + return m.Entropy + } + return nil +} + +//* +// Request: Request device to wipe all sensitive data and settings +// @start +// @next Success +// @next Failure +type WipeDevice struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WipeDevice) Reset() { *m = WipeDevice{} } +func (m *WipeDevice) String() string { return proto.CompactTextString(m) } +func (*WipeDevice) ProtoMessage() {} +func (*WipeDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{11} +} + +func (m *WipeDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WipeDevice.Unmarshal(m, b) +} +func (m *WipeDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WipeDevice.Marshal(b, m, deterministic) +} +func (m *WipeDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_WipeDevice.Merge(m, src) +} +func (m *WipeDevice) XXX_Size() int { + return xxx_messageInfo_WipeDevice.Size(m) +} +func (m *WipeDevice) XXX_DiscardUnknown() { + xxx_messageInfo_WipeDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_WipeDevice proto.InternalMessageInfo + +//* +// Request: Load seed and related internal settings from the computer +// @start +// @next Success +// @next Failure +type LoadDevice struct { + Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` + Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` + Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` + SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` + U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LoadDevice) Reset() { *m = LoadDevice{} } +func (m *LoadDevice) String() string { return proto.CompactTextString(m) } +func (*LoadDevice) ProtoMessage() {} +func (*LoadDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{12} +} + +func (m *LoadDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LoadDevice.Unmarshal(m, b) +} +func (m *LoadDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LoadDevice.Marshal(b, m, deterministic) +} +func (m *LoadDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_LoadDevice.Merge(m, src) +} +func (m *LoadDevice) XXX_Size() int { + return xxx_messageInfo_LoadDevice.Size(m) +} +func (m *LoadDevice) XXX_DiscardUnknown() { + xxx_messageInfo_LoadDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_LoadDevice proto.InternalMessageInfo + +const Default_LoadDevice_Language string = "english" + +func (m *LoadDevice) GetMnemonic() string { + if m != nil && m.Mnemonic != nil { + return *m.Mnemonic + } + return "" +} + +func (m *LoadDevice) GetNode() *HDNodeType { + if m != nil { + return m.Node + } + return nil +} + +func (m *LoadDevice) GetPin() string { + if m != nil && m.Pin != nil { + return *m.Pin + } + return "" +} + +func (m *LoadDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *LoadDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_LoadDevice_Language +} + +func (m *LoadDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *LoadDevice) GetSkipChecksum() bool { + if m != nil && m.SkipChecksum != nil { + return *m.SkipChecksum + } + return false +} + +func (m *LoadDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +//* +// Request: Ask device to do initialization involving user interaction +// @start +// @next EntropyRequest +// @next Failure +type ResetDevice struct { + DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` + Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` + PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` + U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` + NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ResetDevice) Reset() { *m = ResetDevice{} } +func (m *ResetDevice) String() string { return proto.CompactTextString(m) } +func (*ResetDevice) ProtoMessage() {} +func (*ResetDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{13} +} + +func (m *ResetDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ResetDevice.Unmarshal(m, b) +} +func (m *ResetDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ResetDevice.Marshal(b, m, deterministic) +} +func (m *ResetDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_ResetDevice.Merge(m, src) +} +func (m *ResetDevice) XXX_Size() int { + return xxx_messageInfo_ResetDevice.Size(m) +} +func (m *ResetDevice) XXX_DiscardUnknown() { + xxx_messageInfo_ResetDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_ResetDevice proto.InternalMessageInfo + +const Default_ResetDevice_Strength uint32 = 256 +const Default_ResetDevice_Language string = "english" + +func (m *ResetDevice) GetDisplayRandom() bool { + if m != nil && m.DisplayRandom != nil { + return *m.DisplayRandom + } + return false +} + +func (m *ResetDevice) GetStrength() uint32 { + if m != nil && m.Strength != nil { + return *m.Strength + } + return Default_ResetDevice_Strength +} + +func (m *ResetDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *ResetDevice) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *ResetDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_ResetDevice_Language +} + +func (m *ResetDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *ResetDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func (m *ResetDevice) GetSkipBackup() bool { + if m != nil && m.SkipBackup != nil { + return *m.SkipBackup + } + return false +} + +func (m *ResetDevice) GetNoBackup() bool { + if m != nil && m.NoBackup != nil { + return *m.NoBackup + } + return false +} + +//* +// Request: Perform backup of the device seed if not backed up using ResetDevice +// @start +// @next Success +type BackupDevice struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BackupDevice) Reset() { *m = BackupDevice{} } +func (m *BackupDevice) String() string { return proto.CompactTextString(m) } +func (*BackupDevice) ProtoMessage() {} +func (*BackupDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{14} +} + +func (m *BackupDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BackupDevice.Unmarshal(m, b) +} +func (m *BackupDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BackupDevice.Marshal(b, m, deterministic) +} +func (m *BackupDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupDevice.Merge(m, src) +} +func (m *BackupDevice) XXX_Size() int { + return xxx_messageInfo_BackupDevice.Size(m) +} +func (m *BackupDevice) XXX_DiscardUnknown() { + xxx_messageInfo_BackupDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_BackupDevice proto.InternalMessageInfo + +//* +// Response: Ask for additional entropy from host computer +// @next EntropyAck +type EntropyRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } +func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } +func (*EntropyRequest) ProtoMessage() {} +func (*EntropyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{15} +} + +func (m *EntropyRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntropyRequest.Unmarshal(m, b) +} +func (m *EntropyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntropyRequest.Marshal(b, m, deterministic) +} +func (m *EntropyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntropyRequest.Merge(m, src) +} +func (m *EntropyRequest) XXX_Size() int { + return xxx_messageInfo_EntropyRequest.Size(m) +} +func (m *EntropyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_EntropyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo + +//* +// Request: Provide additional entropy for seed generation function +// @next Success +type EntropyAck struct { + Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EntropyAck) Reset() { *m = EntropyAck{} } +func (m *EntropyAck) String() string { return proto.CompactTextString(m) } +func (*EntropyAck) ProtoMessage() {} +func (*EntropyAck) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{16} +} + +func (m *EntropyAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EntropyAck.Unmarshal(m, b) +} +func (m *EntropyAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EntropyAck.Marshal(b, m, deterministic) +} +func (m *EntropyAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_EntropyAck.Merge(m, src) +} +func (m *EntropyAck) XXX_Size() int { + return xxx_messageInfo_EntropyAck.Size(m) +} +func (m *EntropyAck) XXX_DiscardUnknown() { + xxx_messageInfo_EntropyAck.DiscardUnknown(m) +} + +var xxx_messageInfo_EntropyAck proto.InternalMessageInfo + +func (m *EntropyAck) GetEntropy() []byte { + if m != nil { + return m.Entropy + } + return nil +} + +//* +// Request: Start recovery workflow asking user for specific words of mnemonic +// Used to recovery device safely even on untrusted computer. +// @start +// @next WordRequest +type RecoveryDevice struct { + WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` + PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` + Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` + Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` + EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` + // 7 reserved for unused recovery method + Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` + U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } +func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } +func (*RecoveryDevice) ProtoMessage() {} +func (*RecoveryDevice) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{17} +} + +func (m *RecoveryDevice) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RecoveryDevice.Unmarshal(m, b) +} +func (m *RecoveryDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RecoveryDevice.Marshal(b, m, deterministic) +} +func (m *RecoveryDevice) XXX_Merge(src proto.Message) { + xxx_messageInfo_RecoveryDevice.Merge(m, src) +} +func (m *RecoveryDevice) XXX_Size() int { + return xxx_messageInfo_RecoveryDevice.Size(m) +} +func (m *RecoveryDevice) XXX_DiscardUnknown() { + xxx_messageInfo_RecoveryDevice.DiscardUnknown(m) +} + +var xxx_messageInfo_RecoveryDevice proto.InternalMessageInfo + +const Default_RecoveryDevice_Language string = "english" + +func (m *RecoveryDevice) GetWordCount() uint32 { + if m != nil && m.WordCount != nil { + return *m.WordCount + } + return 0 +} + +func (m *RecoveryDevice) GetPassphraseProtection() bool { + if m != nil && m.PassphraseProtection != nil { + return *m.PassphraseProtection + } + return false +} + +func (m *RecoveryDevice) GetPinProtection() bool { + if m != nil && m.PinProtection != nil { + return *m.PinProtection + } + return false +} + +func (m *RecoveryDevice) GetLanguage() string { + if m != nil && m.Language != nil { + return *m.Language + } + return Default_RecoveryDevice_Language +} + +func (m *RecoveryDevice) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *RecoveryDevice) GetEnforceWordlist() bool { + if m != nil && m.EnforceWordlist != nil { + return *m.EnforceWordlist + } + return false +} + +func (m *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { + if m != nil && m.Type != nil { + return *m.Type + } + return RecoveryDevice_RecoveryDeviceType_ScrambledWords +} + +func (m *RecoveryDevice) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func (m *RecoveryDevice) GetDryRun() bool { + if m != nil && m.DryRun != nil { + return *m.DryRun + } + return false +} + +//* +// Response: Device is waiting for user to enter word of the mnemonic +// Its position is shown only on device's internal display. +// @next WordAck +type WordRequest struct { + Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WordRequest) Reset() { *m = WordRequest{} } +func (m *WordRequest) String() string { return proto.CompactTextString(m) } +func (*WordRequest) ProtoMessage() {} +func (*WordRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{18} +} + +func (m *WordRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WordRequest.Unmarshal(m, b) +} +func (m *WordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WordRequest.Marshal(b, m, deterministic) +} +func (m *WordRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WordRequest.Merge(m, src) +} +func (m *WordRequest) XXX_Size() int { + return xxx_messageInfo_WordRequest.Size(m) +} +func (m *WordRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WordRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WordRequest proto.InternalMessageInfo + +func (m *WordRequest) GetType() WordRequest_WordRequestType { + if m != nil && m.Type != nil { + return *m.Type + } + return WordRequest_WordRequestType_Plain +} + +//* +// Request: Computer replies with word from the mnemonic +// @next WordRequest +// @next Success +// @next Failure +type WordAck struct { + Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WordAck) Reset() { *m = WordAck{} } +func (m *WordAck) String() string { return proto.CompactTextString(m) } +func (*WordAck) ProtoMessage() {} +func (*WordAck) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{19} +} + +func (m *WordAck) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WordAck.Unmarshal(m, b) +} +func (m *WordAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WordAck.Marshal(b, m, deterministic) +} +func (m *WordAck) XXX_Merge(src proto.Message) { + xxx_messageInfo_WordAck.Merge(m, src) +} +func (m *WordAck) XXX_Size() int { + return xxx_messageInfo_WordAck.Size(m) +} +func (m *WordAck) XXX_DiscardUnknown() { + xxx_messageInfo_WordAck.DiscardUnknown(m) +} + +var xxx_messageInfo_WordAck proto.InternalMessageInfo + +func (m *WordAck) GetWord() string { + if m != nil && m.Word != nil { + return *m.Word + } + return "" +} + +//* +// Request: Set U2F counter +// @start +// @next Success +type SetU2FCounter struct { + U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } +func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } +func (*SetU2FCounter) ProtoMessage() {} +func (*SetU2FCounter) Descriptor() ([]byte, []int) { + return fileDescriptor_0c720c20d27aa029, []int{20} +} + +func (m *SetU2FCounter) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetU2FCounter.Unmarshal(m, b) +} +func (m *SetU2FCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetU2FCounter.Marshal(b, m, deterministic) +} +func (m *SetU2FCounter) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetU2FCounter.Merge(m, src) +} +func (m *SetU2FCounter) XXX_Size() int { + return xxx_messageInfo_SetU2FCounter.Size(m) +} +func (m *SetU2FCounter) XXX_DiscardUnknown() { + xxx_messageInfo_SetU2FCounter.DiscardUnknown(m) +} + +var xxx_messageInfo_SetU2FCounter proto.InternalMessageInfo + +func (m *SetU2FCounter) GetU2FCounter() uint32 { + if m != nil && m.U2FCounter != nil { + return *m.U2FCounter + } + return 0 +} + +func init() { + proto.RegisterEnum("hw.trezor.messages.management.ApplySettings_PassphraseSourceType", ApplySettings_PassphraseSourceType_name, ApplySettings_PassphraseSourceType_value) + proto.RegisterEnum("hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType", RecoveryDevice_RecoveryDeviceType_name, RecoveryDevice_RecoveryDeviceType_value) + proto.RegisterEnum("hw.trezor.messages.management.WordRequest_WordRequestType", WordRequest_WordRequestType_name, WordRequest_WordRequestType_value) + proto.RegisterType((*Initialize)(nil), "hw.trezor.messages.management.Initialize") + proto.RegisterType((*GetFeatures)(nil), "hw.trezor.messages.management.GetFeatures") + proto.RegisterType((*Features)(nil), "hw.trezor.messages.management.Features") + proto.RegisterType((*ClearSession)(nil), "hw.trezor.messages.management.ClearSession") + proto.RegisterType((*ApplySettings)(nil), "hw.trezor.messages.management.ApplySettings") + proto.RegisterType((*ApplyFlags)(nil), "hw.trezor.messages.management.ApplyFlags") + proto.RegisterType((*ChangePin)(nil), "hw.trezor.messages.management.ChangePin") + proto.RegisterType((*Ping)(nil), "hw.trezor.messages.management.Ping") + proto.RegisterType((*Cancel)(nil), "hw.trezor.messages.management.Cancel") + proto.RegisterType((*GetEntropy)(nil), "hw.trezor.messages.management.GetEntropy") + proto.RegisterType((*Entropy)(nil), "hw.trezor.messages.management.Entropy") + proto.RegisterType((*WipeDevice)(nil), "hw.trezor.messages.management.WipeDevice") + proto.RegisterType((*LoadDevice)(nil), "hw.trezor.messages.management.LoadDevice") + proto.RegisterType((*ResetDevice)(nil), "hw.trezor.messages.management.ResetDevice") + proto.RegisterType((*BackupDevice)(nil), "hw.trezor.messages.management.BackupDevice") + proto.RegisterType((*EntropyRequest)(nil), "hw.trezor.messages.management.EntropyRequest") + proto.RegisterType((*EntropyAck)(nil), "hw.trezor.messages.management.EntropyAck") + proto.RegisterType((*RecoveryDevice)(nil), "hw.trezor.messages.management.RecoveryDevice") + proto.RegisterType((*WordRequest)(nil), "hw.trezor.messages.management.WordRequest") + proto.RegisterType((*WordAck)(nil), "hw.trezor.messages.management.WordAck") + proto.RegisterType((*SetU2FCounter)(nil), "hw.trezor.messages.management.SetU2FCounter") +} + +func init() { proto.RegisterFile("messages-management.proto", fileDescriptor_0c720c20d27aa029) } + +var fileDescriptor_0c720c20d27aa029 = []byte{ + // 1393 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xdd, 0x6e, 0xdb, 0xc8, + 0x15, 0x8e, 0x7e, 0x62, 0x49, 0xc7, 0xfa, 0xcb, 0xd4, 0x8e, 0xe9, 0xb8, 0x6e, 0x1c, 0xba, 0x6e, + 0x12, 0x04, 0x15, 0x0a, 0x17, 0x09, 0x90, 0x5c, 0x14, 0x75, 0xec, 0xfc, 0x21, 0x71, 0x6a, 0xd0, + 0x6e, 0x02, 0xf4, 0x86, 0x18, 0x91, 0x47, 0xd2, 0xd4, 0xe4, 0x0c, 0xcb, 0x19, 0xda, 0x55, 0x5e, + 0x60, 0x6f, 0xf6, 0x45, 0x16, 0xfb, 0x1c, 0x7b, 0xb5, 0xcf, 0xb0, 0xef, 0xb2, 0x98, 0x19, 0x52, + 0xa2, 0x65, 0x3b, 0x46, 0x76, 0xef, 0xe6, 0x7c, 0xe7, 0xe3, 0x68, 0xce, 0x77, 0xbe, 0x39, 0x63, + 0xc3, 0x7a, 0x8c, 0x52, 0xd2, 0x31, 0xca, 0xbf, 0xc6, 0x94, 0xd3, 0x31, 0xc6, 0xc8, 0xd5, 0x20, + 0x49, 0x85, 0x12, 0x64, 0x73, 0x72, 0x3e, 0x50, 0x29, 0x7e, 0x11, 0xe9, 0xa0, 0x20, 0x0d, 0xe6, + 0xa4, 0x7b, 0xab, 0xb3, 0x2f, 0x03, 0x11, 0xc7, 0x82, 0xdb, 0xaf, 0xdc, 0xf7, 0x00, 0xef, 0x38, + 0x53, 0x8c, 0x46, 0xec, 0x0b, 0x92, 0x15, 0xb8, 0x2d, 0x15, 0x55, 0xe8, 0x54, 0xb6, 0x2a, 0x8f, + 0xda, 0x9e, 0x0d, 0xc8, 0x43, 0xe8, 0xc9, 0x53, 0x96, 0xf8, 0x09, 0x95, 0x32, 0x99, 0xa4, 0x54, + 0xa2, 0x53, 0xdd, 0xaa, 0x3c, 0x6a, 0x7a, 0x5d, 0x0d, 0x1f, 0xcd, 0x50, 0xb7, 0x03, 0xcb, 0x6f, + 0x50, 0xbd, 0x46, 0xaa, 0xb2, 0x14, 0xa5, 0xfb, 0x7d, 0x03, 0x9a, 0x45, 0x40, 0xee, 0xc2, 0xd2, + 0x19, 0xf2, 0x50, 0xa4, 0x66, 0xef, 0x96, 0x97, 0x47, 0x64, 0x1b, 0x3a, 0x31, 0xfd, 0xaf, 0x48, + 0xfd, 0x33, 0x4c, 0x25, 0x13, 0xdc, 0x6c, 0xdd, 0xf1, 0xda, 0x06, 0xfc, 0x64, 0x31, 0x43, 0x62, + 0xbc, 0x44, 0xaa, 0xe5, 0x24, 0x0d, 0x96, 0x48, 0x09, 0x55, 0xc1, 0x64, 0x46, 0xaa, 0x5b, 0x92, + 0x01, 0x0b, 0xd2, 0x43, 0xe8, 0x0d, 0x85, 0x50, 0x91, 0xa0, 0x21, 0xa6, 0x7e, 0x2c, 0x42, 0x74, + 0x6e, 0xdb, 0x5a, 0xe6, 0xf0, 0xa1, 0x08, 0x91, 0x6c, 0x40, 0x2b, 0xc4, 0x33, 0x16, 0xa0, 0xcf, + 0x42, 0x67, 0xc9, 0x1c, 0xb9, 0x69, 0x81, 0x77, 0x21, 0xd9, 0x81, 0x6e, 0xc2, 0xb8, 0xaf, 0x25, + 0xc4, 0x40, 0xe9, 0xdf, 0x6a, 0x98, 0x4d, 0x3a, 0x09, 0xe3, 0x47, 0x33, 0x90, 0xfc, 0x1d, 0x56, + 0xe7, 0x9a, 0x95, 0xd9, 0x4d, 0xc3, 0x5e, 0x99, 0x27, 0x4b, 0x1f, 0xdd, 0x83, 0x66, 0x44, 0xf9, + 0x38, 0xa3, 0x63, 0x74, 0x5a, 0xf6, 0x77, 0x8b, 0x58, 0xf7, 0x27, 0xa2, 0x43, 0x8c, 0x1c, 0x30, + 0x09, 0x1b, 0x90, 0x2d, 0x58, 0x66, 0xb3, 0x1e, 0x86, 0x4e, 0xdb, 0x6c, 0x5e, 0x86, 0xf4, 0x9e, + 0x29, 0x9e, 0x31, 0xa3, 0x4a, 0xc7, 0xb4, 0x76, 0x16, 0x2f, 0x28, 0x32, 0xa1, 0x72, 0xe2, 0x74, + 0x0d, 0xa5, 0xa4, 0xc8, 0x5b, 0x2a, 0x27, 0x7a, 0x13, 0x16, 0x27, 0x22, 0x55, 0x18, 0x3a, 0x3d, + 0xf3, 0x1b, 0xb3, 0x98, 0x6c, 0x02, 0x68, 0x41, 0x02, 0x1a, 0x4c, 0x30, 0x74, 0xfa, 0x26, 0xdb, + 0x4a, 0x18, 0xdf, 0x37, 0x00, 0x79, 0x02, 0x77, 0x4a, 0x42, 0xe4, 0xac, 0x3b, 0x86, 0xd5, 0x9f, + 0x27, 0x72, 0xf2, 0x63, 0xe8, 0x8f, 0x58, 0x1a, 0x9f, 0xd3, 0x54, 0x6b, 0x86, 0x12, 0xb9, 0x72, + 0x88, 0xe1, 0xf6, 0x0a, 0xfc, 0xc8, 0xc2, 0xe4, 0x01, 0xb4, 0x39, 0x62, 0x28, 0xfd, 0x21, 0x0d, + 0x4e, 0xb3, 0xc4, 0xf9, 0x83, 0x2d, 0xdd, 0x60, 0x2f, 0x0d, 0xa4, 0x25, 0x1b, 0x45, 0x74, 0x2c, + 0x9d, 0x15, 0xe3, 0x06, 0x1b, 0x68, 0x54, 0xf7, 0x3e, 0x72, 0x56, 0xad, 0x90, 0x26, 0x20, 0xeb, + 0xd0, 0x1c, 0x9d, 0xfb, 0xc6, 0x79, 0xce, 0x5d, 0x43, 0x6f, 0x8c, 0xce, 0x0f, 0x75, 0x58, 0xa4, + 0xb4, 0xdf, 0x9c, 0xb5, 0x59, 0x4a, 0x87, 0x79, 0xca, 0xb8, 0xcc, 0x71, 0x8a, 0xd4, 0x91, 0x0e, + 0xb5, 0x89, 0x46, 0xe7, 0x7e, 0xee, 0xfb, 0x75, 0xdb, 0xcc, 0xd1, 0xf9, 0x27, 0xeb, 0xfc, 0x3f, + 0x43, 0x77, 0x96, 0xf4, 0x4f, 0x71, 0x2a, 0x9d, 0x7b, 0x46, 0xf7, 0x76, 0xc1, 0x78, 0x8f, 0x53, + 0xa9, 0xa5, 0xcb, 0xf8, 0x88, 0x71, 0x26, 0x27, 0x18, 0x16, 0x75, 0x6e, 0x58, 0xe9, 0xe6, 0x89, + 0xbc, 0xd8, 0x0d, 0x68, 0x71, 0x51, 0x90, 0xfe, 0x68, 0x7b, 0xc4, 0x85, 0x4d, 0xba, 0x5d, 0x68, + 0xef, 0x47, 0x48, 0xd3, 0x63, 0x94, 0xba, 0xf1, 0xee, 0x77, 0x35, 0xe8, 0xec, 0x25, 0x49, 0x34, + 0x3d, 0x46, 0xa5, 0x18, 0x1f, 0xcb, 0x0b, 0xd6, 0xab, 0x5c, 0x67, 0xbd, 0x6a, 0xd9, 0x7a, 0x3b, + 0xd0, 0xcd, 0xb4, 0xb5, 0xe7, 0x93, 0xa1, 0x66, 0x2f, 0x42, 0x26, 0x71, 0x3e, 0x18, 0xc8, 0x9f, + 0x00, 0x26, 0x22, 0x46, 0x19, 0xa4, 0x88, 0xf6, 0x5e, 0xb6, 0xbd, 0x12, 0x42, 0xf8, 0x05, 0x7f, + 0x48, 0x91, 0xa5, 0x81, 0xbd, 0x97, 0xdd, 0xdd, 0xbd, 0xc1, 0x57, 0xe7, 0xda, 0xe0, 0x42, 0x05, + 0x83, 0xf9, 0x6f, 0x1e, 0x9b, 0x4d, 0x4e, 0xa6, 0x09, 0x96, 0x2d, 0x66, 0x51, 0xf2, 0x04, 0x08, + 0xcd, 0x94, 0xf0, 0x23, 0x11, 0x9c, 0xfa, 0x21, 0x46, 0x74, 0xea, 0xc7, 0xd2, 0xdc, 0xf2, 0x8e, + 0xd7, 0xd3, 0x99, 0x0f, 0x22, 0x38, 0x3d, 0xd0, 0xf8, 0xa1, 0xd4, 0x7e, 0x0c, 0x99, 0x4c, 0x34, + 0x29, 0x15, 0x8a, 0xce, 0xae, 0x7b, 0xc7, 0xeb, 0xe5, 0xb8, 0x97, 0xc3, 0xee, 0x53, 0x58, 0xb9, + 0xea, 0x04, 0xa4, 0x01, 0xb5, 0xbd, 0xe3, 0xf7, 0xfd, 0x5b, 0x04, 0x60, 0xe9, 0xe0, 0xd5, 0xa7, + 0x77, 0xfb, 0xaf, 0xfa, 0x15, 0xd2, 0x84, 0xfa, 0xdb, 0x7f, 0x1d, 0x9f, 0xf4, 0xab, 0xae, 0x0b, + 0x60, 0xca, 0x78, 0x5d, 0x78, 0xd3, 0x3a, 0xb6, 0x52, 0x72, 0xac, 0xbb, 0x0d, 0xad, 0xfd, 0x09, + 0xe5, 0x63, 0x3c, 0x62, 0x5c, 0x0f, 0xd3, 0x14, 0x63, 0x71, 0x66, 0xdb, 0xd4, 0xf4, 0xf2, 0xc8, + 0xfd, 0xa1, 0x02, 0xf5, 0x23, 0xc6, 0xc7, 0xc4, 0x81, 0x46, 0x2e, 0x56, 0xde, 0xc8, 0x22, 0xd4, + 0x7e, 0x1a, 0x66, 0x4a, 0x89, 0x0b, 0xd3, 0xcb, 0x8e, 0xf3, 0xbe, 0x4d, 0x94, 0x66, 0xd1, 0xe5, + 0x39, 0x57, 0xfb, 0xa6, 0x39, 0x57, 0xbf, 0x7e, 0xce, 0xb9, 0x4d, 0x58, 0xda, 0xa7, 0x3c, 0xc0, + 0xc8, 0xdd, 0x02, 0x78, 0x83, 0xea, 0x15, 0x57, 0xa9, 0x48, 0xa6, 0x84, 0x40, 0x5d, 0xb2, 0x2f, + 0xfa, 0xdc, 0xd5, 0x47, 0x1d, 0xcf, 0xac, 0xdd, 0x6d, 0x68, 0x14, 0x69, 0x07, 0x1a, 0x68, 0x97, + 0x86, 0xd1, 0xf6, 0x8a, 0xd0, 0x6d, 0x03, 0x7c, 0x66, 0x09, 0x1e, 0x98, 0x21, 0xed, 0xfe, 0x58, + 0x05, 0xf8, 0x20, 0x68, 0x68, 0x43, 0x6d, 0xed, 0x98, 0x63, 0x2c, 0x38, 0x0b, 0x0a, 0x6b, 0x17, + 0x31, 0x79, 0x0e, 0x75, 0xae, 0x1f, 0x02, 0xad, 0xc2, 0xf2, 0xee, 0xce, 0x55, 0x86, 0xcb, 0xdf, + 0xcc, 0xb7, 0x07, 0x1f, 0x45, 0x68, 0x4d, 0x65, 0x3e, 0x21, 0x7d, 0xa8, 0x25, 0xcc, 0xaa, 0xd2, + 0xf2, 0xf4, 0xf2, 0x37, 0x69, 0x41, 0xb6, 0x4b, 0x17, 0x4f, 0xdb, 0xbe, 0xf5, 0xa2, 0x81, 0x7c, + 0x1c, 0x31, 0x39, 0xb9, 0xea, 0x06, 0x2e, 0x95, 0x6f, 0xe0, 0x36, 0x74, 0xcc, 0xe3, 0x1c, 0x4c, + 0x30, 0x38, 0x95, 0x59, 0x9c, 0xbf, 0x44, 0x6d, 0x0d, 0xee, 0xe7, 0x18, 0xb9, 0x0f, 0xcb, 0xd9, + 0xee, 0xc8, 0x0f, 0x44, 0xc6, 0x15, 0xa6, 0xe6, 0xf9, 0xe9, 0x78, 0x90, 0xed, 0x8e, 0xf6, 0x2d, + 0xe2, 0xfe, 0x5c, 0x85, 0x65, 0x0f, 0x25, 0xaa, 0x5c, 0xae, 0x1d, 0xe8, 0xce, 0x3c, 0x4f, 0x79, + 0x28, 0xe2, 0xdc, 0x68, 0x9d, 0xc2, 0xf1, 0x06, 0x24, 0xf7, 0xa1, 0x29, 0x55, 0x8a, 0x7c, 0xac, + 0x26, 0xf6, 0xdd, 0x7e, 0x51, 0xdb, 0x7d, 0xfa, 0xcc, 0x9b, 0x81, 0xd7, 0xab, 0x51, 0xfb, 0x8a, + 0x1a, 0x97, 0x5d, 0x57, 0xbf, 0xca, 0x75, 0xbf, 0x43, 0xb4, 0x05, 0x3d, 0x1a, 0x8b, 0x7a, 0x68, + 0x82, 0x51, 0x35, 0x1f, 0xa5, 0xf6, 0xbd, 0x06, 0x0d, 0x5d, 0x35, 0x69, 0x5b, 0x97, 0x27, 0xad, + 0x5d, 0xe5, 0x5e, 0xec, 0x43, 0x37, 0xb7, 0xaf, 0x87, 0xff, 0xcb, 0x50, 0x2a, 0xf7, 0x2f, 0x00, + 0x39, 0xb2, 0x17, 0x9c, 0x5e, 0xf4, 0x74, 0xa5, 0xec, 0xe9, 0x5f, 0x6a, 0xd0, 0xf5, 0x30, 0x10, + 0x67, 0x98, 0x4e, 0xf3, 0xd6, 0x6c, 0x02, 0x9c, 0x8b, 0x34, 0xb4, 0x87, 0xcf, 0x67, 0x44, 0x4b, + 0x23, 0xe6, 0xec, 0xd7, 0x2b, 0x5e, 0xfd, 0x26, 0xc5, 0x6b, 0x37, 0x29, 0x5e, 0xbf, 0x51, 0xf1, + 0xdb, 0x65, 0xc5, 0x1f, 0x43, 0x1f, 0xf9, 0x48, 0xa4, 0x01, 0xfa, 0xfa, 0xac, 0x11, 0x93, 0xca, + 0xb4, 0xa4, 0xe9, 0xf5, 0x72, 0xfc, 0x73, 0x0e, 0x93, 0x13, 0xa8, 0xab, 0x69, 0x82, 0x46, 0xf4, + 0xee, 0xee, 0x3f, 0x6f, 0x98, 0xff, 0x17, 0xd5, 0x59, 0x08, 0xed, 0x4d, 0xd5, 0xbb, 0x2d, 0xb6, + 0xbc, 0x75, 0xa9, 0xe5, 0x6b, 0xd0, 0x08, 0xd3, 0xa9, 0x9f, 0x66, 0xdc, 0xfc, 0x75, 0xd5, 0xf4, + 0x96, 0xc2, 0x74, 0xea, 0x65, 0xdc, 0xfd, 0x0f, 0x90, 0xcb, 0xbb, 0x92, 0x1d, 0x78, 0x70, 0x19, + 0xf5, 0x8f, 0x83, 0x94, 0xc6, 0xc3, 0x08, 0x43, 0x5d, 0x8d, 0xec, 0xdf, 0x22, 0x9b, 0xb0, 0x7e, + 0x05, 0xed, 0x90, 0xaa, 0x94, 0xfd, 0xbf, 0x5f, 0x71, 0x7f, 0xaa, 0xc0, 0xb2, 0xa6, 0xe6, 0xbe, + 0x20, 0x1f, 0xf3, 0xda, 0x2b, 0xa6, 0xf6, 0x17, 0x37, 0xd4, 0x5e, 0xfa, 0xb2, 0xbc, 0x9e, 0x57, + 0xed, 0x8e, 0xa0, 0xb7, 0x90, 0x20, 0xeb, 0xb0, 0xba, 0x00, 0xf9, 0x47, 0x11, 0x65, 0xbc, 0x7f, + 0x8b, 0x6c, 0xc0, 0xda, 0x62, 0xca, 0x9e, 0xf4, 0x79, 0xbf, 0x72, 0x7d, 0xf2, 0x59, 0xbf, 0xea, + 0x6e, 0x42, 0x43, 0x27, 0xb5, 0x99, 0x09, 0xd4, 0x75, 0x87, 0xcd, 0x74, 0x6e, 0x79, 0x66, 0xed, + 0xfe, 0x0d, 0x3a, 0xc7, 0xa8, 0xfe, 0xbd, 0xfb, 0xba, 0x74, 0xbf, 0xca, 0xdd, 0xa8, 0x2c, 0x76, + 0xe3, 0xe5, 0x3f, 0x60, 0x3b, 0x10, 0xf1, 0x40, 0x52, 0x25, 0xe4, 0x84, 0x45, 0x74, 0x28, 0x0b, + 0x21, 0x22, 0x36, 0xb4, 0xff, 0xbb, 0x0c, 0xb3, 0xd1, 0xcb, 0xb5, 0x13, 0x03, 0x1e, 0x5a, 0x71, + 0x0e, 0x67, 0xd2, 0xfc, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0xfc, 0x59, 0x29, 0x0d, 0x00, + 0x00, +} diff --git a/accounts/usbwallet/trezor/messages-management.proto b/accounts/usbwallet/trezor/messages-management.proto new file mode 100644 index 0000000000..0ab825a1bc --- /dev/null +++ b/accounts/usbwallet/trezor/messages-management.proto @@ -0,0 +1,289 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-management.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + +syntax = "proto2"; +package hw.trezor.messages.management; + +// Sugar for easier handling in Java +option java_package = "com.satoshilabs.trezor.lib.protobuf"; +option java_outer_classname = "TrezorMessageManagement"; + +import "messages-common.proto"; + +/** + * Request: Reset device to default state and ask for device details + * @start + * @next Features + */ +message Initialize { + optional bytes state = 1; // assumed device state, clear session if set and different + optional bool skip_passphrase = 2; // this session should always assume empty passphrase +} + +/** + * Request: Ask for device details (no device reset) + * @start + * @next Features + */ +message GetFeatures { +} + +/** + * Response: Reports various information about the device + * @end + */ +message Features { + optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io" + optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1 + optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0 + optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0 + optional bool bootloader_mode = 5; // is device in bootloader mode? + optional string device_id = 6; // device's unique identifier + optional bool pin_protection = 7; // is device protected by PIN? + optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? + optional string language = 9; // device language + optional string label = 10; // device description label + optional bool initialized = 12; // does device contain seed? + optional bytes revision = 13; // SCM revision of firmware + optional bytes bootloader_hash = 14; // hash of the bootloader + optional bool imported = 15; // was storage imported from an external source? + optional bool pin_cached = 16; // is PIN already cached in session? + optional bool passphrase_cached = 17; // is passphrase already cached in session? + optional bool firmware_present = 18; // is valid firmware loaded? + optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) + optional uint32 flags = 20; // device flags (equals to Storage.flags) + optional string model = 21; // device hardware model + optional uint32 fw_major = 22; // reported firmware version if in bootloader mode + optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode + optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode + optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode + optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash) + optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup) + optional bool no_backup = 28; // report no backup (equals to Storage.no_backup) +} + +/** + * Request: clear session (removes cached PIN, passphrase, etc). + * @start + * @next Success + */ +message ClearSession { +} + +/** + * Request: change language and/or label of the device + * @start + * @next Success + * @next Failure + */ +message ApplySettings { + optional string language = 1; + optional string label = 2; + optional bool use_passphrase = 3; + optional bytes homescreen = 4; + optional PassphraseSourceType passphrase_source = 5; + optional uint32 auto_lock_delay_ms = 6; + optional uint32 display_rotation = 7; // in degrees from North + /** + * Structure representing passphrase source + */ + enum PassphraseSourceType { + ASK = 0; + DEVICE = 1; + HOST = 2; + } +} + +/** + * Request: set flags of the device + * @start + * @next Success + * @next Failure + */ +message ApplyFlags { + optional uint32 flags = 1; // bitmask, can only set bits, not unset +} + +/** + * Request: Starts workflow for setting/changing/removing the PIN + * @start + * @next Success + * @next Failure + */ +message ChangePin { + optional bool remove = 1; // is PIN removal requested? +} + +/** + * Request: Test if the device is alive, device sends back the message in Success response + * @start + * @next Success + */ +message Ping { + optional string message = 1; // message to send back in Success message + optional bool button_protection = 2; // ask for button press + optional bool pin_protection = 3; // ask for PIN if set in device + optional bool passphrase_protection = 4; // ask for passphrase if set in device +} + +/** + * Request: Abort last operation that required user interaction + * @start + * @next Failure + */ +message Cancel { +} + +/** + * Request: Request a sample of random data generated by hardware RNG. May be used for testing. + * @start + * @next Entropy + * @next Failure + */ +message GetEntropy { + required uint32 size = 1; // size of requested entropy +} + +/** + * Response: Reply with random data generated by internal RNG + * @end + */ +message Entropy { + required bytes entropy = 1; // chunk of random generated bytes +} + +/** + * Request: Request device to wipe all sensitive data and settings + * @start + * @next Success + * @next Failure + */ +message WipeDevice { +} + +/** + * Request: Load seed and related internal settings from the computer + * @start + * @next Success + * @next Failure + */ +message LoadDevice { + optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + optional hw.trezor.messages.common.HDNodeType node = 2; // BIP-32 node + optional string pin = 3; // set PIN protection + optional bool passphrase_protection = 4; // enable master node encryption using passphrase + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum + optional uint32 u2f_counter = 8; // U2F counter +} + +/** + * Request: Ask device to do initialization involving user interaction + * @start + * @next EntropyRequest + * @next Failure + */ +message ResetDevice { + optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy + optional uint32 strength = 2 [default=256]; // strength of seed in bits + optional bool passphrase_protection = 3; // enable master node encryption using passphrase + optional bool pin_protection = 4; // enable PIN protection + optional string language = 5 [default='english']; // device language + optional string label = 6; // device label + optional uint32 u2f_counter = 7; // U2F counter + optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow + optional bool no_backup = 9; // indicate that no backup is going to be made +} + +/** + * Request: Perform backup of the device seed if not backed up using ResetDevice + * @start + * @next Success + */ +message BackupDevice { +} + +/** + * Response: Ask for additional entropy from host computer + * @next EntropyAck + */ +message EntropyRequest { +} + +/** + * Request: Provide additional entropy for seed generation function + * @next Success + */ +message EntropyAck { + optional bytes entropy = 1; // 256 bits (32 bytes) of random data +} + +/** + * Request: Start recovery workflow asking user for specific words of mnemonic + * Used to recovery device safely even on untrusted computer. + * @start + * @next WordRequest + */ +message RecoveryDevice { + optional uint32 word_count = 1; // number of words in BIP-39 mnemonic + optional bool passphrase_protection = 2; // enable master node encryption using passphrase + optional bool pin_protection = 3; // enable PIN protection + optional string language = 4 [default='english']; // device language + optional string label = 5; // device label + optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process + // 7 reserved for unused recovery method + optional RecoveryDeviceType type = 8; // supported recovery type + optional uint32 u2f_counter = 9; // U2F counter + optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) + /** + * Type of recovery procedure. These should be used as bitmask, e.g., + * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` + * listing every method supported by the host computer. + * + * Note that ScrambledWords must be supported by every implementation + * for backward compatibility; there is no way to not support it. + */ + enum RecoveryDeviceType { + // use powers of two when extending this field + RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order + RecoveryDeviceType_Matrix = 1; // matrix recovery type + } +} + +/** + * Response: Device is waiting for user to enter word of the mnemonic + * Its position is shown only on device's internal display. + * @next WordAck + */ +message WordRequest { + optional WordRequestType type = 1; + /** + * Type of Recovery Word request + */ + enum WordRequestType { + WordRequestType_Plain = 0; + WordRequestType_Matrix9 = 1; + WordRequestType_Matrix6 = 2; + } +} + +/** + * Request: Computer replies with word from the mnemonic + * @next WordRequest + * @next Success + * @next Failure + */ +message WordAck { + required string word = 1; // one word of mnemonic on asked position +} + +/** + * Request: Set U2F counter + * @start + * @next Success + */ +message SetU2FCounter { + optional uint32 u2f_counter = 1; // counter +} diff --git a/accounts/usbwallet/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go index 15bb6fb73b..6278bd8ee0 100644 --- a/accounts/usbwallet/trezor/messages.pb.go +++ b/accounts/usbwallet/trezor/messages.pb.go @@ -3,93 +3,242 @@ package trezor -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + math "math" + + proto "github.com/golang/protobuf/proto" + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf -// * -// Mapping between Trezor wire identifier (uint) and a protobuf message +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +//* +// Mapping between TREZOR wire identifier (uint) and a protobuf message type MessageType int32 const ( - MessageType_MessageType_Initialize MessageType = 0 - MessageType_MessageType_Ping MessageType = 1 - MessageType_MessageType_Success MessageType = 2 - MessageType_MessageType_Failure MessageType = 3 - MessageType_MessageType_ChangePin MessageType = 4 - MessageType_MessageType_WipeDevice MessageType = 5 - MessageType_MessageType_FirmwareErase MessageType = 6 - MessageType_MessageType_FirmwareUpload MessageType = 7 - MessageType_MessageType_FirmwareRequest MessageType = 8 - MessageType_MessageType_GetEntropy MessageType = 9 - MessageType_MessageType_Entropy MessageType = 10 - MessageType_MessageType_GetPublicKey MessageType = 11 - MessageType_MessageType_PublicKey MessageType = 12 - MessageType_MessageType_LoadDevice MessageType = 13 - MessageType_MessageType_ResetDevice MessageType = 14 - MessageType_MessageType_SignTx MessageType = 15 - MessageType_MessageType_SimpleSignTx MessageType = 16 - MessageType_MessageType_Features MessageType = 17 - MessageType_MessageType_PinMatrixRequest MessageType = 18 - MessageType_MessageType_PinMatrixAck MessageType = 19 - MessageType_MessageType_Cancel MessageType = 20 - MessageType_MessageType_TxRequest MessageType = 21 - MessageType_MessageType_TxAck MessageType = 22 - MessageType_MessageType_CipherKeyValue MessageType = 23 - MessageType_MessageType_ClearSession MessageType = 24 - MessageType_MessageType_ApplySettings MessageType = 25 - MessageType_MessageType_ButtonRequest MessageType = 26 - MessageType_MessageType_ButtonAck MessageType = 27 - MessageType_MessageType_ApplyFlags MessageType = 28 - MessageType_MessageType_GetAddress MessageType = 29 - MessageType_MessageType_Address MessageType = 30 - MessageType_MessageType_SelfTest MessageType = 32 - MessageType_MessageType_BackupDevice MessageType = 34 - MessageType_MessageType_EntropyRequest MessageType = 35 - MessageType_MessageType_EntropyAck MessageType = 36 - MessageType_MessageType_SignMessage MessageType = 38 - MessageType_MessageType_VerifyMessage MessageType = 39 - MessageType_MessageType_MessageSignature MessageType = 40 - MessageType_MessageType_PassphraseRequest MessageType = 41 - MessageType_MessageType_PassphraseAck MessageType = 42 - MessageType_MessageType_EstimateTxSize MessageType = 43 - MessageType_MessageType_TxSize MessageType = 44 - MessageType_MessageType_RecoveryDevice MessageType = 45 - MessageType_MessageType_WordRequest MessageType = 46 - MessageType_MessageType_WordAck MessageType = 47 - MessageType_MessageType_CipheredKeyValue MessageType = 48 - MessageType_MessageType_EncryptMessage MessageType = 49 - MessageType_MessageType_EncryptedMessage MessageType = 50 - MessageType_MessageType_DecryptMessage MessageType = 51 - MessageType_MessageType_DecryptedMessage MessageType = 52 - MessageType_MessageType_SignIdentity MessageType = 53 - MessageType_MessageType_SignedIdentity MessageType = 54 - MessageType_MessageType_GetFeatures MessageType = 55 + // Management + MessageType_MessageType_Initialize MessageType = 0 + MessageType_MessageType_Ping MessageType = 1 + MessageType_MessageType_Success MessageType = 2 + MessageType_MessageType_Failure MessageType = 3 + MessageType_MessageType_ChangePin MessageType = 4 + MessageType_MessageType_WipeDevice MessageType = 5 + MessageType_MessageType_GetEntropy MessageType = 9 + MessageType_MessageType_Entropy MessageType = 10 + MessageType_MessageType_LoadDevice MessageType = 13 + MessageType_MessageType_ResetDevice MessageType = 14 + MessageType_MessageType_Features MessageType = 17 + MessageType_MessageType_PinMatrixRequest MessageType = 18 + MessageType_MessageType_PinMatrixAck MessageType = 19 + MessageType_MessageType_Cancel MessageType = 20 + MessageType_MessageType_ClearSession MessageType = 24 + MessageType_MessageType_ApplySettings MessageType = 25 + MessageType_MessageType_ButtonRequest MessageType = 26 + MessageType_MessageType_ButtonAck MessageType = 27 + MessageType_MessageType_ApplyFlags MessageType = 28 + MessageType_MessageType_BackupDevice MessageType = 34 + MessageType_MessageType_EntropyRequest MessageType = 35 + MessageType_MessageType_EntropyAck MessageType = 36 + MessageType_MessageType_PassphraseRequest MessageType = 41 + MessageType_MessageType_PassphraseAck MessageType = 42 + MessageType_MessageType_PassphraseStateRequest MessageType = 77 + MessageType_MessageType_PassphraseStateAck MessageType = 78 + MessageType_MessageType_RecoveryDevice MessageType = 45 + MessageType_MessageType_WordRequest MessageType = 46 + MessageType_MessageType_WordAck MessageType = 47 + MessageType_MessageType_GetFeatures MessageType = 55 + MessageType_MessageType_SetU2FCounter MessageType = 63 + // Bootloader + MessageType_MessageType_FirmwareErase MessageType = 6 + MessageType_MessageType_FirmwareUpload MessageType = 7 + MessageType_MessageType_FirmwareRequest MessageType = 8 + MessageType_MessageType_SelfTest MessageType = 32 + // Bitcoin + MessageType_MessageType_GetPublicKey MessageType = 11 + MessageType_MessageType_PublicKey MessageType = 12 + MessageType_MessageType_SignTx MessageType = 15 + MessageType_MessageType_TxRequest MessageType = 21 + MessageType_MessageType_TxAck MessageType = 22 + MessageType_MessageType_GetAddress MessageType = 29 + MessageType_MessageType_Address MessageType = 30 + MessageType_MessageType_SignMessage MessageType = 38 + MessageType_MessageType_VerifyMessage MessageType = 39 + MessageType_MessageType_MessageSignature MessageType = 40 + // Crypto + MessageType_MessageType_CipherKeyValue MessageType = 23 + MessageType_MessageType_CipheredKeyValue MessageType = 48 + MessageType_MessageType_SignIdentity MessageType = 53 + MessageType_MessageType_SignedIdentity MessageType = 54 + MessageType_MessageType_GetECDHSessionKey MessageType = 61 + MessageType_MessageType_ECDHSessionKey MessageType = 62 + MessageType_MessageType_CosiCommit MessageType = 71 + MessageType_MessageType_CosiCommitment MessageType = 72 + MessageType_MessageType_CosiSign MessageType = 73 + MessageType_MessageType_CosiSignature MessageType = 74 + // Debug + MessageType_MessageType_DebugLinkDecision MessageType = 100 + MessageType_MessageType_DebugLinkGetState MessageType = 101 + MessageType_MessageType_DebugLinkState MessageType = 102 + MessageType_MessageType_DebugLinkStop MessageType = 103 + MessageType_MessageType_DebugLinkLog MessageType = 104 + MessageType_MessageType_DebugLinkMemoryRead MessageType = 110 + MessageType_MessageType_DebugLinkMemory MessageType = 111 + MessageType_MessageType_DebugLinkMemoryWrite MessageType = 112 + MessageType_MessageType_DebugLinkFlashErase MessageType = 113 + // Ethereum + MessageType_MessageType_EthereumGetPublicKey MessageType = 450 + MessageType_MessageType_EthereumPublicKey MessageType = 451 MessageType_MessageType_EthereumGetAddress MessageType = 56 MessageType_MessageType_EthereumAddress MessageType = 57 MessageType_MessageType_EthereumSignTx MessageType = 58 MessageType_MessageType_EthereumTxRequest MessageType = 59 MessageType_MessageType_EthereumTxAck MessageType = 60 - MessageType_MessageType_GetECDHSessionKey MessageType = 61 - MessageType_MessageType_ECDHSessionKey MessageType = 62 - MessageType_MessageType_SetU2FCounter MessageType = 63 MessageType_MessageType_EthereumSignMessage MessageType = 64 MessageType_MessageType_EthereumVerifyMessage MessageType = 65 MessageType_MessageType_EthereumMessageSignature MessageType = 66 - MessageType_MessageType_DebugLinkDecision MessageType = 100 - MessageType_MessageType_DebugLinkGetState MessageType = 101 - MessageType_MessageType_DebugLinkState MessageType = 102 - MessageType_MessageType_DebugLinkStop MessageType = 103 - MessageType_MessageType_DebugLinkLog MessageType = 104 - MessageType_MessageType_DebugLinkMemoryRead MessageType = 110 - MessageType_MessageType_DebugLinkMemory MessageType = 111 - MessageType_MessageType_DebugLinkMemoryWrite MessageType = 112 - MessageType_MessageType_DebugLinkFlashErase MessageType = 113 + // NEM + MessageType_MessageType_NEMGetAddress MessageType = 67 + MessageType_MessageType_NEMAddress MessageType = 68 + MessageType_MessageType_NEMSignTx MessageType = 69 + MessageType_MessageType_NEMSignedTx MessageType = 70 + MessageType_MessageType_NEMDecryptMessage MessageType = 75 + MessageType_MessageType_NEMDecryptedMessage MessageType = 76 + // Lisk + MessageType_MessageType_LiskGetAddress MessageType = 114 + MessageType_MessageType_LiskAddress MessageType = 115 + MessageType_MessageType_LiskSignTx MessageType = 116 + MessageType_MessageType_LiskSignedTx MessageType = 117 + MessageType_MessageType_LiskSignMessage MessageType = 118 + MessageType_MessageType_LiskMessageSignature MessageType = 119 + MessageType_MessageType_LiskVerifyMessage MessageType = 120 + MessageType_MessageType_LiskGetPublicKey MessageType = 121 + MessageType_MessageType_LiskPublicKey MessageType = 122 + // Tezos + MessageType_MessageType_TezosGetAddress MessageType = 150 + MessageType_MessageType_TezosAddress MessageType = 151 + MessageType_MessageType_TezosSignTx MessageType = 152 + MessageType_MessageType_TezosSignedTx MessageType = 153 + MessageType_MessageType_TezosGetPublicKey MessageType = 154 + MessageType_MessageType_TezosPublicKey MessageType = 155 + // Stellar + MessageType_MessageType_StellarSignTx MessageType = 202 + MessageType_MessageType_StellarTxOpRequest MessageType = 203 + MessageType_MessageType_StellarGetAddress MessageType = 207 + MessageType_MessageType_StellarAddress MessageType = 208 + MessageType_MessageType_StellarCreateAccountOp MessageType = 210 + MessageType_MessageType_StellarPaymentOp MessageType = 211 + MessageType_MessageType_StellarPathPaymentOp MessageType = 212 + MessageType_MessageType_StellarManageOfferOp MessageType = 213 + MessageType_MessageType_StellarCreatePassiveOfferOp MessageType = 214 + MessageType_MessageType_StellarSetOptionsOp MessageType = 215 + MessageType_MessageType_StellarChangeTrustOp MessageType = 216 + MessageType_MessageType_StellarAllowTrustOp MessageType = 217 + MessageType_MessageType_StellarAccountMergeOp MessageType = 218 + // omitted: StellarInflationOp is not a supported operation, would be 219 + MessageType_MessageType_StellarManageDataOp MessageType = 220 + MessageType_MessageType_StellarBumpSequenceOp MessageType = 221 + MessageType_MessageType_StellarSignedTx MessageType = 230 + // TRON + MessageType_MessageType_TronGetAddress MessageType = 250 + MessageType_MessageType_TronAddress MessageType = 251 + MessageType_MessageType_TronSignTx MessageType = 252 + MessageType_MessageType_TronSignedTx MessageType = 253 + // Cardano + // dropped Sign/VerifyMessage ids 300-302 + MessageType_MessageType_CardanoSignTx MessageType = 303 + MessageType_MessageType_CardanoTxRequest MessageType = 304 + MessageType_MessageType_CardanoGetPublicKey MessageType = 305 + MessageType_MessageType_CardanoPublicKey MessageType = 306 + MessageType_MessageType_CardanoGetAddress MessageType = 307 + MessageType_MessageType_CardanoAddress MessageType = 308 + MessageType_MessageType_CardanoTxAck MessageType = 309 + MessageType_MessageType_CardanoSignedTx MessageType = 310 + // Ontology + MessageType_MessageType_OntologyGetAddress MessageType = 350 + MessageType_MessageType_OntologyAddress MessageType = 351 + MessageType_MessageType_OntologyGetPublicKey MessageType = 352 + MessageType_MessageType_OntologyPublicKey MessageType = 353 + MessageType_MessageType_OntologySignTransfer MessageType = 354 + MessageType_MessageType_OntologySignedTransfer MessageType = 355 + MessageType_MessageType_OntologySignWithdrawOng MessageType = 356 + MessageType_MessageType_OntologySignedWithdrawOng MessageType = 357 + MessageType_MessageType_OntologySignOntIdRegister MessageType = 358 + MessageType_MessageType_OntologySignedOntIdRegister MessageType = 359 + MessageType_MessageType_OntologySignOntIdAddAttributes MessageType = 360 + MessageType_MessageType_OntologySignedOntIdAddAttributes MessageType = 361 + // Ripple + MessageType_MessageType_RippleGetAddress MessageType = 400 + MessageType_MessageType_RippleAddress MessageType = 401 + MessageType_MessageType_RippleSignTx MessageType = 402 + MessageType_MessageType_RippleSignedTx MessageType = 403 + // Monero + MessageType_MessageType_MoneroTransactionInitRequest MessageType = 501 + MessageType_MessageType_MoneroTransactionInitAck MessageType = 502 + MessageType_MessageType_MoneroTransactionSetInputRequest MessageType = 503 + MessageType_MessageType_MoneroTransactionSetInputAck MessageType = 504 + MessageType_MessageType_MoneroTransactionInputsPermutationRequest MessageType = 505 + MessageType_MessageType_MoneroTransactionInputsPermutationAck MessageType = 506 + MessageType_MessageType_MoneroTransactionInputViniRequest MessageType = 507 + MessageType_MessageType_MoneroTransactionInputViniAck MessageType = 508 + MessageType_MessageType_MoneroTransactionAllInputsSetRequest MessageType = 509 + MessageType_MessageType_MoneroTransactionAllInputsSetAck MessageType = 510 + MessageType_MessageType_MoneroTransactionSetOutputRequest MessageType = 511 + MessageType_MessageType_MoneroTransactionSetOutputAck MessageType = 512 + MessageType_MessageType_MoneroTransactionAllOutSetRequest MessageType = 513 + MessageType_MessageType_MoneroTransactionAllOutSetAck MessageType = 514 + MessageType_MessageType_MoneroTransactionSignInputRequest MessageType = 515 + MessageType_MessageType_MoneroTransactionSignInputAck MessageType = 516 + MessageType_MessageType_MoneroTransactionFinalRequest MessageType = 517 + MessageType_MessageType_MoneroTransactionFinalAck MessageType = 518 + MessageType_MessageType_MoneroKeyImageExportInitRequest MessageType = 530 + MessageType_MessageType_MoneroKeyImageExportInitAck MessageType = 531 + MessageType_MessageType_MoneroKeyImageSyncStepRequest MessageType = 532 + MessageType_MessageType_MoneroKeyImageSyncStepAck MessageType = 533 + MessageType_MessageType_MoneroKeyImageSyncFinalRequest MessageType = 534 + MessageType_MessageType_MoneroKeyImageSyncFinalAck MessageType = 535 + MessageType_MessageType_MoneroGetAddress MessageType = 540 + MessageType_MessageType_MoneroAddress MessageType = 541 + MessageType_MessageType_MoneroGetWatchKey MessageType = 542 + MessageType_MessageType_MoneroWatchKey MessageType = 543 + MessageType_MessageType_DebugMoneroDiagRequest MessageType = 546 + MessageType_MessageType_DebugMoneroDiagAck MessageType = 547 + MessageType_MessageType_MoneroGetTxKeyRequest MessageType = 550 + MessageType_MessageType_MoneroGetTxKeyAck MessageType = 551 + MessageType_MessageType_MoneroLiveRefreshStartRequest MessageType = 552 + MessageType_MessageType_MoneroLiveRefreshStartAck MessageType = 553 + MessageType_MessageType_MoneroLiveRefreshStepRequest MessageType = 554 + MessageType_MessageType_MoneroLiveRefreshStepAck MessageType = 555 + MessageType_MessageType_MoneroLiveRefreshFinalRequest MessageType = 556 + MessageType_MessageType_MoneroLiveRefreshFinalAck MessageType = 557 + // EOS + MessageType_MessageType_EosGetPublicKey MessageType = 600 + MessageType_MessageType_EosPublicKey MessageType = 601 + MessageType_MessageType_EosSignTx MessageType = 602 + MessageType_MessageType_EosTxActionRequest MessageType = 603 + MessageType_MessageType_EosTxActionAck MessageType = 604 + MessageType_MessageType_EosSignedTx MessageType = 605 + // Binance + MessageType_MessageType_BinanceGetAddress MessageType = 700 + MessageType_MessageType_BinanceAddress MessageType = 701 + MessageType_MessageType_BinanceGetPublicKey MessageType = 702 + MessageType_MessageType_BinancePublicKey MessageType = 703 + MessageType_MessageType_BinanceSignTx MessageType = 704 + MessageType_MessageType_BinanceTxRequest MessageType = 705 + MessageType_MessageType_BinanceTransferMsg MessageType = 706 + MessageType_MessageType_BinanceOrderMsg MessageType = 707 + MessageType_MessageType_BinanceCancelMsg MessageType = 708 + MessageType_MessageType_BinanceSignedTx MessageType = 709 ) var MessageType_name = map[int32]string{ @@ -99,64 +248,55 @@ var MessageType_name = map[int32]string{ 3: "MessageType_Failure", 4: "MessageType_ChangePin", 5: "MessageType_WipeDevice", - 6: "MessageType_FirmwareErase", - 7: "MessageType_FirmwareUpload", - 8: "MessageType_FirmwareRequest", 9: "MessageType_GetEntropy", 10: "MessageType_Entropy", - 11: "MessageType_GetPublicKey", - 12: "MessageType_PublicKey", 13: "MessageType_LoadDevice", 14: "MessageType_ResetDevice", - 15: "MessageType_SignTx", - 16: "MessageType_SimpleSignTx", 17: "MessageType_Features", 18: "MessageType_PinMatrixRequest", 19: "MessageType_PinMatrixAck", 20: "MessageType_Cancel", - 21: "MessageType_TxRequest", - 22: "MessageType_TxAck", - 23: "MessageType_CipherKeyValue", 24: "MessageType_ClearSession", 25: "MessageType_ApplySettings", 26: "MessageType_ButtonRequest", 27: "MessageType_ButtonAck", 28: "MessageType_ApplyFlags", - 29: "MessageType_GetAddress", - 30: "MessageType_Address", - 32: "MessageType_SelfTest", 34: "MessageType_BackupDevice", 35: "MessageType_EntropyRequest", 36: "MessageType_EntropyAck", - 38: "MessageType_SignMessage", - 39: "MessageType_VerifyMessage", - 40: "MessageType_MessageSignature", 41: "MessageType_PassphraseRequest", 42: "MessageType_PassphraseAck", - 43: "MessageType_EstimateTxSize", - 44: "MessageType_TxSize", + 77: "MessageType_PassphraseStateRequest", + 78: "MessageType_PassphraseStateAck", 45: "MessageType_RecoveryDevice", 46: "MessageType_WordRequest", 47: "MessageType_WordAck", + 55: "MessageType_GetFeatures", + 63: "MessageType_SetU2FCounter", + 6: "MessageType_FirmwareErase", + 7: "MessageType_FirmwareUpload", + 8: "MessageType_FirmwareRequest", + 32: "MessageType_SelfTest", + 11: "MessageType_GetPublicKey", + 12: "MessageType_PublicKey", + 15: "MessageType_SignTx", + 21: "MessageType_TxRequest", + 22: "MessageType_TxAck", + 29: "MessageType_GetAddress", + 30: "MessageType_Address", + 38: "MessageType_SignMessage", + 39: "MessageType_VerifyMessage", + 40: "MessageType_MessageSignature", + 23: "MessageType_CipherKeyValue", 48: "MessageType_CipheredKeyValue", - 49: "MessageType_EncryptMessage", - 50: "MessageType_EncryptedMessage", - 51: "MessageType_DecryptMessage", - 52: "MessageType_DecryptedMessage", 53: "MessageType_SignIdentity", 54: "MessageType_SignedIdentity", - 55: "MessageType_GetFeatures", - 56: "MessageType_EthereumGetAddress", - 57: "MessageType_EthereumAddress", - 58: "MessageType_EthereumSignTx", - 59: "MessageType_EthereumTxRequest", - 60: "MessageType_EthereumTxAck", 61: "MessageType_GetECDHSessionKey", 62: "MessageType_ECDHSessionKey", - 63: "MessageType_SetU2FCounter", - 64: "MessageType_EthereumSignMessage", - 65: "MessageType_EthereumVerifyMessage", - 66: "MessageType_EthereumMessageSignature", + 71: "MessageType_CosiCommit", + 72: "MessageType_CosiCommitment", + 73: "MessageType_CosiSign", + 74: "MessageType_CosiSignature", 100: "MessageType_DebugLinkDecision", 101: "MessageType_DebugLinkGetState", 102: "MessageType_DebugLinkState", @@ -166,81 +306,331 @@ var MessageType_name = map[int32]string{ 111: "MessageType_DebugLinkMemory", 112: "MessageType_DebugLinkMemoryWrite", 113: "MessageType_DebugLinkFlashErase", + 450: "MessageType_EthereumGetPublicKey", + 451: "MessageType_EthereumPublicKey", + 56: "MessageType_EthereumGetAddress", + 57: "MessageType_EthereumAddress", + 58: "MessageType_EthereumSignTx", + 59: "MessageType_EthereumTxRequest", + 60: "MessageType_EthereumTxAck", + 64: "MessageType_EthereumSignMessage", + 65: "MessageType_EthereumVerifyMessage", + 66: "MessageType_EthereumMessageSignature", + 67: "MessageType_NEMGetAddress", + 68: "MessageType_NEMAddress", + 69: "MessageType_NEMSignTx", + 70: "MessageType_NEMSignedTx", + 75: "MessageType_NEMDecryptMessage", + 76: "MessageType_NEMDecryptedMessage", + 114: "MessageType_LiskGetAddress", + 115: "MessageType_LiskAddress", + 116: "MessageType_LiskSignTx", + 117: "MessageType_LiskSignedTx", + 118: "MessageType_LiskSignMessage", + 119: "MessageType_LiskMessageSignature", + 120: "MessageType_LiskVerifyMessage", + 121: "MessageType_LiskGetPublicKey", + 122: "MessageType_LiskPublicKey", + 150: "MessageType_TezosGetAddress", + 151: "MessageType_TezosAddress", + 152: "MessageType_TezosSignTx", + 153: "MessageType_TezosSignedTx", + 154: "MessageType_TezosGetPublicKey", + 155: "MessageType_TezosPublicKey", + 202: "MessageType_StellarSignTx", + 203: "MessageType_StellarTxOpRequest", + 207: "MessageType_StellarGetAddress", + 208: "MessageType_StellarAddress", + 210: "MessageType_StellarCreateAccountOp", + 211: "MessageType_StellarPaymentOp", + 212: "MessageType_StellarPathPaymentOp", + 213: "MessageType_StellarManageOfferOp", + 214: "MessageType_StellarCreatePassiveOfferOp", + 215: "MessageType_StellarSetOptionsOp", + 216: "MessageType_StellarChangeTrustOp", + 217: "MessageType_StellarAllowTrustOp", + 218: "MessageType_StellarAccountMergeOp", + 220: "MessageType_StellarManageDataOp", + 221: "MessageType_StellarBumpSequenceOp", + 230: "MessageType_StellarSignedTx", + 250: "MessageType_TronGetAddress", + 251: "MessageType_TronAddress", + 252: "MessageType_TronSignTx", + 253: "MessageType_TronSignedTx", + 303: "MessageType_CardanoSignTx", + 304: "MessageType_CardanoTxRequest", + 305: "MessageType_CardanoGetPublicKey", + 306: "MessageType_CardanoPublicKey", + 307: "MessageType_CardanoGetAddress", + 308: "MessageType_CardanoAddress", + 309: "MessageType_CardanoTxAck", + 310: "MessageType_CardanoSignedTx", + 350: "MessageType_OntologyGetAddress", + 351: "MessageType_OntologyAddress", + 352: "MessageType_OntologyGetPublicKey", + 353: "MessageType_OntologyPublicKey", + 354: "MessageType_OntologySignTransfer", + 355: "MessageType_OntologySignedTransfer", + 356: "MessageType_OntologySignWithdrawOng", + 357: "MessageType_OntologySignedWithdrawOng", + 358: "MessageType_OntologySignOntIdRegister", + 359: "MessageType_OntologySignedOntIdRegister", + 360: "MessageType_OntologySignOntIdAddAttributes", + 361: "MessageType_OntologySignedOntIdAddAttributes", + 400: "MessageType_RippleGetAddress", + 401: "MessageType_RippleAddress", + 402: "MessageType_RippleSignTx", + 403: "MessageType_RippleSignedTx", + 501: "MessageType_MoneroTransactionInitRequest", + 502: "MessageType_MoneroTransactionInitAck", + 503: "MessageType_MoneroTransactionSetInputRequest", + 504: "MessageType_MoneroTransactionSetInputAck", + 505: "MessageType_MoneroTransactionInputsPermutationRequest", + 506: "MessageType_MoneroTransactionInputsPermutationAck", + 507: "MessageType_MoneroTransactionInputViniRequest", + 508: "MessageType_MoneroTransactionInputViniAck", + 509: "MessageType_MoneroTransactionAllInputsSetRequest", + 510: "MessageType_MoneroTransactionAllInputsSetAck", + 511: "MessageType_MoneroTransactionSetOutputRequest", + 512: "MessageType_MoneroTransactionSetOutputAck", + 513: "MessageType_MoneroTransactionAllOutSetRequest", + 514: "MessageType_MoneroTransactionAllOutSetAck", + 515: "MessageType_MoneroTransactionSignInputRequest", + 516: "MessageType_MoneroTransactionSignInputAck", + 517: "MessageType_MoneroTransactionFinalRequest", + 518: "MessageType_MoneroTransactionFinalAck", + 530: "MessageType_MoneroKeyImageExportInitRequest", + 531: "MessageType_MoneroKeyImageExportInitAck", + 532: "MessageType_MoneroKeyImageSyncStepRequest", + 533: "MessageType_MoneroKeyImageSyncStepAck", + 534: "MessageType_MoneroKeyImageSyncFinalRequest", + 535: "MessageType_MoneroKeyImageSyncFinalAck", + 540: "MessageType_MoneroGetAddress", + 541: "MessageType_MoneroAddress", + 542: "MessageType_MoneroGetWatchKey", + 543: "MessageType_MoneroWatchKey", + 546: "MessageType_DebugMoneroDiagRequest", + 547: "MessageType_DebugMoneroDiagAck", + 550: "MessageType_MoneroGetTxKeyRequest", + 551: "MessageType_MoneroGetTxKeyAck", + 552: "MessageType_MoneroLiveRefreshStartRequest", + 553: "MessageType_MoneroLiveRefreshStartAck", + 554: "MessageType_MoneroLiveRefreshStepRequest", + 555: "MessageType_MoneroLiveRefreshStepAck", + 556: "MessageType_MoneroLiveRefreshFinalRequest", + 557: "MessageType_MoneroLiveRefreshFinalAck", + 600: "MessageType_EosGetPublicKey", + 601: "MessageType_EosPublicKey", + 602: "MessageType_EosSignTx", + 603: "MessageType_EosTxActionRequest", + 604: "MessageType_EosTxActionAck", + 605: "MessageType_EosSignedTx", + 700: "MessageType_BinanceGetAddress", + 701: "MessageType_BinanceAddress", + 702: "MessageType_BinanceGetPublicKey", + 703: "MessageType_BinancePublicKey", + 704: "MessageType_BinanceSignTx", + 705: "MessageType_BinanceTxRequest", + 706: "MessageType_BinanceTransferMsg", + 707: "MessageType_BinanceOrderMsg", + 708: "MessageType_BinanceCancelMsg", + 709: "MessageType_BinanceSignedTx", } + var MessageType_value = map[string]int32{ - "MessageType_Initialize": 0, - "MessageType_Ping": 1, - "MessageType_Success": 2, - "MessageType_Failure": 3, - "MessageType_ChangePin": 4, - "MessageType_WipeDevice": 5, - "MessageType_FirmwareErase": 6, - "MessageType_FirmwareUpload": 7, - "MessageType_FirmwareRequest": 8, - "MessageType_GetEntropy": 9, - "MessageType_Entropy": 10, - "MessageType_GetPublicKey": 11, - "MessageType_PublicKey": 12, - "MessageType_LoadDevice": 13, - "MessageType_ResetDevice": 14, - "MessageType_SignTx": 15, - "MessageType_SimpleSignTx": 16, - "MessageType_Features": 17, - "MessageType_PinMatrixRequest": 18, - "MessageType_PinMatrixAck": 19, - "MessageType_Cancel": 20, - "MessageType_TxRequest": 21, - "MessageType_TxAck": 22, - "MessageType_CipherKeyValue": 23, - "MessageType_ClearSession": 24, - "MessageType_ApplySettings": 25, - "MessageType_ButtonRequest": 26, - "MessageType_ButtonAck": 27, - "MessageType_ApplyFlags": 28, - "MessageType_GetAddress": 29, - "MessageType_Address": 30, - "MessageType_SelfTest": 32, - "MessageType_BackupDevice": 34, - "MessageType_EntropyRequest": 35, - "MessageType_EntropyAck": 36, - "MessageType_SignMessage": 38, - "MessageType_VerifyMessage": 39, - "MessageType_MessageSignature": 40, - "MessageType_PassphraseRequest": 41, - "MessageType_PassphraseAck": 42, - "MessageType_EstimateTxSize": 43, - "MessageType_TxSize": 44, - "MessageType_RecoveryDevice": 45, - "MessageType_WordRequest": 46, - "MessageType_WordAck": 47, - "MessageType_CipheredKeyValue": 48, - "MessageType_EncryptMessage": 49, - "MessageType_EncryptedMessage": 50, - "MessageType_DecryptMessage": 51, - "MessageType_DecryptedMessage": 52, - "MessageType_SignIdentity": 53, - "MessageType_SignedIdentity": 54, - "MessageType_GetFeatures": 55, - "MessageType_EthereumGetAddress": 56, - "MessageType_EthereumAddress": 57, - "MessageType_EthereumSignTx": 58, - "MessageType_EthereumTxRequest": 59, - "MessageType_EthereumTxAck": 60, - "MessageType_GetECDHSessionKey": 61, - "MessageType_ECDHSessionKey": 62, - "MessageType_SetU2FCounter": 63, - "MessageType_EthereumSignMessage": 64, - "MessageType_EthereumVerifyMessage": 65, - "MessageType_EthereumMessageSignature": 66, - "MessageType_DebugLinkDecision": 100, - "MessageType_DebugLinkGetState": 101, - "MessageType_DebugLinkState": 102, - "MessageType_DebugLinkStop": 103, - "MessageType_DebugLinkLog": 104, - "MessageType_DebugLinkMemoryRead": 110, - "MessageType_DebugLinkMemory": 111, - "MessageType_DebugLinkMemoryWrite": 112, - "MessageType_DebugLinkFlashErase": 113, + "MessageType_Initialize": 0, + "MessageType_Ping": 1, + "MessageType_Success": 2, + "MessageType_Failure": 3, + "MessageType_ChangePin": 4, + "MessageType_WipeDevice": 5, + "MessageType_GetEntropy": 9, + "MessageType_Entropy": 10, + "MessageType_LoadDevice": 13, + "MessageType_ResetDevice": 14, + "MessageType_Features": 17, + "MessageType_PinMatrixRequest": 18, + "MessageType_PinMatrixAck": 19, + "MessageType_Cancel": 20, + "MessageType_ClearSession": 24, + "MessageType_ApplySettings": 25, + "MessageType_ButtonRequest": 26, + "MessageType_ButtonAck": 27, + "MessageType_ApplyFlags": 28, + "MessageType_BackupDevice": 34, + "MessageType_EntropyRequest": 35, + "MessageType_EntropyAck": 36, + "MessageType_PassphraseRequest": 41, + "MessageType_PassphraseAck": 42, + "MessageType_PassphraseStateRequest": 77, + "MessageType_PassphraseStateAck": 78, + "MessageType_RecoveryDevice": 45, + "MessageType_WordRequest": 46, + "MessageType_WordAck": 47, + "MessageType_GetFeatures": 55, + "MessageType_SetU2FCounter": 63, + "MessageType_FirmwareErase": 6, + "MessageType_FirmwareUpload": 7, + "MessageType_FirmwareRequest": 8, + "MessageType_SelfTest": 32, + "MessageType_GetPublicKey": 11, + "MessageType_PublicKey": 12, + "MessageType_SignTx": 15, + "MessageType_TxRequest": 21, + "MessageType_TxAck": 22, + "MessageType_GetAddress": 29, + "MessageType_Address": 30, + "MessageType_SignMessage": 38, + "MessageType_VerifyMessage": 39, + "MessageType_MessageSignature": 40, + "MessageType_CipherKeyValue": 23, + "MessageType_CipheredKeyValue": 48, + "MessageType_SignIdentity": 53, + "MessageType_SignedIdentity": 54, + "MessageType_GetECDHSessionKey": 61, + "MessageType_ECDHSessionKey": 62, + "MessageType_CosiCommit": 71, + "MessageType_CosiCommitment": 72, + "MessageType_CosiSign": 73, + "MessageType_CosiSignature": 74, + "MessageType_DebugLinkDecision": 100, + "MessageType_DebugLinkGetState": 101, + "MessageType_DebugLinkState": 102, + "MessageType_DebugLinkStop": 103, + "MessageType_DebugLinkLog": 104, + "MessageType_DebugLinkMemoryRead": 110, + "MessageType_DebugLinkMemory": 111, + "MessageType_DebugLinkMemoryWrite": 112, + "MessageType_DebugLinkFlashErase": 113, + "MessageType_EthereumGetPublicKey": 450, + "MessageType_EthereumPublicKey": 451, + "MessageType_EthereumGetAddress": 56, + "MessageType_EthereumAddress": 57, + "MessageType_EthereumSignTx": 58, + "MessageType_EthereumTxRequest": 59, + "MessageType_EthereumTxAck": 60, + "MessageType_EthereumSignMessage": 64, + "MessageType_EthereumVerifyMessage": 65, + "MessageType_EthereumMessageSignature": 66, + "MessageType_NEMGetAddress": 67, + "MessageType_NEMAddress": 68, + "MessageType_NEMSignTx": 69, + "MessageType_NEMSignedTx": 70, + "MessageType_NEMDecryptMessage": 75, + "MessageType_NEMDecryptedMessage": 76, + "MessageType_LiskGetAddress": 114, + "MessageType_LiskAddress": 115, + "MessageType_LiskSignTx": 116, + "MessageType_LiskSignedTx": 117, + "MessageType_LiskSignMessage": 118, + "MessageType_LiskMessageSignature": 119, + "MessageType_LiskVerifyMessage": 120, + "MessageType_LiskGetPublicKey": 121, + "MessageType_LiskPublicKey": 122, + "MessageType_TezosGetAddress": 150, + "MessageType_TezosAddress": 151, + "MessageType_TezosSignTx": 152, + "MessageType_TezosSignedTx": 153, + "MessageType_TezosGetPublicKey": 154, + "MessageType_TezosPublicKey": 155, + "MessageType_StellarSignTx": 202, + "MessageType_StellarTxOpRequest": 203, + "MessageType_StellarGetAddress": 207, + "MessageType_StellarAddress": 208, + "MessageType_StellarCreateAccountOp": 210, + "MessageType_StellarPaymentOp": 211, + "MessageType_StellarPathPaymentOp": 212, + "MessageType_StellarManageOfferOp": 213, + "MessageType_StellarCreatePassiveOfferOp": 214, + "MessageType_StellarSetOptionsOp": 215, + "MessageType_StellarChangeTrustOp": 216, + "MessageType_StellarAllowTrustOp": 217, + "MessageType_StellarAccountMergeOp": 218, + "MessageType_StellarManageDataOp": 220, + "MessageType_StellarBumpSequenceOp": 221, + "MessageType_StellarSignedTx": 230, + "MessageType_TronGetAddress": 250, + "MessageType_TronAddress": 251, + "MessageType_TronSignTx": 252, + "MessageType_TronSignedTx": 253, + "MessageType_CardanoSignTx": 303, + "MessageType_CardanoTxRequest": 304, + "MessageType_CardanoGetPublicKey": 305, + "MessageType_CardanoPublicKey": 306, + "MessageType_CardanoGetAddress": 307, + "MessageType_CardanoAddress": 308, + "MessageType_CardanoTxAck": 309, + "MessageType_CardanoSignedTx": 310, + "MessageType_OntologyGetAddress": 350, + "MessageType_OntologyAddress": 351, + "MessageType_OntologyGetPublicKey": 352, + "MessageType_OntologyPublicKey": 353, + "MessageType_OntologySignTransfer": 354, + "MessageType_OntologySignedTransfer": 355, + "MessageType_OntologySignWithdrawOng": 356, + "MessageType_OntologySignedWithdrawOng": 357, + "MessageType_OntologySignOntIdRegister": 358, + "MessageType_OntologySignedOntIdRegister": 359, + "MessageType_OntologySignOntIdAddAttributes": 360, + "MessageType_OntologySignedOntIdAddAttributes": 361, + "MessageType_RippleGetAddress": 400, + "MessageType_RippleAddress": 401, + "MessageType_RippleSignTx": 402, + "MessageType_RippleSignedTx": 403, + "MessageType_MoneroTransactionInitRequest": 501, + "MessageType_MoneroTransactionInitAck": 502, + "MessageType_MoneroTransactionSetInputRequest": 503, + "MessageType_MoneroTransactionSetInputAck": 504, + "MessageType_MoneroTransactionInputsPermutationRequest": 505, + "MessageType_MoneroTransactionInputsPermutationAck": 506, + "MessageType_MoneroTransactionInputViniRequest": 507, + "MessageType_MoneroTransactionInputViniAck": 508, + "MessageType_MoneroTransactionAllInputsSetRequest": 509, + "MessageType_MoneroTransactionAllInputsSetAck": 510, + "MessageType_MoneroTransactionSetOutputRequest": 511, + "MessageType_MoneroTransactionSetOutputAck": 512, + "MessageType_MoneroTransactionAllOutSetRequest": 513, + "MessageType_MoneroTransactionAllOutSetAck": 514, + "MessageType_MoneroTransactionSignInputRequest": 515, + "MessageType_MoneroTransactionSignInputAck": 516, + "MessageType_MoneroTransactionFinalRequest": 517, + "MessageType_MoneroTransactionFinalAck": 518, + "MessageType_MoneroKeyImageExportInitRequest": 530, + "MessageType_MoneroKeyImageExportInitAck": 531, + "MessageType_MoneroKeyImageSyncStepRequest": 532, + "MessageType_MoneroKeyImageSyncStepAck": 533, + "MessageType_MoneroKeyImageSyncFinalRequest": 534, + "MessageType_MoneroKeyImageSyncFinalAck": 535, + "MessageType_MoneroGetAddress": 540, + "MessageType_MoneroAddress": 541, + "MessageType_MoneroGetWatchKey": 542, + "MessageType_MoneroWatchKey": 543, + "MessageType_DebugMoneroDiagRequest": 546, + "MessageType_DebugMoneroDiagAck": 547, + "MessageType_MoneroGetTxKeyRequest": 550, + "MessageType_MoneroGetTxKeyAck": 551, + "MessageType_MoneroLiveRefreshStartRequest": 552, + "MessageType_MoneroLiveRefreshStartAck": 553, + "MessageType_MoneroLiveRefreshStepRequest": 554, + "MessageType_MoneroLiveRefreshStepAck": 555, + "MessageType_MoneroLiveRefreshFinalRequest": 556, + "MessageType_MoneroLiveRefreshFinalAck": 557, + "MessageType_EosGetPublicKey": 600, + "MessageType_EosPublicKey": 601, + "MessageType_EosSignTx": 602, + "MessageType_EosTxActionRequest": 603, + "MessageType_EosTxActionAck": 604, + "MessageType_EosSignedTx": 605, + "MessageType_BinanceGetAddress": 700, + "MessageType_BinanceAddress": 701, + "MessageType_BinanceGetPublicKey": 702, + "MessageType_BinancePublicKey": 703, + "MessageType_BinanceSignTx": 704, + "MessageType_BinanceTxRequest": 705, + "MessageType_BinanceTransferMsg": 706, + "MessageType_BinanceOrderMsg": 707, + "MessageType_BinanceCancelMsg": 708, + "MessageType_BinanceSignedTx": 709, } func (x MessageType) Enum() *MessageType { @@ -248,9 +638,11 @@ func (x MessageType) Enum() *MessageType { *p = x return p } + func (x MessageType) String() string { return proto.EnumName(MessageType_name, int32(x)) } + func (x *MessageType) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType") if err != nil { @@ -259,2823 +651,239 @@ func (x *MessageType) UnmarshalJSON(data []byte) error { *x = MessageType(value) return nil } -func (MessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } -// * -// Request: Reset device to default state and ask for device details -// @next Features -type Initialize struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *Initialize) Reset() { *m = Initialize{} } -func (m *Initialize) String() string { return proto.CompactTextString(m) } -func (*Initialize) ProtoMessage() {} -func (*Initialize) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } - -// * -// Request: Ask for device details (no device reset) -// @next Features -type GetFeatures struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *GetFeatures) Reset() { *m = GetFeatures{} } -func (m *GetFeatures) String() string { return proto.CompactTextString(m) } -func (*GetFeatures) ProtoMessage() {} -func (*GetFeatures) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } - -// * -// Response: Reports various information about the device -// @prev Initialize -// @prev GetFeatures -type Features struct { - Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` - MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` - MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` - PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` - BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` - DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` - PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` - Coins []*CoinType `protobuf:"bytes,11,rep,name=coins" json:"coins,omitempty"` - Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` - Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` - BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` - Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` - PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` - PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` - FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` - NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` - Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Features) Reset() { *m = Features{} } -func (m *Features) String() string { return proto.CompactTextString(m) } -func (*Features) ProtoMessage() {} -func (*Features) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } - -func (m *Features) GetVendor() string { - if m != nil && m.Vendor != nil { - return *m.Vendor - } - return "" -} - -func (m *Features) GetMajorVersion() uint32 { - if m != nil && m.MajorVersion != nil { - return *m.MajorVersion - } - return 0 -} - -func (m *Features) GetMinorVersion() uint32 { - if m != nil && m.MinorVersion != nil { - return *m.MinorVersion - } - return 0 -} - -func (m *Features) GetPatchVersion() uint32 { - if m != nil && m.PatchVersion != nil { - return *m.PatchVersion - } - return 0 -} - -func (m *Features) GetBootloaderMode() bool { - if m != nil && m.BootloaderMode != nil { - return *m.BootloaderMode - } - return false -} - -func (m *Features) GetDeviceId() string { - if m != nil && m.DeviceId != nil { - return *m.DeviceId - } - return "" -} - -func (m *Features) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *Features) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *Features) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return "" -} - -func (m *Features) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *Features) GetCoins() []*CoinType { - if m != nil { - return m.Coins - } - return nil -} - -func (m *Features) GetInitialized() bool { - if m != nil && m.Initialized != nil { - return *m.Initialized - } - return false -} - -func (m *Features) GetRevision() []byte { - if m != nil { - return m.Revision - } - return nil -} - -func (m *Features) GetBootloaderHash() []byte { - if m != nil { - return m.BootloaderHash - } - return nil -} - -func (m *Features) GetImported() bool { - if m != nil && m.Imported != nil { - return *m.Imported - } - return false -} - -func (m *Features) GetPinCached() bool { - if m != nil && m.PinCached != nil { - return *m.PinCached - } - return false -} - -func (m *Features) GetPassphraseCached() bool { - if m != nil && m.PassphraseCached != nil { - return *m.PassphraseCached - } - return false -} - -func (m *Features) GetFirmwarePresent() bool { - if m != nil && m.FirmwarePresent != nil { - return *m.FirmwarePresent - } - return false -} - -func (m *Features) GetNeedsBackup() bool { - if m != nil && m.NeedsBackup != nil { - return *m.NeedsBackup - } - return false -} - -func (m *Features) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags - } - return 0 -} - -// * -// Request: clear session (removes cached PIN, passphrase, etc). -// @next Success -type ClearSession struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *ClearSession) Reset() { *m = ClearSession{} } -func (m *ClearSession) String() string { return proto.CompactTextString(m) } -func (*ClearSession) ProtoMessage() {} -func (*ClearSession) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } - -// * -// Request: change language and/or label of the device -// @next Success -// @next Failure -// @next ButtonRequest -// @next PinMatrixRequest -type ApplySettings struct { - Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` - UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` - Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ApplySettings) Reset() { *m = ApplySettings{} } -func (m *ApplySettings) String() string { return proto.CompactTextString(m) } -func (*ApplySettings) ProtoMessage() {} -func (*ApplySettings) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } - -func (m *ApplySettings) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return "" -} - -func (m *ApplySettings) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *ApplySettings) GetUsePassphrase() bool { - if m != nil && m.UsePassphrase != nil { - return *m.UsePassphrase - } - return false -} - -func (m *ApplySettings) GetHomescreen() []byte { - if m != nil { - return m.Homescreen - } - return nil -} - -// * -// Request: set flags of the device -// @next Success -// @next Failure -type ApplyFlags struct { - Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } -func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } -func (*ApplyFlags) ProtoMessage() {} -func (*ApplyFlags) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } - -func (m *ApplyFlags) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags - } - return 0 -} - -// * -// Request: Starts workflow for setting/changing/removing the PIN -// @next ButtonRequest -// @next PinMatrixRequest -type ChangePin struct { - Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ChangePin) Reset() { *m = ChangePin{} } -func (m *ChangePin) String() string { return proto.CompactTextString(m) } -func (*ChangePin) ProtoMessage() {} -func (*ChangePin) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } - -func (m *ChangePin) GetRemove() bool { - if m != nil && m.Remove != nil { - return *m.Remove - } - return false -} - -// * -// Request: Test if the device is alive, device sends back the message in Success response -// @next Success -type Ping struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Ping) Reset() { *m = Ping{} } -func (m *Ping) String() string { return proto.CompactTextString(m) } -func (*Ping) ProtoMessage() {} -func (*Ping) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} } - -func (m *Ping) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -func (m *Ping) GetButtonProtection() bool { - if m != nil && m.ButtonProtection != nil { - return *m.ButtonProtection - } - return false -} - -func (m *Ping) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *Ping) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -// * -// Response: Success of the previous request -type Success struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Success) Reset() { *m = Success{} } -func (m *Success) String() string { return proto.CompactTextString(m) } -func (*Success) ProtoMessage() {} -func (*Success) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} } - -func (m *Success) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -// * -// Response: Failure of the previous request -type Failure struct { - Code *FailureType `protobuf:"varint,1,opt,name=code,enum=FailureType" json:"code,omitempty"` - Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Failure) Reset() { *m = Failure{} } -func (m *Failure) String() string { return proto.CompactTextString(m) } -func (*Failure) ProtoMessage() {} -func (*Failure) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} } - -func (m *Failure) GetCode() FailureType { - if m != nil && m.Code != nil { - return *m.Code - } - return FailureType_Failure_UnexpectedMessage -} - -func (m *Failure) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message - } - return "" -} - -// * -// Response: Device is waiting for HW button press. -// @next ButtonAck -// @next Cancel -type ButtonRequest struct { - Code *ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=ButtonRequestType" json:"code,omitempty"` - Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } -func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } -func (*ButtonRequest) ProtoMessage() {} -func (*ButtonRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{10} } - -func (m *ButtonRequest) GetCode() ButtonRequestType { - if m != nil && m.Code != nil { - return *m.Code - } - return ButtonRequestType_ButtonRequest_Other -} - -func (m *ButtonRequest) GetData() string { - if m != nil && m.Data != nil { - return *m.Data - } - return "" -} - -// * -// Request: Computer agrees to wait for HW button press -// @prev ButtonRequest -type ButtonAck struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *ButtonAck) Reset() { *m = ButtonAck{} } -func (m *ButtonAck) String() string { return proto.CompactTextString(m) } -func (*ButtonAck) ProtoMessage() {} -func (*ButtonAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{11} } - -// * -// Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme -// @next PinMatrixAck -// @next Cancel -type PinMatrixRequest struct { - Type *PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=PinMatrixRequestType" json:"type,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } -func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } -func (*PinMatrixRequest) ProtoMessage() {} -func (*PinMatrixRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{12} } - -func (m *PinMatrixRequest) GetType() PinMatrixRequestType { - if m != nil && m.Type != nil { - return *m.Type - } - return PinMatrixRequestType_PinMatrixRequestType_Current -} - -// * -// Request: Computer responds with encoded PIN -// @prev PinMatrixRequest -type PinMatrixAck struct { - Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } -func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } -func (*PinMatrixAck) ProtoMessage() {} -func (*PinMatrixAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{13} } - -func (m *PinMatrixAck) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -// * -// Request: Abort last operation that required user interaction -// @prev ButtonRequest -// @prev PinMatrixRequest -// @prev PassphraseRequest -type Cancel struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *Cancel) Reset() { *m = Cancel{} } -func (m *Cancel) String() string { return proto.CompactTextString(m) } -func (*Cancel) ProtoMessage() {} -func (*Cancel) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{14} } - -// * -// Response: Device awaits encryption passphrase -// @next PassphraseAck -// @next Cancel -type PassphraseRequest struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } -func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseRequest) ProtoMessage() {} -func (*PassphraseRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{15} } - -// * -// Request: Send passphrase back -// @prev PassphraseRequest -type PassphraseAck struct { - Passphrase *string `protobuf:"bytes,1,req,name=passphrase" json:"passphrase,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } -func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseAck) ProtoMessage() {} -func (*PassphraseAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{16} } - -func (m *PassphraseAck) GetPassphrase() string { - if m != nil && m.Passphrase != nil { - return *m.Passphrase - } - return "" -} - -// * -// Request: Request a sample of random data generated by hardware RNG. May be used for testing. -// @next ButtonRequest -// @next Entropy -// @next Failure -type GetEntropy struct { - Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *GetEntropy) Reset() { *m = GetEntropy{} } -func (m *GetEntropy) String() string { return proto.CompactTextString(m) } -func (*GetEntropy) ProtoMessage() {} -func (*GetEntropy) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{17} } - -func (m *GetEntropy) GetSize() uint32 { - if m != nil && m.Size != nil { - return *m.Size - } - return 0 -} - -// * -// Response: Reply with random data generated by internal RNG -// @prev GetEntropy -type Entropy struct { - Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Entropy) Reset() { *m = Entropy{} } -func (m *Entropy) String() string { return proto.CompactTextString(m) } -func (*Entropy) ProtoMessage() {} -func (*Entropy) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{18} } - -func (m *Entropy) GetEntropy() []byte { - if m != nil { - return m.Entropy - } - return nil -} - -// * -// Request: Ask device for public key corresponding to address_n path -// @next PassphraseRequest -// @next PublicKey -// @next Failure -type GetPublicKey struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,2,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - ShowDisplay *bool `protobuf:"varint,3,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *GetPublicKey) Reset() { *m = GetPublicKey{} } -func (m *GetPublicKey) String() string { return proto.CompactTextString(m) } -func (*GetPublicKey) ProtoMessage() {} -func (*GetPublicKey) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{19} } - -const Default_GetPublicKey_CoinName string = "Bitcoin" - -func (m *GetPublicKey) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *GetPublicKey) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -func (m *GetPublicKey) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -func (m *GetPublicKey) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_GetPublicKey_CoinName -} - -// * -// Response: Contains public key derived from device private seed -// @prev GetPublicKey -type PublicKey struct { - Node *HDNodeType `protobuf:"bytes,1,req,name=node" json:"node,omitempty"` - Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PublicKey) Reset() { *m = PublicKey{} } -func (m *PublicKey) String() string { return proto.CompactTextString(m) } -func (*PublicKey) ProtoMessage() {} -func (*PublicKey) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{20} } - -func (m *PublicKey) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *PublicKey) GetXpub() string { - if m != nil && m.Xpub != nil { - return *m.Xpub - } - return "" -} - -// * -// Request: Ask device for address corresponding to address_n path -// @next PassphraseRequest -// @next Address -// @next Failure -type GetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - CoinName *string `protobuf:"bytes,2,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - ShowDisplay *bool `protobuf:"varint,3,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,4,opt,name=multisig" json:"multisig,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,5,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *GetAddress) Reset() { *m = GetAddress{} } -func (m *GetAddress) String() string { return proto.CompactTextString(m) } -func (*GetAddress) ProtoMessage() {} -func (*GetAddress) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{21} } - -const Default_GetAddress_CoinName string = "Bitcoin" -const Default_GetAddress_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *GetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *GetAddress) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_GetAddress_CoinName -} - -func (m *GetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -func (m *GetAddress) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *GetAddress) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_GetAddress_ScriptType -} - -// * -// Request: Ask device for Ethereum address corresponding to address_n path -// @next PassphraseRequest -// @next EthereumAddress -// @next Failure -type EthereumGetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } -func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumGetAddress) ProtoMessage() {} -func (*EthereumGetAddress) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{22} } - -func (m *EthereumGetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumGetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay - } - return false -} - -// * -// Response: Contains address derived from device private seed -// @prev GetAddress -type Address struct { - Address *string `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *Address) Reset() { *m = Address{} } -func (m *Address) String() string { return proto.CompactTextString(m) } -func (*Address) ProtoMessage() {} -func (*Address) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{23} } - -func (m *Address) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -// * -// Response: Contains an Ethereum address derived from device private seed -// @prev EthereumGetAddress -type EthereumAddress struct { - Address []byte `protobuf:"bytes,1,req,name=address" json:"address,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } -func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumAddress) ProtoMessage() {} -func (*EthereumAddress) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{24} } - -func (m *EthereumAddress) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -// * -// Request: Request device to wipe all sensitive data and settings -// @next ButtonRequest -type WipeDevice struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *WipeDevice) Reset() { *m = WipeDevice{} } -func (m *WipeDevice) String() string { return proto.CompactTextString(m) } -func (*WipeDevice) ProtoMessage() {} -func (*WipeDevice) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{25} } - -// * -// Request: Load seed and related internal settings from the computer -// @next ButtonRequest -// @next Success -// @next Failure -type LoadDevice struct { - Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` - Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` - U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *LoadDevice) Reset() { *m = LoadDevice{} } -func (m *LoadDevice) String() string { return proto.CompactTextString(m) } -func (*LoadDevice) ProtoMessage() {} -func (*LoadDevice) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{26} } - -const Default_LoadDevice_Language string = "english" - -func (m *LoadDevice) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic - } - return "" -} - -func (m *LoadDevice) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *LoadDevice) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -func (m *LoadDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *LoadDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_LoadDevice_Language -} - -func (m *LoadDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *LoadDevice) GetSkipChecksum() bool { - if m != nil && m.SkipChecksum != nil { - return *m.SkipChecksum - } - return false -} - -func (m *LoadDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -// * -// Request: Ask device to do initialization involving user interaction -// @next EntropyRequest -// @next Failure -type ResetDevice struct { - DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` - Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` - PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ResetDevice) Reset() { *m = ResetDevice{} } -func (m *ResetDevice) String() string { return proto.CompactTextString(m) } -func (*ResetDevice) ProtoMessage() {} -func (*ResetDevice) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{27} } - -const Default_ResetDevice_Strength uint32 = 256 -const Default_ResetDevice_Language string = "english" - -func (m *ResetDevice) GetDisplayRandom() bool { - if m != nil && m.DisplayRandom != nil { - return *m.DisplayRandom - } - return false -} - -func (m *ResetDevice) GetStrength() uint32 { - if m != nil && m.Strength != nil { - return *m.Strength - } - return Default_ResetDevice_Strength -} - -func (m *ResetDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *ResetDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *ResetDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_ResetDevice_Language -} - -func (m *ResetDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *ResetDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -func (m *ResetDevice) GetSkipBackup() bool { - if m != nil && m.SkipBackup != nil { - return *m.SkipBackup - } - return false -} - -// * -// Request: Perform backup of the device seed if not backed up using ResetDevice -// @next ButtonRequest -type BackupDevice struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *BackupDevice) Reset() { *m = BackupDevice{} } -func (m *BackupDevice) String() string { return proto.CompactTextString(m) } -func (*BackupDevice) ProtoMessage() {} -func (*BackupDevice) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{28} } - -// * -// Response: Ask for additional entropy from host computer -// @prev ResetDevice -// @next EntropyAck -type EntropyRequest struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } -func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } -func (*EntropyRequest) ProtoMessage() {} -func (*EntropyRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{29} } - -// * -// Request: Provide additional entropy for seed generation function -// @prev EntropyRequest -// @next ButtonRequest -type EntropyAck struct { - Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EntropyAck) Reset() { *m = EntropyAck{} } -func (m *EntropyAck) String() string { return proto.CompactTextString(m) } -func (*EntropyAck) ProtoMessage() {} -func (*EntropyAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{30} } - -func (m *EntropyAck) GetEntropy() []byte { - if m != nil { - return m.Entropy - } - return nil -} - -// * -// Request: Start recovery workflow asking user for specific words of mnemonic -// Used to recovery device safely even on untrusted computer. -// @next WordRequest -type RecoveryDevice struct { - WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` - PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` - EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` - // 7 reserved for unused recovery method - Type *uint32 `protobuf:"varint,8,opt,name=type" json:"type,omitempty"` - U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } -func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } -func (*RecoveryDevice) ProtoMessage() {} -func (*RecoveryDevice) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{31} } - -const Default_RecoveryDevice_Language string = "english" - -func (m *RecoveryDevice) GetWordCount() uint32 { - if m != nil && m.WordCount != nil { - return *m.WordCount - } - return 0 -} - -func (m *RecoveryDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *RecoveryDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection - } - return false -} - -func (m *RecoveryDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language - } - return Default_RecoveryDevice_Language -} - -func (m *RecoveryDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" -} - -func (m *RecoveryDevice) GetEnforceWordlist() bool { - if m != nil && m.EnforceWordlist != nil { - return *m.EnforceWordlist - } - return false -} - -func (m *RecoveryDevice) GetType() uint32 { - if m != nil && m.Type != nil { - return *m.Type - } - return 0 -} - -func (m *RecoveryDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -func (m *RecoveryDevice) GetDryRun() bool { - if m != nil && m.DryRun != nil { - return *m.DryRun - } - return false -} - -// * -// Response: Device is waiting for user to enter word of the mnemonic -// Its position is shown only on device's internal display. -// @prev RecoveryDevice -// @prev WordAck -type WordRequest struct { - Type *WordRequestType `protobuf:"varint,1,opt,name=type,enum=WordRequestType" json:"type,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *WordRequest) Reset() { *m = WordRequest{} } -func (m *WordRequest) String() string { return proto.CompactTextString(m) } -func (*WordRequest) ProtoMessage() {} -func (*WordRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{32} } - -func (m *WordRequest) GetType() WordRequestType { - if m != nil && m.Type != nil { - return *m.Type - } - return WordRequestType_WordRequestType_Plain -} - -// * -// Request: Computer replies with word from the mnemonic -// @prev WordRequest -// @next WordRequest -// @next Success -// @next Failure -type WordAck struct { - Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *WordAck) Reset() { *m = WordAck{} } -func (m *WordAck) String() string { return proto.CompactTextString(m) } -func (*WordAck) ProtoMessage() {} -func (*WordAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{33} } - -func (m *WordAck) GetWord() string { - if m != nil && m.Word != nil { - return *m.Word - } - return "" -} - -// * -// Request: Ask device to sign message -// @next MessageSignature -// @next Failure -type SignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,req,name=message" json:"message,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,4,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SignMessage) Reset() { *m = SignMessage{} } -func (m *SignMessage) String() string { return proto.CompactTextString(m) } -func (*SignMessage) ProtoMessage() {} -func (*SignMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{34} } - -const Default_SignMessage_CoinName string = "Bitcoin" -const Default_SignMessage_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *SignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *SignMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *SignMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SignMessage_CoinName -} - -func (m *SignMessage) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_SignMessage_ScriptType -} - -// * -// Request: Ask device to verify message -// @next Success -// @next Failure -type VerifyMessage struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *VerifyMessage) Reset() { *m = VerifyMessage{} } -func (m *VerifyMessage) String() string { return proto.CompactTextString(m) } -func (*VerifyMessage) ProtoMessage() {} -func (*VerifyMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{35} } - -const Default_VerifyMessage_CoinName string = "Bitcoin" - -func (m *VerifyMessage) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *VerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *VerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *VerifyMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_VerifyMessage_CoinName -} - -// * -// Response: Signed message -// @prev SignMessage -type MessageSignature struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *MessageSignature) Reset() { *m = MessageSignature{} } -func (m *MessageSignature) String() string { return proto.CompactTextString(m) } -func (*MessageSignature) ProtoMessage() {} -func (*MessageSignature) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{36} } - -func (m *MessageSignature) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *MessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to encrypt message -// @next EncryptedMessage -// @next Failure -type EncryptMessage struct { - Pubkey []byte `protobuf:"bytes,1,opt,name=pubkey" json:"pubkey,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - DisplayOnly *bool `protobuf:"varint,3,opt,name=display_only,json=displayOnly" json:"display_only,omitempty"` - AddressN []uint32 `protobuf:"varint,4,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - CoinName *string `protobuf:"bytes,5,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EncryptMessage) Reset() { *m = EncryptMessage{} } -func (m *EncryptMessage) String() string { return proto.CompactTextString(m) } -func (*EncryptMessage) ProtoMessage() {} -func (*EncryptMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{37} } - -const Default_EncryptMessage_CoinName string = "Bitcoin" - -func (m *EncryptMessage) GetPubkey() []byte { - if m != nil { - return m.Pubkey - } - return nil -} - -func (m *EncryptMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *EncryptMessage) GetDisplayOnly() bool { - if m != nil && m.DisplayOnly != nil { - return *m.DisplayOnly - } - return false -} - -func (m *EncryptMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EncryptMessage) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_EncryptMessage_CoinName -} - -// * -// Response: Encrypted message -// @prev EncryptMessage -type EncryptedMessage struct { - Nonce []byte `protobuf:"bytes,1,opt,name=nonce" json:"nonce,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - Hmac []byte `protobuf:"bytes,3,opt,name=hmac" json:"hmac,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EncryptedMessage) Reset() { *m = EncryptedMessage{} } -func (m *EncryptedMessage) String() string { return proto.CompactTextString(m) } -func (*EncryptedMessage) ProtoMessage() {} -func (*EncryptedMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{38} } - -func (m *EncryptedMessage) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *EncryptedMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *EncryptedMessage) GetHmac() []byte { - if m != nil { - return m.Hmac - } - return nil -} - -// * -// Request: Ask device to decrypt message -// @next Success -// @next Failure -type DecryptMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - Hmac []byte `protobuf:"bytes,4,opt,name=hmac" json:"hmac,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DecryptMessage) Reset() { *m = DecryptMessage{} } -func (m *DecryptMessage) String() string { return proto.CompactTextString(m) } -func (*DecryptMessage) ProtoMessage() {} -func (*DecryptMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{39} } - -func (m *DecryptMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *DecryptMessage) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *DecryptMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *DecryptMessage) GetHmac() []byte { - if m != nil { - return m.Hmac - } - return nil -} - -// * -// Response: Decrypted message -// @prev DecryptedMessage -type DecryptedMessage struct { - Message []byte `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - Address *string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DecryptedMessage) Reset() { *m = DecryptedMessage{} } -func (m *DecryptedMessage) String() string { return proto.CompactTextString(m) } -func (*DecryptedMessage) ProtoMessage() {} -func (*DecryptedMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{40} } - -func (m *DecryptedMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *DecryptedMessage) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -// * -// Request: Ask device to encrypt or decrypt value of given key -// @next CipheredKeyValue -// @next Failure -type CipherKeyValue struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Key *string `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` - Value []byte `protobuf:"bytes,3,opt,name=value" json:"value,omitempty"` - Encrypt *bool `protobuf:"varint,4,opt,name=encrypt" json:"encrypt,omitempty"` - AskOnEncrypt *bool `protobuf:"varint,5,opt,name=ask_on_encrypt,json=askOnEncrypt" json:"ask_on_encrypt,omitempty"` - AskOnDecrypt *bool `protobuf:"varint,6,opt,name=ask_on_decrypt,json=askOnDecrypt" json:"ask_on_decrypt,omitempty"` - Iv []byte `protobuf:"bytes,7,opt,name=iv" json:"iv,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CipherKeyValue) Reset() { *m = CipherKeyValue{} } -func (m *CipherKeyValue) String() string { return proto.CompactTextString(m) } -func (*CipherKeyValue) ProtoMessage() {} -func (*CipherKeyValue) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{41} } - -func (m *CipherKeyValue) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *CipherKeyValue) GetKey() string { - if m != nil && m.Key != nil { - return *m.Key - } - return "" -} - -func (m *CipherKeyValue) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func (m *CipherKeyValue) GetEncrypt() bool { - if m != nil && m.Encrypt != nil { - return *m.Encrypt - } - return false -} - -func (m *CipherKeyValue) GetAskOnEncrypt() bool { - if m != nil && m.AskOnEncrypt != nil { - return *m.AskOnEncrypt - } - return false -} - -func (m *CipherKeyValue) GetAskOnDecrypt() bool { - if m != nil && m.AskOnDecrypt != nil { - return *m.AskOnDecrypt - } - return false -} - -func (m *CipherKeyValue) GetIv() []byte { - if m != nil { - return m.Iv - } - return nil -} - -// * -// Response: Return ciphered/deciphered value -// @prev CipherKeyValue -type CipheredKeyValue struct { - Value []byte `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CipheredKeyValue) Reset() { *m = CipheredKeyValue{} } -func (m *CipheredKeyValue) String() string { return proto.CompactTextString(m) } -func (*CipheredKeyValue) ProtoMessage() {} -func (*CipheredKeyValue) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{42} } - -func (m *CipheredKeyValue) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -// * -// Request: Estimated size of the transaction -// This behaves exactly like SignTx, which means that it can ask using TxRequest -// This call is non-blocking (except possible PassphraseRequest to unlock the seed) -// @next TxSize -// @next Failure -type EstimateTxSize struct { - OutputsCount *uint32 `protobuf:"varint,1,req,name=outputs_count,json=outputsCount" json:"outputs_count,omitempty"` - InputsCount *uint32 `protobuf:"varint,2,req,name=inputs_count,json=inputsCount" json:"inputs_count,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EstimateTxSize) Reset() { *m = EstimateTxSize{} } -func (m *EstimateTxSize) String() string { return proto.CompactTextString(m) } -func (*EstimateTxSize) ProtoMessage() {} -func (*EstimateTxSize) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{43} } - -const Default_EstimateTxSize_CoinName string = "Bitcoin" - -func (m *EstimateTxSize) GetOutputsCount() uint32 { - if m != nil && m.OutputsCount != nil { - return *m.OutputsCount - } - return 0 -} - -func (m *EstimateTxSize) GetInputsCount() uint32 { - if m != nil && m.InputsCount != nil { - return *m.InputsCount - } - return 0 -} - -func (m *EstimateTxSize) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_EstimateTxSize_CoinName -} - -// * -// Response: Estimated size of the transaction -// @prev EstimateTxSize -type TxSize struct { - TxSize *uint32 `protobuf:"varint,1,opt,name=tx_size,json=txSize" json:"tx_size,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxSize) Reset() { *m = TxSize{} } -func (m *TxSize) String() string { return proto.CompactTextString(m) } -func (*TxSize) ProtoMessage() {} -func (*TxSize) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{44} } - -func (m *TxSize) GetTxSize() uint32 { - if m != nil && m.TxSize != nil { - return *m.TxSize - } - return 0 -} - -// * -// Request: Ask device to sign transaction -// @next PassphraseRequest -// @next PinMatrixRequest -// @next TxRequest -// @next Failure -type SignTx struct { - OutputsCount *uint32 `protobuf:"varint,1,req,name=outputs_count,json=outputsCount" json:"outputs_count,omitempty"` - InputsCount *uint32 `protobuf:"varint,2,req,name=inputs_count,json=inputsCount" json:"inputs_count,omitempty"` - CoinName *string `protobuf:"bytes,3,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - Version *uint32 `protobuf:"varint,4,opt,name=version,def=1" json:"version,omitempty"` - LockTime *uint32 `protobuf:"varint,5,opt,name=lock_time,json=lockTime,def=0" json:"lock_time,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SignTx) Reset() { *m = SignTx{} } -func (m *SignTx) String() string { return proto.CompactTextString(m) } -func (*SignTx) ProtoMessage() {} -func (*SignTx) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{45} } - -const Default_SignTx_CoinName string = "Bitcoin" -const Default_SignTx_Version uint32 = 1 -const Default_SignTx_LockTime uint32 = 0 - -func (m *SignTx) GetOutputsCount() uint32 { - if m != nil && m.OutputsCount != nil { - return *m.OutputsCount - } - return 0 -} - -func (m *SignTx) GetInputsCount() uint32 { - if m != nil && m.InputsCount != nil { - return *m.InputsCount - } - return 0 -} - -func (m *SignTx) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SignTx_CoinName -} - -func (m *SignTx) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return Default_SignTx_Version -} - -func (m *SignTx) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return Default_SignTx_LockTime -} - -// * -// Request: Simplified transaction signing -// This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. -// In case of success, the result is returned using TxRequest message. -// @next PassphraseRequest -// @next PinMatrixRequest -// @next TxRequest -// @next Failure -type SimpleSignTx struct { - Inputs []*TxInputType `protobuf:"bytes,1,rep,name=inputs" json:"inputs,omitempty"` - Outputs []*TxOutputType `protobuf:"bytes,2,rep,name=outputs" json:"outputs,omitempty"` - Transactions []*TransactionType `protobuf:"bytes,3,rep,name=transactions" json:"transactions,omitempty"` - CoinName *string `protobuf:"bytes,4,opt,name=coin_name,json=coinName,def=Bitcoin" json:"coin_name,omitempty"` - Version *uint32 `protobuf:"varint,5,opt,name=version,def=1" json:"version,omitempty"` - LockTime *uint32 `protobuf:"varint,6,opt,name=lock_time,json=lockTime,def=0" json:"lock_time,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SimpleSignTx) Reset() { *m = SimpleSignTx{} } -func (m *SimpleSignTx) String() string { return proto.CompactTextString(m) } -func (*SimpleSignTx) ProtoMessage() {} -func (*SimpleSignTx) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{46} } - -const Default_SimpleSignTx_CoinName string = "Bitcoin" -const Default_SimpleSignTx_Version uint32 = 1 -const Default_SimpleSignTx_LockTime uint32 = 0 - -func (m *SimpleSignTx) GetInputs() []*TxInputType { - if m != nil { - return m.Inputs - } - return nil -} - -func (m *SimpleSignTx) GetOutputs() []*TxOutputType { - if m != nil { - return m.Outputs - } - return nil -} - -func (m *SimpleSignTx) GetTransactions() []*TransactionType { - if m != nil { - return m.Transactions - } - return nil -} - -func (m *SimpleSignTx) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return Default_SimpleSignTx_CoinName -} - -func (m *SimpleSignTx) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return Default_SimpleSignTx_Version -} - -func (m *SimpleSignTx) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return Default_SimpleSignTx_LockTime -} - -// * -// Response: Device asks for information for signing transaction or returns the last result -// If request_index is set, device awaits TxAck message (with fields filled in according to request_type) -// If signature_index is set, 'signature' contains signed input of signature_index's input -// @prev SignTx -// @prev SimpleSignTx -// @prev TxAck -type TxRequest struct { - RequestType *RequestType `protobuf:"varint,1,opt,name=request_type,json=requestType,enum=RequestType" json:"request_type,omitempty"` - Details *TxRequestDetailsType `protobuf:"bytes,2,opt,name=details" json:"details,omitempty"` - Serialized *TxRequestSerializedType `protobuf:"bytes,3,opt,name=serialized" json:"serialized,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxRequest) Reset() { *m = TxRequest{} } -func (m *TxRequest) String() string { return proto.CompactTextString(m) } -func (*TxRequest) ProtoMessage() {} -func (*TxRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{47} } - -func (m *TxRequest) GetRequestType() RequestType { - if m != nil && m.RequestType != nil { - return *m.RequestType - } - return RequestType_TXINPUT -} - -func (m *TxRequest) GetDetails() *TxRequestDetailsType { - if m != nil { - return m.Details - } - return nil -} - -func (m *TxRequest) GetSerialized() *TxRequestSerializedType { - if m != nil { - return m.Serialized - } - return nil -} - -// * -// Request: Reported transaction data -// @prev TxRequest -// @next TxRequest -type TxAck struct { - Tx *TransactionType `protobuf:"bytes,1,opt,name=tx" json:"tx,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxAck) Reset() { *m = TxAck{} } -func (m *TxAck) String() string { return proto.CompactTextString(m) } -func (*TxAck) ProtoMessage() {} -func (*TxAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{48} } - -func (m *TxAck) GetTx() *TransactionType { - if m != nil { - return m.Tx - } - return nil -} - -// * -// Request: Ask device to sign transaction -// All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. -// Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. -// @next PassphraseRequest -// @next PinMatrixRequest -// @next EthereumTxRequest -// @next Failure -type EthereumSignTx struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` - GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` - To []byte `protobuf:"bytes,5,opt,name=to" json:"to,omitempty"` - Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` - DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` - DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } -func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } -func (*EthereumSignTx) ProtoMessage() {} -func (*EthereumSignTx) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{49} } - -func (m *EthereumSignTx) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumSignTx) GetNonce() []byte { - if m != nil { - return m.Nonce - } - return nil -} - -func (m *EthereumSignTx) GetGasPrice() []byte { - if m != nil { - return m.GasPrice - } - return nil -} - -func (m *EthereumSignTx) GetGasLimit() []byte { - if m != nil { - return m.GasLimit - } - return nil -} - -func (m *EthereumSignTx) GetTo() []byte { - if m != nil { - return m.To - } - return nil -} - -func (m *EthereumSignTx) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func (m *EthereumSignTx) GetDataInitialChunk() []byte { - if m != nil { - return m.DataInitialChunk - } - return nil -} - -func (m *EthereumSignTx) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength - } - return 0 -} - -func (m *EthereumSignTx) GetChainId() uint32 { - if m != nil && m.ChainId != nil { - return *m.ChainId - } - return 0 -} - -// * -// Response: Device asks for more data from transaction payload, or returns the signature. -// If data_length is set, device awaits that many more bytes of payload. -// Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. -// @prev EthereumSignTx -// @next EthereumTxAck -type EthereumTxRequest struct { - DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` - SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` - SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } -func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } -func (*EthereumTxRequest) ProtoMessage() {} -func (*EthereumTxRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{50} } - -func (m *EthereumTxRequest) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength - } - return 0 -} - -func (m *EthereumTxRequest) GetSignatureV() uint32 { - if m != nil && m.SignatureV != nil { - return *m.SignatureV - } - return 0 -} - -func (m *EthereumTxRequest) GetSignatureR() []byte { - if m != nil { - return m.SignatureR - } - return nil -} - -func (m *EthereumTxRequest) GetSignatureS() []byte { - if m != nil { - return m.SignatureS - } - return nil -} - -// * -// Request: Transaction payload data. -// @prev EthereumTxRequest -// @next EthereumTxRequest -type EthereumTxAck struct { - DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } -func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } -func (*EthereumTxAck) ProtoMessage() {} -func (*EthereumTxAck) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{51} } - -func (m *EthereumTxAck) GetDataChunk() []byte { - if m != nil { - return m.DataChunk - } - return nil -} - -// * -// Request: Ask device to sign message -// @next EthereumMessageSignature -// @next Failure -type EthereumSignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,req,name=message" json:"message,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } -func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumSignMessage) ProtoMessage() {} -func (*EthereumSignMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{52} } - -func (m *EthereumSignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *EthereumSignMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -// * -// Request: Ask device to verify message -// @next Success -// @next Failure -type EthereumVerifyMessage struct { - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } -func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumVerifyMessage) ProtoMessage() {} -func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{53} } - -func (m *EthereumVerifyMessage) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *EthereumVerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *EthereumVerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -// * -// Response: Signed message -// @prev EthereumSignMessage -type EthereumMessageSignature struct { - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } -func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } -func (*EthereumMessageSignature) ProtoMessage() {} -func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{54} } - -func (m *EthereumMessageSignature) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *EthereumMessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to sign identity -// @next SignedIdentity -// @next Failure -type SignIdentity struct { - Identity *IdentityType `protobuf:"bytes,1,opt,name=identity" json:"identity,omitempty"` - ChallengeHidden []byte `protobuf:"bytes,2,opt,name=challenge_hidden,json=challengeHidden" json:"challenge_hidden,omitempty"` - ChallengeVisual *string `protobuf:"bytes,3,opt,name=challenge_visual,json=challengeVisual" json:"challenge_visual,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,4,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SignIdentity) Reset() { *m = SignIdentity{} } -func (m *SignIdentity) String() string { return proto.CompactTextString(m) } -func (*SignIdentity) ProtoMessage() {} -func (*SignIdentity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{55} } - -func (m *SignIdentity) GetIdentity() *IdentityType { - if m != nil { - return m.Identity - } - return nil -} - -func (m *SignIdentity) GetChallengeHidden() []byte { - if m != nil { - return m.ChallengeHidden - } - return nil -} - -func (m *SignIdentity) GetChallengeVisual() string { - if m != nil && m.ChallengeVisual != nil { - return *m.ChallengeVisual - } - return "" -} - -func (m *SignIdentity) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -// * -// Response: Device provides signed identity -// @prev SignIdentity -type SignedIdentity struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - Signature []byte `protobuf:"bytes,3,opt,name=signature" json:"signature,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SignedIdentity) Reset() { *m = SignedIdentity{} } -func (m *SignedIdentity) String() string { return proto.CompactTextString(m) } -func (*SignedIdentity) ProtoMessage() {} -func (*SignedIdentity) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{56} } - -func (m *SignedIdentity) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *SignedIdentity) GetPublicKey() []byte { - if m != nil { - return m.PublicKey - } - return nil -} - -func (m *SignedIdentity) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -// * -// Request: Ask device to generate ECDH session key -// @next ECDHSessionKey -// @next Failure -type GetECDHSessionKey struct { - Identity *IdentityType `protobuf:"bytes,1,opt,name=identity" json:"identity,omitempty"` - PeerPublicKey []byte `protobuf:"bytes,2,opt,name=peer_public_key,json=peerPublicKey" json:"peer_public_key,omitempty"` - EcdsaCurveName *string `protobuf:"bytes,3,opt,name=ecdsa_curve_name,json=ecdsaCurveName" json:"ecdsa_curve_name,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *GetECDHSessionKey) Reset() { *m = GetECDHSessionKey{} } -func (m *GetECDHSessionKey) String() string { return proto.CompactTextString(m) } -func (*GetECDHSessionKey) ProtoMessage() {} -func (*GetECDHSessionKey) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{57} } - -func (m *GetECDHSessionKey) GetIdentity() *IdentityType { - if m != nil { - return m.Identity - } - return nil -} - -func (m *GetECDHSessionKey) GetPeerPublicKey() []byte { - if m != nil { - return m.PeerPublicKey - } - return nil -} - -func (m *GetECDHSessionKey) GetEcdsaCurveName() string { - if m != nil && m.EcdsaCurveName != nil { - return *m.EcdsaCurveName - } - return "" -} - -// * -// Response: Device provides ECDH session key -// @prev GetECDHSessionKey -type ECDHSessionKey struct { - SessionKey []byte `protobuf:"bytes,1,opt,name=session_key,json=sessionKey" json:"session_key,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ECDHSessionKey) Reset() { *m = ECDHSessionKey{} } -func (m *ECDHSessionKey) String() string { return proto.CompactTextString(m) } -func (*ECDHSessionKey) ProtoMessage() {} -func (*ECDHSessionKey) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{58} } - -func (m *ECDHSessionKey) GetSessionKey() []byte { - if m != nil { - return m.SessionKey - } - return nil -} - -// * -// Request: Set U2F counter -// @next Success -type SetU2FCounter struct { - U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } -func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } -func (*SetU2FCounter) ProtoMessage() {} -func (*SetU2FCounter) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{59} } - -func (m *SetU2FCounter) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter - } - return 0 -} - -// * -// Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) -// @next Success -// @next FirmwareRequest -// @next Failure -type FirmwareErase struct { - Length *uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *FirmwareErase) Reset() { *m = FirmwareErase{} } -func (m *FirmwareErase) String() string { return proto.CompactTextString(m) } -func (*FirmwareErase) ProtoMessage() {} -func (*FirmwareErase) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{60} } - -func (m *FirmwareErase) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Response: Ask for firmware chunk -// @next FirmwareUpload -type FirmwareRequest struct { - Offset *uint32 `protobuf:"varint,1,opt,name=offset" json:"offset,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *FirmwareRequest) Reset() { *m = FirmwareRequest{} } -func (m *FirmwareRequest) String() string { return proto.CompactTextString(m) } -func (*FirmwareRequest) ProtoMessage() {} -func (*FirmwareRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{61} } - -func (m *FirmwareRequest) GetOffset() uint32 { - if m != nil && m.Offset != nil { - return *m.Offset - } - return 0 -} - -func (m *FirmwareRequest) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Request: Send firmware in binary form to the device -// @next Success -// @next Failure -type FirmwareUpload struct { - Payload []byte `protobuf:"bytes,1,req,name=payload" json:"payload,omitempty"` - Hash []byte `protobuf:"bytes,2,opt,name=hash" json:"hash,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *FirmwareUpload) Reset() { *m = FirmwareUpload{} } -func (m *FirmwareUpload) String() string { return proto.CompactTextString(m) } -func (*FirmwareUpload) ProtoMessage() {} -func (*FirmwareUpload) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{62} } - -func (m *FirmwareUpload) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -func (m *FirmwareUpload) GetHash() []byte { - if m != nil { - return m.Hash - } - return nil -} - -// * -// Request: Perform a device self-test -// @next Success -// @next Failure -type SelfTest struct { - Payload []byte `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *SelfTest) Reset() { *m = SelfTest{} } -func (m *SelfTest) String() string { return proto.CompactTextString(m) } -func (*SelfTest) ProtoMessage() {} -func (*SelfTest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{63} } - -func (m *SelfTest) GetPayload() []byte { - if m != nil { - return m.Payload - } - return nil -} - -// * -// Request: "Press" the button on the device -// @next Success -type DebugLinkDecision struct { - YesNo *bool `protobuf:"varint,1,req,name=yes_no,json=yesNo" json:"yes_no,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkDecision) Reset() { *m = DebugLinkDecision{} } -func (m *DebugLinkDecision) String() string { return proto.CompactTextString(m) } -func (*DebugLinkDecision) ProtoMessage() {} -func (*DebugLinkDecision) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{64} } - -func (m *DebugLinkDecision) GetYesNo() bool { - if m != nil && m.YesNo != nil { - return *m.YesNo - } - return false -} - -// * -// Request: Computer asks for device state -// @next DebugLinkState -type DebugLinkGetState struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkGetState) Reset() { *m = DebugLinkGetState{} } -func (m *DebugLinkGetState) String() string { return proto.CompactTextString(m) } -func (*DebugLinkGetState) ProtoMessage() {} -func (*DebugLinkGetState) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{65} } - -// * -// Response: Device current state -// @prev DebugLinkGetState -type DebugLinkState struct { - Layout []byte `protobuf:"bytes,1,opt,name=layout" json:"layout,omitempty"` - Pin *string `protobuf:"bytes,2,opt,name=pin" json:"pin,omitempty"` - Matrix *string `protobuf:"bytes,3,opt,name=matrix" json:"matrix,omitempty"` - Mnemonic *string `protobuf:"bytes,4,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,5,opt,name=node" json:"node,omitempty"` - PassphraseProtection *bool `protobuf:"varint,6,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - ResetWord *string `protobuf:"bytes,7,opt,name=reset_word,json=resetWord" json:"reset_word,omitempty"` - ResetEntropy []byte `protobuf:"bytes,8,opt,name=reset_entropy,json=resetEntropy" json:"reset_entropy,omitempty"` - RecoveryFakeWord *string `protobuf:"bytes,9,opt,name=recovery_fake_word,json=recoveryFakeWord" json:"recovery_fake_word,omitempty"` - RecoveryWordPos *uint32 `protobuf:"varint,10,opt,name=recovery_word_pos,json=recoveryWordPos" json:"recovery_word_pos,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkState) Reset() { *m = DebugLinkState{} } -func (m *DebugLinkState) String() string { return proto.CompactTextString(m) } -func (*DebugLinkState) ProtoMessage() {} -func (*DebugLinkState) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{66} } - -func (m *DebugLinkState) GetLayout() []byte { - if m != nil { - return m.Layout - } - return nil -} - -func (m *DebugLinkState) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin - } - return "" -} - -func (m *DebugLinkState) GetMatrix() string { - if m != nil && m.Matrix != nil { - return *m.Matrix - } - return "" -} - -func (m *DebugLinkState) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic - } - return "" -} - -func (m *DebugLinkState) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *DebugLinkState) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection - } - return false -} - -func (m *DebugLinkState) GetResetWord() string { - if m != nil && m.ResetWord != nil { - return *m.ResetWord - } - return "" -} - -func (m *DebugLinkState) GetResetEntropy() []byte { - if m != nil { - return m.ResetEntropy - } - return nil -} - -func (m *DebugLinkState) GetRecoveryFakeWord() string { - if m != nil && m.RecoveryFakeWord != nil { - return *m.RecoveryFakeWord - } - return "" -} - -func (m *DebugLinkState) GetRecoveryWordPos() uint32 { - if m != nil && m.RecoveryWordPos != nil { - return *m.RecoveryWordPos - } - return 0 -} - -// * -// Request: Ask device to restart -type DebugLinkStop struct { - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkStop) Reset() { *m = DebugLinkStop{} } -func (m *DebugLinkStop) String() string { return proto.CompactTextString(m) } -func (*DebugLinkStop) ProtoMessage() {} -func (*DebugLinkStop) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{67} } - -// * -// Response: Device wants host to log event -type DebugLinkLog struct { - Level *uint32 `protobuf:"varint,1,opt,name=level" json:"level,omitempty"` - Bucket *string `protobuf:"bytes,2,opt,name=bucket" json:"bucket,omitempty"` - Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkLog) Reset() { *m = DebugLinkLog{} } -func (m *DebugLinkLog) String() string { return proto.CompactTextString(m) } -func (*DebugLinkLog) ProtoMessage() {} -func (*DebugLinkLog) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{68} } - -func (m *DebugLinkLog) GetLevel() uint32 { - if m != nil && m.Level != nil { - return *m.Level - } - return 0 -} - -func (m *DebugLinkLog) GetBucket() string { - if m != nil && m.Bucket != nil { - return *m.Bucket - } - return "" -} - -func (m *DebugLinkLog) GetText() string { - if m != nil && m.Text != nil { - return *m.Text - } - return "" -} - -// * -// Request: Read memory from device -// @next DebugLinkMemory -type DebugLinkMemoryRead struct { - Address *uint32 `protobuf:"varint,1,opt,name=address" json:"address,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkMemoryRead) Reset() { *m = DebugLinkMemoryRead{} } -func (m *DebugLinkMemoryRead) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemoryRead) ProtoMessage() {} -func (*DebugLinkMemoryRead) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{69} } - -func (m *DebugLinkMemoryRead) GetAddress() uint32 { - if m != nil && m.Address != nil { - return *m.Address - } - return 0 -} - -func (m *DebugLinkMemoryRead) GetLength() uint32 { - if m != nil && m.Length != nil { - return *m.Length - } - return 0 -} - -// * -// Response: Device sends memory back -// @prev DebugLinkMemoryRead -type DebugLinkMemory struct { - Memory []byte `protobuf:"bytes,1,opt,name=memory" json:"memory,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkMemory) Reset() { *m = DebugLinkMemory{} } -func (m *DebugLinkMemory) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemory) ProtoMessage() {} -func (*DebugLinkMemory) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{70} } - -func (m *DebugLinkMemory) GetMemory() []byte { - if m != nil { - return m.Memory - } - return nil -} - -// * -// Request: Write memory to device. -// WARNING: Writing to the wrong location can irreparably break the device. -type DebugLinkMemoryWrite struct { - Address *uint32 `protobuf:"varint,1,opt,name=address" json:"address,omitempty"` - Memory []byte `protobuf:"bytes,2,opt,name=memory" json:"memory,omitempty"` - Flash *bool `protobuf:"varint,3,opt,name=flash" json:"flash,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkMemoryWrite) Reset() { *m = DebugLinkMemoryWrite{} } -func (m *DebugLinkMemoryWrite) String() string { return proto.CompactTextString(m) } -func (*DebugLinkMemoryWrite) ProtoMessage() {} -func (*DebugLinkMemoryWrite) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{71} } - -func (m *DebugLinkMemoryWrite) GetAddress() uint32 { - if m != nil && m.Address != nil { - return *m.Address - } - return 0 -} - -func (m *DebugLinkMemoryWrite) GetMemory() []byte { - if m != nil { - return m.Memory - } - return nil -} - -func (m *DebugLinkMemoryWrite) GetFlash() bool { - if m != nil && m.Flash != nil { - return *m.Flash - } - return false -} - -// * -// Request: Erase block of flash on device -// WARNING: Writing to the wrong location can irreparably break the device. -type DebugLinkFlashErase struct { - Sector *uint32 `protobuf:"varint,1,opt,name=sector" json:"sector,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *DebugLinkFlashErase) Reset() { *m = DebugLinkFlashErase{} } -func (m *DebugLinkFlashErase) String() string { return proto.CompactTextString(m) } -func (*DebugLinkFlashErase) ProtoMessage() {} -func (*DebugLinkFlashErase) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{72} } - -func (m *DebugLinkFlashErase) GetSector() uint32 { - if m != nil && m.Sector != nil { - return *m.Sector - } - return 0 +func (MessageType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_4dc296cbfe5ffcd5, []int{0} +} + +var E_WireIn = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50002, + Name: "hw.trezor.messages.wire_in", + Tag: "varint,50002,opt,name=wire_in", + Filename: "messages.proto", +} + +var E_WireOut = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50003, + Name: "hw.trezor.messages.wire_out", + Tag: "varint,50003,opt,name=wire_out", + Filename: "messages.proto", +} + +var E_WireDebugIn = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50004, + Name: "hw.trezor.messages.wire_debug_in", + Tag: "varint,50004,opt,name=wire_debug_in", + Filename: "messages.proto", +} + +var E_WireDebugOut = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50005, + Name: "hw.trezor.messages.wire_debug_out", + Tag: "varint,50005,opt,name=wire_debug_out", + Filename: "messages.proto", +} + +var E_WireTiny = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50006, + Name: "hw.trezor.messages.wire_tiny", + Tag: "varint,50006,opt,name=wire_tiny", + Filename: "messages.proto", +} + +var E_WireBootloader = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50007, + Name: "hw.trezor.messages.wire_bootloader", + Tag: "varint,50007,opt,name=wire_bootloader", + Filename: "messages.proto", +} + +var E_WireNoFsm = &proto.ExtensionDesc{ + ExtendedType: (*descriptor.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50008, + Name: "hw.trezor.messages.wire_no_fsm", + Tag: "varint,50008,opt,name=wire_no_fsm", + Filename: "messages.proto", } func init() { - proto.RegisterType((*Initialize)(nil), "Initialize") - proto.RegisterType((*GetFeatures)(nil), "GetFeatures") - proto.RegisterType((*Features)(nil), "Features") - proto.RegisterType((*ClearSession)(nil), "ClearSession") - proto.RegisterType((*ApplySettings)(nil), "ApplySettings") - proto.RegisterType((*ApplyFlags)(nil), "ApplyFlags") - proto.RegisterType((*ChangePin)(nil), "ChangePin") - proto.RegisterType((*Ping)(nil), "Ping") - proto.RegisterType((*Success)(nil), "Success") - proto.RegisterType((*Failure)(nil), "Failure") - proto.RegisterType((*ButtonRequest)(nil), "ButtonRequest") - proto.RegisterType((*ButtonAck)(nil), "ButtonAck") - proto.RegisterType((*PinMatrixRequest)(nil), "PinMatrixRequest") - proto.RegisterType((*PinMatrixAck)(nil), "PinMatrixAck") - proto.RegisterType((*Cancel)(nil), "Cancel") - proto.RegisterType((*PassphraseRequest)(nil), "PassphraseRequest") - proto.RegisterType((*PassphraseAck)(nil), "PassphraseAck") - proto.RegisterType((*GetEntropy)(nil), "GetEntropy") - proto.RegisterType((*Entropy)(nil), "Entropy") - proto.RegisterType((*GetPublicKey)(nil), "GetPublicKey") - proto.RegisterType((*PublicKey)(nil), "PublicKey") - proto.RegisterType((*GetAddress)(nil), "GetAddress") - proto.RegisterType((*EthereumGetAddress)(nil), "EthereumGetAddress") - proto.RegisterType((*Address)(nil), "Address") - proto.RegisterType((*EthereumAddress)(nil), "EthereumAddress") - proto.RegisterType((*WipeDevice)(nil), "WipeDevice") - proto.RegisterType((*LoadDevice)(nil), "LoadDevice") - proto.RegisterType((*ResetDevice)(nil), "ResetDevice") - proto.RegisterType((*BackupDevice)(nil), "BackupDevice") - proto.RegisterType((*EntropyRequest)(nil), "EntropyRequest") - proto.RegisterType((*EntropyAck)(nil), "EntropyAck") - proto.RegisterType((*RecoveryDevice)(nil), "RecoveryDevice") - proto.RegisterType((*WordRequest)(nil), "WordRequest") - proto.RegisterType((*WordAck)(nil), "WordAck") - proto.RegisterType((*SignMessage)(nil), "SignMessage") - proto.RegisterType((*VerifyMessage)(nil), "VerifyMessage") - proto.RegisterType((*MessageSignature)(nil), "MessageSignature") - proto.RegisterType((*EncryptMessage)(nil), "EncryptMessage") - proto.RegisterType((*EncryptedMessage)(nil), "EncryptedMessage") - proto.RegisterType((*DecryptMessage)(nil), "DecryptMessage") - proto.RegisterType((*DecryptedMessage)(nil), "DecryptedMessage") - proto.RegisterType((*CipherKeyValue)(nil), "CipherKeyValue") - proto.RegisterType((*CipheredKeyValue)(nil), "CipheredKeyValue") - proto.RegisterType((*EstimateTxSize)(nil), "EstimateTxSize") - proto.RegisterType((*TxSize)(nil), "TxSize") - proto.RegisterType((*SignTx)(nil), "SignTx") - proto.RegisterType((*SimpleSignTx)(nil), "SimpleSignTx") - proto.RegisterType((*TxRequest)(nil), "TxRequest") - proto.RegisterType((*TxAck)(nil), "TxAck") - proto.RegisterType((*EthereumSignTx)(nil), "EthereumSignTx") - proto.RegisterType((*EthereumTxRequest)(nil), "EthereumTxRequest") - proto.RegisterType((*EthereumTxAck)(nil), "EthereumTxAck") - proto.RegisterType((*EthereumSignMessage)(nil), "EthereumSignMessage") - proto.RegisterType((*EthereumVerifyMessage)(nil), "EthereumVerifyMessage") - proto.RegisterType((*EthereumMessageSignature)(nil), "EthereumMessageSignature") - proto.RegisterType((*SignIdentity)(nil), "SignIdentity") - proto.RegisterType((*SignedIdentity)(nil), "SignedIdentity") - proto.RegisterType((*GetECDHSessionKey)(nil), "GetECDHSessionKey") - proto.RegisterType((*ECDHSessionKey)(nil), "ECDHSessionKey") - proto.RegisterType((*SetU2FCounter)(nil), "SetU2FCounter") - proto.RegisterType((*FirmwareErase)(nil), "FirmwareErase") - proto.RegisterType((*FirmwareRequest)(nil), "FirmwareRequest") - proto.RegisterType((*FirmwareUpload)(nil), "FirmwareUpload") - proto.RegisterType((*SelfTest)(nil), "SelfTest") - proto.RegisterType((*DebugLinkDecision)(nil), "DebugLinkDecision") - proto.RegisterType((*DebugLinkGetState)(nil), "DebugLinkGetState") - proto.RegisterType((*DebugLinkState)(nil), "DebugLinkState") - proto.RegisterType((*DebugLinkStop)(nil), "DebugLinkStop") - proto.RegisterType((*DebugLinkLog)(nil), "DebugLinkLog") - proto.RegisterType((*DebugLinkMemoryRead)(nil), "DebugLinkMemoryRead") - proto.RegisterType((*DebugLinkMemory)(nil), "DebugLinkMemory") - proto.RegisterType((*DebugLinkMemoryWrite)(nil), "DebugLinkMemoryWrite") - proto.RegisterType((*DebugLinkFlashErase)(nil), "DebugLinkFlashErase") - proto.RegisterEnum("MessageType", MessageType_name, MessageType_value) + proto.RegisterEnum("hw.trezor.messages.MessageType", MessageType_name, MessageType_value) + proto.RegisterExtension(E_WireIn) + proto.RegisterExtension(E_WireOut) + proto.RegisterExtension(E_WireDebugIn) + proto.RegisterExtension(E_WireDebugOut) + proto.RegisterExtension(E_WireTiny) + proto.RegisterExtension(E_WireBootloader) + proto.RegisterExtension(E_WireNoFsm) } -func init() { proto.RegisterFile("messages.proto", fileDescriptor1) } +func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } -var fileDescriptor1 = []byte{ - // 3424 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5a, 0xcb, 0x6f, 0xdc, 0x46, - 0x9a, 0x5f, 0x76, 0xb7, 0xfa, 0xf1, 0x35, 0xbb, 0x55, 0xa2, 0x2d, 0xbb, 0x2d, 0x5b, 0xb6, 0x4c, - 0xc9, 0xb6, 0x64, 0x27, 0xed, 0x44, 0x79, 0x6c, 0xd6, 0xbb, 0x79, 0xc8, 0x7a, 0xd8, 0xde, 0xd8, - 0x8e, 0xc0, 0x56, 0x9c, 0xdb, 0x12, 0x14, 0x59, 0xea, 0xae, 0x55, 0x37, 0xc9, 0xf0, 0xa1, 0xa8, - 0x7d, 0xd8, 0xeb, 0xee, 0x65, 0x81, 0xec, 0x69, 0x73, 0x1a, 0xe4, 0x36, 0x19, 0x04, 0x18, 0x0c, - 0x30, 0x18, 0x60, 0x72, 0x9a, 0x3f, 0x60, 0xfe, 0x8b, 0x39, 0xce, 0x1f, 0x30, 0xe7, 0x41, 0x3d, - 0x48, 0x16, 0x29, 0xb6, 0x6c, 0x27, 0xc0, 0x5c, 0x04, 0xd6, 0x57, 0xbf, 0xfe, 0xea, 0x7b, 0xd5, - 0x57, 0x5f, 0x7d, 0x25, 0xe8, 0x4e, 0x70, 0x18, 0x5a, 0x43, 0x1c, 0xf6, 0xfd, 0xc0, 0x8b, 0xbc, - 0xa5, 0x76, 0x34, 0xf5, 0x93, 0x81, 0xae, 0x02, 0x3c, 0x71, 0x49, 0x44, 0xac, 0x31, 0x79, 0x89, - 0xf5, 0x0e, 0xb4, 0x1f, 0xe1, 0x68, 0x0f, 0x5b, 0x51, 0x1c, 0xe0, 0x50, 0xff, 0x69, 0x0e, 0x9a, - 0xc9, 0x40, 0xbb, 0x04, 0xf5, 0x13, 0xec, 0x3a, 0x5e, 0xd0, 0x53, 0x56, 0x94, 0xf5, 0x96, 0x21, - 0x46, 0xda, 0x2a, 0x74, 0x26, 0xd6, 0x7f, 0x7a, 0x81, 0x79, 0x82, 0x83, 0x90, 0x78, 0x6e, 0xaf, - 0xb2, 0xa2, 0xac, 0x77, 0x0c, 0x95, 0x11, 0x5f, 0x70, 0x1a, 0x03, 0x11, 0x57, 0x02, 0x55, 0x05, - 0x88, 0x12, 0x25, 0x90, 0x6f, 0x45, 0xf6, 0x28, 0x05, 0xd5, 0x38, 0x88, 0x11, 0x13, 0xd0, 0x1d, - 0x98, 0x3f, 0xf4, 0xbc, 0x68, 0xec, 0x59, 0x0e, 0x0e, 0xcc, 0x89, 0xe7, 0xe0, 0xde, 0xdc, 0x8a, - 0xb2, 0xde, 0x34, 0xba, 0x19, 0xf9, 0x99, 0xe7, 0x60, 0xed, 0x2a, 0xb4, 0x1c, 0x7c, 0x42, 0x6c, - 0x6c, 0x12, 0xa7, 0x57, 0x67, 0x22, 0x37, 0x39, 0xe1, 0x89, 0xa3, 0xdd, 0x82, 0xae, 0x4f, 0x5c, - 0x93, 0xda, 0x00, 0xdb, 0x11, 0x5d, 0xab, 0xc1, 0x98, 0x74, 0x7c, 0xe2, 0xee, 0xa7, 0x44, 0xed, - 0x3d, 0x58, 0xf4, 0xad, 0x30, 0xf4, 0x47, 0x81, 0x15, 0x62, 0x19, 0xdd, 0x64, 0xe8, 0x8b, 0xd9, - 0xa4, 0xf4, 0xa3, 0x25, 0x68, 0x8e, 0x2d, 0x77, 0x18, 0x5b, 0x43, 0xdc, 0x6b, 0xf1, 0x75, 0x93, - 0xb1, 0x76, 0x11, 0xe6, 0xc6, 0xd6, 0x21, 0x1e, 0xf7, 0x80, 0x4d, 0xf0, 0x81, 0x76, 0x03, 0xe6, - 0x6c, 0x8f, 0xb8, 0x61, 0xaf, 0xbd, 0x52, 0x5d, 0x6f, 0x6f, 0xb6, 0xfa, 0xdb, 0x1e, 0x71, 0x0f, - 0xa6, 0x3e, 0x36, 0x38, 0x5d, 0x5b, 0x81, 0x36, 0x49, 0xbd, 0xe4, 0xf4, 0x54, 0xb6, 0xba, 0x4c, - 0xa2, 0x8b, 0x06, 0xf8, 0x84, 0x30, 0xb3, 0x75, 0x56, 0x94, 0x75, 0xd5, 0x48, 0xc7, 0x05, 0x93, - 0x8d, 0xac, 0x70, 0xd4, 0xeb, 0x32, 0x88, 0x64, 0xb2, 0xc7, 0x56, 0x38, 0xa2, 0x4c, 0xc8, 0xc4, - 0xf7, 0x82, 0x08, 0x3b, 0xbd, 0x79, 0xb6, 0x46, 0x3a, 0xd6, 0x96, 0x01, 0xa8, 0xc5, 0x6c, 0xcb, - 0x1e, 0x61, 0xa7, 0x87, 0xd8, 0x6c, 0xcb, 0x27, 0xee, 0x36, 0x23, 0x68, 0xf7, 0x60, 0x41, 0xb2, - 0x94, 0x40, 0x2d, 0x30, 0x14, 0xca, 0x26, 0x04, 0x78, 0x03, 0xd0, 0x11, 0x09, 0x26, 0xdf, 0x58, - 0x01, 0x35, 0x2a, 0x0e, 0xb1, 0x1b, 0xf5, 0x34, 0x86, 0x9d, 0x4f, 0xe8, 0xfb, 0x9c, 0xac, 0xdd, - 0x04, 0xd5, 0xc5, 0xd8, 0x09, 0xcd, 0x43, 0xcb, 0x3e, 0x8e, 0xfd, 0xde, 0x05, 0xae, 0x3a, 0xa3, - 0x3d, 0x64, 0x24, 0x6a, 0xd3, 0xa3, 0xb1, 0x35, 0x0c, 0x7b, 0x17, 0x59, 0xb8, 0xf0, 0x81, 0xde, - 0x05, 0x75, 0x7b, 0x8c, 0xad, 0x60, 0x80, 0x43, 0x6a, 0x04, 0xfd, 0x7f, 0x14, 0xe8, 0x6c, 0xf9, - 0xfe, 0x78, 0x3a, 0xc0, 0x51, 0x44, 0xdc, 0x61, 0x98, 0xf3, 0x93, 0x32, 0xcb, 0x4f, 0x15, 0xd9, - 0x4f, 0xb7, 0xa0, 0x1b, 0xd3, 0x38, 0x48, 0xf5, 0x61, 0x61, 0xdc, 0x34, 0x3a, 0x71, 0x88, 0xf7, - 0x53, 0xa2, 0x76, 0x1d, 0x60, 0xe4, 0x4d, 0x70, 0x68, 0x07, 0x18, 0xf3, 0x20, 0x56, 0x0d, 0x89, - 0xa2, 0xeb, 0x00, 0x4c, 0x92, 0x3d, 0x2a, 0x68, 0x26, 0xbe, 0x22, 0x8b, 0xbf, 0x0a, 0xad, 0xed, - 0x91, 0xe5, 0x0e, 0xf1, 0x3e, 0x71, 0xe9, 0xd6, 0x0b, 0xf0, 0xc4, 0x3b, 0xe1, 0x72, 0x36, 0x0d, - 0x31, 0xd2, 0x7f, 0xa3, 0x40, 0x6d, 0x9f, 0xb8, 0x43, 0xad, 0x07, 0x0d, 0xb1, 0xc9, 0x85, 0x26, - 0xc9, 0x90, 0xfa, 0xe5, 0x30, 0x8e, 0x22, 0x2f, 0x17, 0xeb, 0x15, 0xee, 0x17, 0x3e, 0x21, 0x45, - 0xee, 0xd9, 0x5d, 0x51, 0x7d, 0xa3, 0x5d, 0x51, 0x9b, 0xbd, 0x2b, 0xf4, 0x55, 0x68, 0x0c, 0x62, - 0xdb, 0xc6, 0x61, 0x38, 0x5b, 0x5a, 0x7d, 0x17, 0x1a, 0x7b, 0x16, 0x19, 0xc7, 0x01, 0xd6, 0x56, - 0xa0, 0x66, 0xd3, 0xcd, 0x4d, 0x11, 0xdd, 0x4d, 0xb5, 0x2f, 0xe8, 0x6c, 0x57, 0xb0, 0x19, 0x99, - 0x4d, 0x25, 0xcf, 0xe6, 0x73, 0xe8, 0x3c, 0x64, 0xba, 0x19, 0xf8, 0xeb, 0x18, 0x87, 0x91, 0x76, - 0x3b, 0xc7, 0x4c, 0xeb, 0xe7, 0x66, 0x25, 0x96, 0x1a, 0xd4, 0x1c, 0x2b, 0xb2, 0x04, 0x3f, 0xf6, - 0xad, 0xb7, 0xa1, 0xc5, 0xe1, 0x5b, 0xf6, 0xb1, 0xfe, 0x31, 0xa0, 0x7d, 0xe2, 0x3e, 0xb3, 0xa2, - 0x80, 0x9c, 0x26, 0xcc, 0x37, 0xa0, 0x46, 0x33, 0xaa, 0x60, 0xbe, 0xd8, 0x2f, 0x02, 0x38, 0x7f, - 0x0a, 0xd1, 0x57, 0x40, 0x4d, 0x67, 0xb7, 0xec, 0x63, 0x0d, 0x41, 0xd5, 0x27, 0x6e, 0x4f, 0x59, - 0xa9, 0xac, 0xb7, 0x0c, 0xfa, 0xa9, 0x37, 0xa1, 0xbe, 0x6d, 0xb9, 0x36, 0x1e, 0xeb, 0x17, 0x60, - 0x21, 0x8b, 0x29, 0xc1, 0x4a, 0xbf, 0x0f, 0x9d, 0x8c, 0x48, 0x39, 0x5c, 0x07, 0x90, 0xc2, 0x91, - 0x33, 0x92, 0x28, 0xfa, 0x0a, 0xc0, 0x23, 0x1c, 0xed, 0xba, 0x51, 0xe0, 0xf9, 0x53, 0xaa, 0x5f, - 0x48, 0x5e, 0x72, 0x5c, 0xc7, 0x60, 0xdf, 0xd4, 0x31, 0xc9, 0x74, 0x0f, 0x1a, 0x98, 0x7f, 0x32, - 0x84, 0x6a, 0x24, 0x43, 0xfd, 0x57, 0x0a, 0xa8, 0x8f, 0x70, 0xb4, 0x1f, 0x1f, 0x8e, 0x89, 0xfd, - 0x39, 0x9e, 0xd2, 0xec, 0x6a, 0x39, 0x4e, 0x80, 0xc3, 0xd0, 0xa4, 0xf2, 0x57, 0xd7, 0x3b, 0x46, - 0x53, 0x10, 0x9e, 0x6b, 0xeb, 0x80, 0xb0, 0xed, 0x84, 0x96, 0x69, 0xc7, 0xc1, 0x09, 0x36, 0x5d, - 0x6b, 0x92, 0xb8, 0xa8, 0xcb, 0xe8, 0xdb, 0x94, 0xfc, 0xdc, 0x9a, 0x60, 0xba, 0xbd, 0xc3, 0x91, - 0xf7, 0x8d, 0xe9, 0x90, 0xd0, 0x1f, 0x5b, 0x53, 0x11, 0x6f, 0x6d, 0x4a, 0xdb, 0xe1, 0x24, 0x6d, - 0x0d, 0x5a, 0x34, 0x09, 0x72, 0x2e, 0x34, 0xc2, 0x5a, 0x0f, 0x1a, 0x0f, 0x49, 0x44, 0x69, 0x46, - 0x93, 0xfe, 0xa5, 0x8c, 0xf4, 0xcf, 0xa0, 0x95, 0x09, 0x77, 0x03, 0x6a, 0x2e, 0x77, 0x77, 0x65, - 0xbd, 0xbd, 0xd9, 0xee, 0x3f, 0xde, 0x79, 0xee, 0x39, 0x22, 0x74, 0x5c, 0xe1, 0xe7, 0x53, 0x3f, - 0x3e, 0x4c, 0xfc, 0x4c, 0xbf, 0xf5, 0xbf, 0x2a, 0xcc, 0x54, 0x5b, 0x5c, 0x89, 0xf3, 0x15, 0xcc, - 0xc9, 0x54, 0x99, 0x21, 0xd3, 0xeb, 0x28, 0xf7, 0x01, 0x34, 0x27, 0xf1, 0x38, 0x22, 0x21, 0x19, - 0x32, 0xdd, 0xda, 0x9b, 0x57, 0xfa, 0xcf, 0x04, 0xc1, 0xc0, 0x0e, 0xc6, 0x93, 0x81, 0x1d, 0x10, - 0x9f, 0xc7, 0x50, 0x0a, 0xd5, 0x3e, 0x85, 0x76, 0xc8, 0xe8, 0x26, 0x8b, 0xbc, 0x39, 0x16, 0x79, - 0xa8, 0xff, 0xc4, 0xf5, 0xe3, 0x28, 0xfb, 0xc1, 0x03, 0x75, 0xb0, 0xbf, 0xfb, 0x7c, 0x67, 0x6b, - 0x67, 0xc7, 0xd8, 0x1d, 0x0c, 0x0c, 0x08, 0xd3, 0x19, 0xfd, 0x00, 0xb4, 0xdd, 0x68, 0x84, 0x03, - 0x1c, 0x4f, 0x5e, 0x57, 0xe7, 0xa2, 0x36, 0x95, 0x33, 0xda, 0xd0, 0x50, 0x4a, 0x58, 0xf5, 0xa0, - 0x21, 0x7e, 0x29, 0x82, 0x32, 0x19, 0xea, 0xf7, 0x60, 0x3e, 0x59, 0x7a, 0x06, 0x58, 0xcd, 0xc0, - 0x2a, 0xc0, 0x57, 0xc4, 0xc7, 0x3b, 0xec, 0xdc, 0xd6, 0xff, 0xaf, 0x02, 0xf0, 0xd4, 0xb3, 0x1c, - 0x3e, 0xa4, 0x09, 0x7c, 0xe2, 0xe2, 0x89, 0xe7, 0x12, 0x3b, 0x49, 0xe0, 0xc9, 0x38, 0x0d, 0x81, - 0x0a, 0x33, 0x6a, 0x49, 0x08, 0x88, 0xad, 0x57, 0x65, 0xbf, 0xa3, 0x9f, 0x3f, 0x2b, 0xad, 0x69, - 0xab, 0xd2, 0x21, 0x32, 0xc7, 0x03, 0x01, 0xbb, 0xc3, 0x31, 0x09, 0x47, 0x65, 0xa7, 0x49, 0x5d, - 0x3e, 0x4d, 0x56, 0xa1, 0x13, 0x1e, 0x13, 0xdf, 0xb4, 0x47, 0xd8, 0x3e, 0x0e, 0xe3, 0x89, 0x28, - 0x41, 0x54, 0x4a, 0xdc, 0x16, 0x34, 0xed, 0x06, 0xb4, 0xe3, 0xcd, 0x23, 0xd3, 0xf6, 0x62, 0x37, - 0xc2, 0x01, 0xab, 0x3b, 0x3a, 0x06, 0xc4, 0x9b, 0x47, 0xdb, 0x9c, 0xa2, 0xff, 0xb6, 0x02, 0x6d, - 0x03, 0x87, 0x38, 0x12, 0x46, 0xb9, 0x05, 0x5d, 0xe1, 0x21, 0x33, 0xb0, 0x5c, 0xc7, 0x9b, 0x88, - 0x33, 0xa3, 0x23, 0xa8, 0x06, 0x23, 0x6a, 0x37, 0xa0, 0x19, 0x46, 0x01, 0x76, 0x87, 0xd1, 0x88, - 0x17, 0x6c, 0x0f, 0xaa, 0x9b, 0x1f, 0x7c, 0x68, 0xa4, 0xc4, 0xd9, 0xd6, 0xa8, 0x9e, 0x63, 0x8d, - 0xb3, 0x07, 0x48, 0xad, 0xec, 0x00, 0xf9, 0x05, 0x46, 0x2b, 0xd8, 0xa3, 0x51, 0xb4, 0x07, 0x05, - 0x30, 0xab, 0x8a, 0x7a, 0x81, 0x17, 0x6a, 0x40, 0x49, 0xbc, 0x5c, 0xa0, 0x85, 0x01, 0xff, 0x12, - 0x41, 0x85, 0xa0, 0x2b, 0xf2, 0x5f, 0x92, 0x64, 0x6f, 0x03, 0x08, 0x0a, 0xcd, 0xb0, 0xb9, 0xa4, - 0xa8, 0xc8, 0x49, 0xf1, 0x4f, 0x15, 0xe8, 0x1a, 0xd8, 0xf6, 0x4e, 0x70, 0x30, 0x15, 0xd6, 0x5f, - 0x06, 0xf8, 0xc6, 0x0b, 0x1c, 0x2e, 0x9f, 0x38, 0xd1, 0x5b, 0x94, 0xc2, 0xc4, 0x9b, 0x6d, 0xd4, - 0xca, 0x1b, 0x19, 0xb5, 0xfa, 0x2a, 0xa3, 0xd6, 0x5e, 0x69, 0xd4, 0x39, 0xd9, 0xa8, 0x1b, 0x80, - 0xb0, 0x7b, 0xe4, 0x05, 0x36, 0x36, 0xa9, 0xac, 0x63, 0x12, 0x46, 0xcc, 0xea, 0x4d, 0x63, 0x5e, - 0xd0, 0xbf, 0x12, 0x64, 0x9a, 0x39, 0x59, 0xca, 0xe1, 0x81, 0xc8, 0xbe, 0x8b, 0x3e, 0x69, 0x9d, - 0xf1, 0xc9, 0x65, 0x68, 0x38, 0xc1, 0xd4, 0x0c, 0x62, 0x97, 0xd5, 0xbd, 0x4d, 0xa3, 0xee, 0x04, - 0x53, 0x23, 0x76, 0xf5, 0xf7, 0xa0, 0x4d, 0x39, 0x27, 0x27, 0xe9, 0x5a, 0xee, 0x24, 0x45, 0x7d, - 0x69, 0x4e, 0x3a, 0x44, 0x97, 0xa1, 0x41, 0x27, 0xa8, 0x6f, 0x34, 0xa8, 0x51, 0x81, 0x45, 0x8a, - 0x61, 0xdf, 0xfa, 0x8f, 0x0a, 0xb4, 0x07, 0x64, 0xe8, 0x3e, 0x13, 0x15, 0xd0, 0xb9, 0x49, 0x2d, - 0x57, 0x43, 0xb0, 0xcc, 0x93, 0x14, 0x4e, 0xb9, 0x14, 0x5f, 0x9d, 0x95, 0xe2, 0x0b, 0x89, 0xb8, - 0xf6, 0xc6, 0x89, 0xf8, 0xbf, 0x15, 0xe8, 0xbc, 0xc0, 0x01, 0x39, 0x9a, 0x26, 0xf2, 0xe6, 0x92, - 0xa1, 0x22, 0x65, 0x4e, 0xed, 0x1a, 0xb4, 0x42, 0x32, 0x74, 0xd9, 0x7d, 0x8c, 0x45, 0x8c, 0x6a, - 0x64, 0x04, 0x59, 0x95, 0x2a, 0x8f, 0xd3, 0x52, 0x55, 0x66, 0x9e, 0xa0, 0xff, 0x0e, 0x48, 0x88, - 0x30, 0x90, 0x79, 0xfe, 0x1c, 0x59, 0xf4, 0x1f, 0x14, 0xba, 0xa9, 0xec, 0x60, 0xea, 0x47, 0x89, - 0x5a, 0x97, 0xa0, 0xee, 0xc7, 0x87, 0xc7, 0x38, 0xd9, 0x45, 0x62, 0x54, 0xac, 0xe2, 0x24, 0xb1, - 0x6f, 0x82, 0x9a, 0x64, 0x32, 0xcf, 0x1d, 0xa7, 0xc7, 0xa7, 0xa0, 0x7d, 0xe1, 0x8e, 0x0b, 0x55, - 0x48, 0xed, 0xbc, 0x43, 0x7a, 0x6e, 0x96, 0xda, 0x2f, 0x00, 0x09, 0x49, 0xb1, 0x93, 0xc8, 0x7a, - 0x11, 0xe6, 0x5c, 0xcf, 0xb5, 0xb1, 0x10, 0x95, 0x0f, 0xce, 0x91, 0x54, 0x83, 0xda, 0x68, 0x62, - 0xd9, 0xc2, 0xee, 0xec, 0x5b, 0xff, 0x1a, 0xba, 0x3b, 0x38, 0x67, 0x81, 0x73, 0x03, 0x31, 0x5d, - 0xb2, 0x32, 0x63, 0xc9, 0x6a, 0xf9, 0x92, 0x35, 0x69, 0xc9, 0x3d, 0x40, 0x62, 0xc9, 0x4c, 0x95, - 0x42, 0xad, 0x2d, 0x71, 0x90, 0x7c, 0x5b, 0xc9, 0xf9, 0x56, 0xff, 0xb3, 0x02, 0xdd, 0x6d, 0xe2, - 0x8f, 0x70, 0xf0, 0x39, 0x9e, 0xbe, 0xb0, 0xc6, 0xf1, 0x2b, 0x64, 0x47, 0x50, 0xa5, 0x7e, 0xe5, - 0x5c, 0xe8, 0x27, 0xd5, 0xe6, 0x84, 0xfe, 0x4e, 0x48, 0xcd, 0x07, 0x3c, 0x93, 0x32, 0xf9, 0xc4, - 0xb1, 0x90, 0x0c, 0xb5, 0x35, 0xe8, 0x5a, 0xe1, 0xb1, 0xe9, 0xb9, 0x66, 0x02, 0xe0, 0x77, 0x7a, - 0xd5, 0x0a, 0x8f, 0xbf, 0x70, 0x77, 0xcf, 0xa0, 0x1c, 0xae, 0xa6, 0x48, 0x52, 0x1c, 0x25, 0x54, - 0xd7, 0xba, 0x50, 0x21, 0x27, 0xec, 0x60, 0x50, 0x8d, 0x0a, 0x39, 0xd1, 0xd7, 0x01, 0x71, 0x65, - 0xb0, 0x93, 0xaa, 0x93, 0xca, 0xa7, 0x48, 0xf2, 0xe9, 0xff, 0x05, 0xdd, 0xdd, 0x30, 0x22, 0x13, - 0x2b, 0xc2, 0x07, 0xa7, 0x03, 0xf2, 0x12, 0xd3, 0x23, 0xda, 0x8b, 0x23, 0x3f, 0x8e, 0xc2, 0x34, - 0xa3, 0xd3, 0xc2, 0x59, 0x15, 0x44, 0x9e, 0xd4, 0x6f, 0x82, 0x4a, 0x5c, 0x09, 0x53, 0x61, 0x98, - 0x36, 0xa7, 0x71, 0xc8, 0x6b, 0x25, 0x13, 0xfd, 0x26, 0xd4, 0xc5, 0xba, 0x97, 0xa1, 0x11, 0x9d, - 0x9a, 0xa2, 0x54, 0xa7, 0xd9, 0xb4, 0x1e, 0xb1, 0x09, 0xfd, 0xf7, 0x0a, 0xd4, 0xe9, 0xf6, 0x3c, - 0x38, 0xfd, 0xc7, 0xca, 0xa6, 0x5d, 0x85, 0x46, 0xae, 0x2b, 0xf3, 0x40, 0x79, 0xd7, 0x48, 0x28, - 0xda, 0x75, 0x68, 0x8d, 0x3d, 0xfb, 0xd8, 0x8c, 0x88, 0xd8, 0x69, 0x9d, 0x07, 0xca, 0x3b, 0x46, - 0x93, 0xd2, 0x0e, 0xc8, 0x04, 0xeb, 0x7f, 0x53, 0x40, 0x1d, 0x90, 0x89, 0x3f, 0xc6, 0x42, 0xf6, - 0x35, 0xa8, 0x73, 0x11, 0x58, 0x2c, 0xb5, 0x37, 0xd5, 0xfe, 0xc1, 0x29, 0xcb, 0x99, 0x2c, 0xcd, - 0x8b, 0x39, 0xed, 0x0e, 0x34, 0x84, 0x32, 0xbd, 0x0a, 0x83, 0x75, 0xfa, 0x07, 0xa7, 0x5f, 0x30, - 0x0a, 0xc3, 0x25, 0xb3, 0xda, 0xfb, 0xa0, 0x46, 0x81, 0xe5, 0x86, 0x16, 0x3b, 0x09, 0xc3, 0x5e, - 0x95, 0xa1, 0x51, 0xff, 0x20, 0x23, 0xb2, 0x1f, 0xe4, 0x50, 0xaf, 0x97, 0x16, 0x65, 0xc5, 0xe7, - 0xce, 0x57, 0xbc, 0x7e, 0x56, 0xf1, 0x5f, 0x2b, 0xd0, 0x3a, 0x48, 0x2f, 0x8a, 0xf7, 0x41, 0x0d, - 0xf8, 0xa7, 0x29, 0x1d, 0x73, 0x6a, 0x5f, 0x3e, 0xe2, 0xda, 0x41, 0x36, 0xd0, 0xee, 0x43, 0xc3, - 0xc1, 0x91, 0x45, 0xc6, 0xa1, 0xa8, 0x63, 0x17, 0xfb, 0x29, 0xb7, 0x1d, 0x3e, 0xc1, 0x0d, 0x21, - 0x50, 0xda, 0x47, 0x00, 0x21, 0x0e, 0x92, 0x36, 0x51, 0x95, 0xfd, 0xa6, 0x97, 0xfd, 0x66, 0x90, - 0xce, 0xb1, 0x9f, 0x49, 0x58, 0x7d, 0x03, 0xe6, 0x0e, 0xd8, 0x95, 0x74, 0x05, 0x2a, 0xd1, 0x29, - 0x13, 0xad, 0xcc, 0x82, 0x95, 0xe8, 0x54, 0xff, 0xdf, 0x0a, 0x74, 0x93, 0x0a, 0x5e, 0xf8, 0xf3, - 0x67, 0xa4, 0xb6, 0xab, 0xd0, 0x1a, 0x5a, 0xa1, 0xe9, 0x07, 0xc4, 0x4e, 0xd2, 0x44, 0x73, 0x68, - 0x85, 0xfb, 0x74, 0x9c, 0x4c, 0x8e, 0xc9, 0x84, 0x44, 0x22, 0xc5, 0xd1, 0xc9, 0xa7, 0x74, 0x4c, - 0x37, 0x78, 0xe4, 0x31, 0x67, 0xa8, 0x46, 0x25, 0xf2, 0xb2, 0xcd, 0x5c, 0x97, 0x93, 0xcd, 0x5b, - 0xa0, 0xd1, 0xeb, 0xbb, 0x29, 0x9a, 0x64, 0xa6, 0x3d, 0x8a, 0xdd, 0x63, 0x91, 0x16, 0x10, 0x9d, - 0x11, 0x6d, 0xcf, 0x6d, 0x4a, 0xa7, 0x25, 0x0c, 0x43, 0x8f, 0x79, 0x45, 0x2c, 0xca, 0x6c, 0x4a, - 0x7a, 0xca, 0xcb, 0xe1, 0x2b, 0xd0, 0xb4, 0x47, 0x16, 0x71, 0x4d, 0xe2, 0x88, 0x02, 0xa7, 0xc1, - 0xc6, 0x4f, 0x1c, 0xfd, 0xff, 0x15, 0x58, 0x48, 0xec, 0x91, 0x39, 0xbb, 0xc0, 0x51, 0x39, 0xc3, - 0x91, 0x16, 0xaa, 0xc9, 0x81, 0x69, 0x9e, 0x88, 0xae, 0x29, 0xa4, 0xa4, 0x17, 0x79, 0x40, 0x20, - 0x6c, 0x94, 0x01, 0x8c, 0x3c, 0x20, 0x4c, 0x1a, 0x4d, 0x29, 0x69, 0xa0, 0xf7, 0xa1, 0x93, 0x09, - 0x46, 0x9d, 0xbb, 0x0c, 0x4c, 0x02, 0x61, 0x0c, 0x9e, 0xfc, 0x5a, 0x94, 0xc2, 0xac, 0xa0, 0x3f, - 0x85, 0x0b, 0xb2, 0x63, 0x7f, 0x59, 0x05, 0xa5, 0x13, 0x58, 0x4c, 0xb8, 0x9d, 0x5b, 0xe1, 0xa8, - 0xbf, 0xb8, 0xc2, 0xd1, 0x0d, 0xe8, 0x25, 0x4b, 0xbd, 0xaa, 0x86, 0x79, 0xdd, 0xd5, 0xf4, 0x9f, - 0x58, 0xd2, 0x1a, 0xba, 0x4f, 0x1c, 0xec, 0x46, 0x24, 0x9a, 0x6a, 0x1b, 0xd0, 0x24, 0xe2, 0x5b, - 0xec, 0x8f, 0x4e, 0x3f, 0x99, 0xe4, 0xf7, 0x73, 0x92, 0x41, 0x91, 0x3d, 0xb2, 0xc6, 0xd4, 0xf7, - 0xd8, 0x1c, 0x11, 0xc7, 0xc1, 0xae, 0x58, 0x60, 0x3e, 0xa5, 0x3f, 0x66, 0xe4, 0x3c, 0xf4, 0x84, - 0x84, 0xb1, 0x35, 0x16, 0x97, 0xd2, 0x0c, 0xfa, 0x82, 0x91, 0x4b, 0xdb, 0x2a, 0xb5, 0xb2, 0xb6, - 0x8a, 0x3e, 0x84, 0x2e, 0x15, 0x1d, 0x3b, 0xa9, 0xf0, 0xb3, 0x2b, 0xb9, 0x65, 0x00, 0x9f, 0x75, - 0x4e, 0xcc, 0xe4, 0x10, 0x57, 0x8d, 0x96, 0x9f, 0xf6, 0x52, 0x72, 0x46, 0xaa, 0x16, 0x8d, 0xf4, - 0xad, 0x02, 0x0b, 0x8f, 0x70, 0xb4, 0xbb, 0xbd, 0xf3, 0x58, 0x34, 0x5a, 0xe9, 0x6f, 0xde, 0xc0, - 0x52, 0xb7, 0x61, 0xde, 0xc7, 0x38, 0x30, 0xcf, 0x88, 0xd0, 0xa1, 0xe4, 0xac, 0xa5, 0x53, 0xa6, - 0x7b, 0xb5, 0x54, 0xf7, 0x77, 0xa1, 0x5b, 0x10, 0x87, 0xee, 0x13, 0x3e, 0x32, 0xb3, 0xfa, 0x13, - 0xc2, 0x14, 0xa0, 0xbf, 0x03, 0x9d, 0x01, 0x8e, 0xbe, 0xdc, 0xdc, 0x93, 0x2e, 0x91, 0xf2, 0x8d, - 0x46, 0x39, 0x73, 0xeb, 0xbe, 0x03, 0x9d, 0x3d, 0xd1, 0xa9, 0xde, 0x65, 0x3d, 0xdf, 0x4b, 0x50, - 0xcf, 0xed, 0x74, 0x31, 0xd2, 0xb7, 0x60, 0x3e, 0x01, 0x26, 0x99, 0xe1, 0x12, 0xd4, 0xbd, 0xa3, - 0xa3, 0x10, 0x27, 0xf7, 0x43, 0x31, 0x92, 0x58, 0x54, 0x72, 0x2c, 0x3e, 0x81, 0x6e, 0xc2, 0xe2, - 0x4b, 0x7f, 0xec, 0x59, 0x0e, 0x75, 0xa6, 0x6f, 0x4d, 0xe9, 0x67, 0xd2, 0x2f, 0x11, 0x43, 0x56, - 0x16, 0x5a, 0xe1, 0x48, 0xd8, 0x90, 0x7d, 0xeb, 0x6b, 0xd0, 0x1c, 0xe0, 0xf1, 0xd1, 0x01, 0x5d, - 0x3b, 0xf7, 0x4b, 0x45, 0xfa, 0xa5, 0x7e, 0x17, 0x16, 0x76, 0xf0, 0x61, 0x3c, 0x7c, 0x4a, 0xdc, - 0xe3, 0x1d, 0x6c, 0xf3, 0x97, 0x83, 0x45, 0xa8, 0x4f, 0x71, 0x68, 0xba, 0x1e, 0x5b, 0xa7, 0x69, - 0xcc, 0x4d, 0x71, 0xf8, 0xdc, 0xd3, 0x2f, 0x48, 0xd8, 0x47, 0x38, 0x1a, 0x44, 0x56, 0x84, 0xf5, - 0xbf, 0x54, 0x68, 0xc5, 0x2b, 0xa8, 0x8c, 0xc4, 0x34, 0xb2, 0xa6, 0x5e, 0x1c, 0x25, 0x35, 0x3f, - 0x1f, 0x25, 0xbd, 0x97, 0x4a, 0xd6, 0x7b, 0xb9, 0x04, 0xf5, 0x09, 0xeb, 0x8a, 0x0a, 0xa7, 0x8a, - 0x51, 0xae, 0xc5, 0x53, 0x9b, 0xd1, 0xe2, 0x99, 0x9b, 0xd5, 0xe2, 0x99, 0x79, 0xdb, 0xae, 0x9f, - 0x73, 0xdb, 0x5e, 0x06, 0x08, 0x70, 0x88, 0x23, 0x76, 0x13, 0x66, 0xe7, 0x45, 0xcb, 0x68, 0x31, - 0x0a, 0xbd, 0x74, 0xd2, 0xaa, 0x8b, 0x4f, 0x27, 0x3d, 0x81, 0x26, 0xd3, 0x4c, 0x65, 0xc4, 0xa4, - 0x8f, 0xfa, 0x16, 0x68, 0x81, 0xe8, 0x0b, 0x98, 0x47, 0xd6, 0x31, 0xbf, 0x55, 0x8b, 0xb7, 0x20, - 0x94, 0xcc, 0xec, 0x59, 0xc7, 0xec, 0x5a, 0xad, 0xdd, 0x85, 0x85, 0x14, 0xcd, 0x9a, 0x07, 0xbe, - 0x17, 0xb2, 0x7b, 0x72, 0xc7, 0x98, 0x4f, 0x26, 0x28, 0x70, 0xdf, 0x0b, 0xf5, 0x79, 0xe8, 0x48, - 0x36, 0xf6, 0x7c, 0x7d, 0x1f, 0xd4, 0x94, 0xf0, 0xd4, 0x1b, 0xb2, 0x0b, 0x3e, 0x3e, 0xc1, 0xe3, - 0xe4, 0x35, 0x81, 0x0d, 0xa8, 0x79, 0x0f, 0x63, 0xfb, 0x18, 0x47, 0xc2, 0xe6, 0x62, 0xc4, 0x6e, - 0xf3, 0xf8, 0x34, 0x12, 0x46, 0x67, 0xdf, 0xfa, 0x23, 0xb8, 0x90, 0x72, 0x7c, 0x86, 0x27, 0x5e, - 0x30, 0x35, 0x30, 0x8f, 0x39, 0x39, 0x81, 0x74, 0xb2, 0x04, 0x32, 0x2b, 0x6e, 0x37, 0x60, 0xbe, - 0xc0, 0x88, 0xb9, 0x99, 0x7d, 0x25, 0x01, 0xc1, 0x47, 0xfa, 0x7f, 0xc0, 0xc5, 0x02, 0xf4, 0xab, - 0x80, 0x44, 0xf8, 0xfc, 0x45, 0x05, 0xa7, 0x8a, 0xcc, 0x49, 0xbc, 0xa6, 0x84, 0x23, 0x71, 0x5b, - 0xe4, 0x03, 0xfd, 0x6d, 0x49, 0xa7, 0x3d, 0x4a, 0x49, 0x37, 0x6d, 0x88, 0xed, 0xc8, 0x4b, 0x76, - 0xb8, 0x18, 0xdd, 0xfd, 0x71, 0x11, 0xda, 0xe2, 0x1c, 0x61, 0x75, 0xd8, 0x0a, 0x5c, 0x92, 0x86, - 0x66, 0xf6, 0x60, 0x8a, 0xfe, 0x69, 0xa9, 0xf6, 0xed, 0x1f, 0x7a, 0x8a, 0xb6, 0x94, 0x5e, 0x9e, - 0x19, 0x62, 0x9f, 0xb8, 0x43, 0xa4, 0x88, 0xb9, 0x65, 0xb8, 0x20, 0xcf, 0x89, 0x57, 0x10, 0x54, - 0x59, 0xaa, 0x7d, 0x57, 0x32, 0x2d, 0xde, 0x39, 0x50, 0x55, 0x4c, 0xdf, 0x80, 0x45, 0x79, 0x3a, - 0x7d, 0x14, 0x42, 0x35, 0xc1, 0xbe, 0x20, 0x5c, 0xd6, 0x2e, 0x45, 0x73, 0x02, 0x71, 0x07, 0xae, - 0xe4, 0x56, 0x90, 0x13, 0x17, 0xaa, 0x2f, 0x35, 0x29, 0xe8, 0x8f, 0x14, 0xb8, 0x0e, 0x4b, 0x65, - 0x40, 0x9e, 0x75, 0x50, 0x43, 0x42, 0x6e, 0xc0, 0xd5, 0x32, 0xa4, 0x48, 0x71, 0xa8, 0xb9, 0xd4, - 0xfc, 0x2e, 0x81, 0x16, 0xe4, 0xcb, 0x5e, 0x23, 0x50, 0xab, 0xdc, 0x40, 0xc9, 0x34, 0x08, 0x0b, - 0xe8, 0xd0, 0x2b, 0x30, 0x48, 0x8f, 0x05, 0xd4, 0x16, 0x2c, 0x0a, 0x56, 0xca, 0x00, 0xaa, 0x60, - 0x52, 0x90, 0x22, 0xeb, 0x22, 0xa3, 0x8e, 0x60, 0x71, 0x13, 0x2e, 0xcb, 0x08, 0xa9, 0xa7, 0x8a, - 0xba, 0x02, 0x72, 0x0d, 0xb4, 0x9c, 0x27, 0x59, 0xf1, 0x8b, 0xe6, 0xc5, 0xec, 0x5a, 0x5e, 0x4e, - 0xf9, 0xc2, 0x83, 0xd0, 0x52, 0x9d, 0x62, 0x9a, 0x8a, 0x76, 0x1d, 0x2e, 0xe6, 0x2c, 0x27, 0x9e, - 0xd7, 0xd1, 0x82, 0x10, 0xf4, 0x36, 0x5c, 0x2b, 0x44, 0x52, 0xee, 0x31, 0x09, 0x69, 0x29, 0xae, - 0x57, 0x8a, 0xdb, 0xb2, 0x8f, 0xd1, 0x05, 0xee, 0xa9, 0xdf, 0x95, 0xc8, 0xcc, 0x1f, 0x97, 0xd0, - 0xc5, 0x72, 0xbb, 0xa5, 0xe5, 0x2b, 0x5a, 0x14, 0xcb, 0x5c, 0x85, 0x85, 0x3c, 0x80, 0xf2, 0xbf, - 0x94, 0x6a, 0x9c, 0x8b, 0x97, 0x7c, 0xcf, 0x00, 0x5d, 0x16, 0xa8, 0x82, 0xff, 0xe4, 0x57, 0x59, - 0xd4, 0x13, 0x98, 0xd5, 0x7c, 0x88, 0xe6, 0x1e, 0x6a, 0xd1, 0x95, 0x72, 0x50, 0xee, 0x11, 0x0f, - 0x2d, 0x09, 0x81, 0x57, 0xf3, 0x1a, 0xa5, 0x4f, 0x77, 0xe8, 0xaa, 0x64, 0x94, 0x42, 0x34, 0x64, - 0xaf, 0xb1, 0xe8, 0x5a, 0xf9, 0xae, 0xca, 0x1e, 0x49, 0xd0, 0x72, 0x79, 0xd4, 0x26, 0xd3, 0xd7, - 0xd3, 0xa8, 0xcd, 0xf9, 0x39, 0x39, 0x81, 0xd1, 0x8a, 0xb4, 0x8b, 0x0a, 0x96, 0x91, 0xdb, 0xd2, - 0x48, 0x2f, 0xb7, 0x71, 0xbe, 0x55, 0x8d, 0x56, 0xcb, 0xc3, 0x3b, 0x6b, 0x5f, 0xa3, 0xb5, 0xf2, - 0xf0, 0x96, 0xea, 0x7b, 0x74, 0xbb, 0xdc, 0xbe, 0xb9, 0xa2, 0x1d, 0xdd, 0x11, 0xa0, 0x42, 0x7c, - 0x16, 0xcb, 0x6d, 0xb4, 0x2e, 0x24, 0xba, 0x03, 0xcb, 0xb9, 0xf8, 0x2c, 0x3e, 0x65, 0xa2, 0x8d, - 0x14, 0x78, 0xa5, 0x1c, 0x48, 0xa5, 0xbf, 0x2b, 0x39, 0xed, 0x76, 0xc1, 0x12, 0xb9, 0x56, 0x0d, - 0xba, 0x27, 0xed, 0x30, 0x2d, 0x1f, 0xb2, 0x6c, 0xfe, 0xad, 0xa5, 0xfa, 0x77, 0x7c, 0xbe, 0x60, - 0xd1, 0x7c, 0x07, 0x1f, 0xbd, 0x5d, 0x6e, 0x2f, 0xa9, 0x15, 0x8d, 0xfa, 0xe5, 0x99, 0x5b, 0x34, - 0xa5, 0xd1, 0xfd, 0x72, 0x4b, 0x15, 0x9b, 0x50, 0xe8, 0x9d, 0x74, 0x27, 0x17, 0x3c, 0x2c, 0x77, - 0x0d, 0xd1, 0xbb, 0xa9, 0x5e, 0xeb, 0x79, 0x7e, 0xc5, 0xae, 0x25, 0xda, 0x4c, 0x35, 0x2c, 0x70, - 0xcc, 0xf7, 0x21, 0xd1, 0x7b, 0xb3, 0x38, 0x16, 0x9b, 0x87, 0xe8, 0xfd, 0x94, 0xa3, 0x5e, 0xcc, - 0x6d, 0xd9, 0xbd, 0x08, 0x7d, 0x50, 0x1e, 0xa9, 0xf9, 0x0b, 0x08, 0xfa, 0x50, 0x68, 0x5b, 0xb0, - 0xab, 0xf4, 0xef, 0x46, 0xe8, 0x9f, 0x05, 0xa3, 0x75, 0xb8, 0x9e, 0x53, 0xf4, 0xcc, 0x43, 0x25, - 0xfa, 0x48, 0x20, 0x6f, 0xe5, 0x8f, 0xa1, 0xc2, 0xbb, 0x22, 0xfa, 0x17, 0xb1, 0x66, 0x71, 0x0f, - 0xe5, 0x9a, 0x17, 0xe8, 0x41, 0x7a, 0x4c, 0x2e, 0x97, 0xa1, 0xb2, 0x9c, 0xf8, 0xaf, 0x69, 0x8a, - 0xb9, 0x52, 0x0e, 0xa4, 0xde, 0xff, 0xb7, 0x72, 0x6e, 0x67, 0x2e, 0x49, 0xe8, 0xe3, 0x19, 0x1b, - 0x3c, 0x8f, 0xfa, 0xa4, 0x7c, 0xcd, 0xdc, 0x75, 0x05, 0x7d, 0x2a, 0x58, 0x6d, 0xc0, 0x8d, 0x59, - 0x7a, 0x26, 0x2e, 0xfd, 0x4c, 0x40, 0xef, 0xc1, 0xcd, 0x32, 0x68, 0x7e, 0xcf, 0x6f, 0x09, 0x70, - 0x1f, 0xd6, 0xca, 0xc0, 0x67, 0xf6, 0xfe, 0x43, 0x21, 0xec, 0xbd, 0xbc, 0xee, 0x67, 0xee, 0x15, - 0xc8, 0x59, 0x6a, 0x7e, 0x9f, 0x6c, 0xeb, 0x3b, 0x33, 0xc0, 0xc9, 0xc5, 0x02, 0xe1, 0xa5, 0xda, - 0xf7, 0x25, 0x86, 0xca, 0xdf, 0x35, 0xd0, 0xd1, 0x52, 0xed, 0x87, 0x12, 0x43, 0xe5, 0xaa, 0x65, - 0x34, 0x14, 0xac, 0x0a, 0xe1, 0x2c, 0x57, 0xd0, 0x68, 0x24, 0x18, 0x15, 0x8c, 0x59, 0x52, 0x13, - 0x23, 0x57, 0xb0, 0x2b, 0x84, 0x61, 0x01, 0x8a, 0x3c, 0xc1, 0xf1, 0x2e, 0xac, 0x9c, 0x03, 0x63, - 0x15, 0x2f, 0xf2, 0x05, 0xcb, 0x59, 0xab, 0x67, 0xd5, 0x2b, 0xfa, 0x9a, 0x43, 0x1f, 0xbe, 0x0f, - 0xab, 0xb6, 0x37, 0xe9, 0x87, 0x56, 0xe4, 0x85, 0x23, 0x32, 0xb6, 0x0e, 0xc3, 0x7e, 0x14, 0xe0, - 0x97, 0x5e, 0xd0, 0x1f, 0x93, 0x43, 0xfe, 0x6f, 0x7e, 0x87, 0xf1, 0xd1, 0xc3, 0xce, 0x01, 0x23, - 0x0a, 0xae, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x2a, 0xe4, 0xc0, 0x85, 0x16, 0x28, 0x00, 0x00, +var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ + // 2430 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x9a, 0xd9, 0x73, 0x1c, 0xc5, + 0x1d, 0xc7, 0xb3, 0xab, 0x11, 0x88, 0xf6, 0x41, 0x23, 0xb0, 0x2d, 0xaf, 0x2f, 0xf9, 0xc0, 0x96, + 0x2f, 0xd9, 0x10, 0x0c, 0x44, 0x38, 0x60, 0x69, 0xb5, 0x12, 0x8a, 0xb5, 0x5a, 0x97, 0x76, 0xb1, + 0x1f, 0x5d, 0xa3, 0x9d, 0xd6, 0x6e, 0x97, 0x67, 0x67, 0x86, 0x9e, 0x1e, 0x49, 0xeb, 0xa7, 0x9c, + 0x3c, 0x13, 0x48, 0xc0, 0xb9, 0xa9, 0xa4, 0x2a, 0x21, 0x57, 0x85, 0x1c, 0x4e, 0x25, 0x55, 0x39, + 0x08, 0x24, 0x2f, 0xc9, 0x43, 0x52, 0x9c, 0x86, 0x40, 0xee, 0x90, 0xe4, 0x0f, 0xc8, 0xc5, 0x91, + 0xa4, 0x7a, 0xa6, 0xbb, 0xe7, 0xd8, 0xdf, 0xae, 0x36, 0x6f, 0x58, 0xf3, 0xf9, 0x7d, 0x7f, 0x47, + 0xff, 0xfa, 0x37, 0xdd, 0xb3, 0xa0, 0xcd, 0x2d, 0xe2, 0xfb, 0x66, 0x83, 0xf8, 0xe3, 0x1e, 0x73, + 0xb9, 0x3b, 0x3c, 0xdc, 0x5c, 0x1d, 0xe7, 0x8c, 0x5c, 0x76, 0xd9, 0xb8, 0x7a, 0x52, 0x18, 0x6d, + 0xb8, 0x6e, 0xc3, 0x26, 0x27, 0x42, 0x62, 0x29, 0x58, 0x3e, 0x61, 0x11, 0xbf, 0xce, 0xa8, 0xc7, + 0x5d, 0x16, 0x59, 0x1d, 0xf9, 0xfe, 0x7d, 0x68, 0x43, 0x39, 0xc2, 0x6b, 0x6d, 0x8f, 0x0c, 0x1f, + 0x40, 0x5b, 0x13, 0xff, 0xbc, 0x38, 0xe7, 0x50, 0x4e, 0x4d, 0x9b, 0x5e, 0x26, 0xf8, 0x5d, 0x85, + 0xa1, 0x87, 0xaf, 0x8e, 0xe4, 0x9e, 0xba, 0x3a, 0x92, 0x1b, 0x2e, 0x20, 0x9c, 0xa4, 0xce, 0x51, + 0xa7, 0x81, 0x73, 0x05, 0x43, 0x3c, 0x1f, 0xde, 0x85, 0x6e, 0x4e, 0x3e, 0xab, 0x06, 0xf5, 0x3a, + 0xf1, 0x7d, 0x9c, 0x2f, 0x18, 0x57, 0x80, 0xc7, 0x33, 0x26, 0xb5, 0x03, 0x46, 0xf0, 0x80, 0x7c, + 0xbc, 0x07, 0x6d, 0x49, 0x3e, 0x2e, 0x36, 0x4d, 0xa7, 0x41, 0xce, 0x51, 0x07, 0x1b, 0x52, 0x7e, + 0x34, 0x1d, 0xe0, 0x05, 0xea, 0x91, 0x69, 0xb2, 0x42, 0xeb, 0x04, 0x0f, 0xc2, 0xc4, 0x2c, 0xe1, + 0x25, 0x87, 0x33, 0xd7, 0x6b, 0xe3, 0x1b, 0xe0, 0x10, 0xd5, 0x63, 0x24, 0x63, 0xc8, 0x08, 0xcc, + 0xbb, 0xa6, 0x25, 0x5d, 0x6c, 0x92, 0x02, 0x7b, 0xd1, 0xb6, 0x24, 0xb1, 0x48, 0x7c, 0xc2, 0x25, + 0xb2, 0x59, 0x22, 0xbb, 0xd1, 0x2d, 0xa9, 0x3c, 0x89, 0xc9, 0x03, 0x46, 0x7c, 0x7c, 0x93, 0x74, + 0x72, 0x10, 0xed, 0xcc, 0x94, 0xb0, 0x6c, 0x72, 0x46, 0xd7, 0x16, 0xc9, 0x83, 0x01, 0xf1, 0x39, + 0x1e, 0x96, 0xdc, 0x11, 0x34, 0x02, 0x72, 0x93, 0xf5, 0x4b, 0xf8, 0xe6, 0xc2, 0x46, 0xb5, 0x24, + 0x4f, 0x47, 0x81, 0x0f, 0xa7, 0x8a, 0x67, 0x3a, 0x75, 0x62, 0xe3, 0x5b, 0x12, 0x0b, 0xb7, 0x2f, + 0xad, 0x56, 0xb4, 0x89, 0xc9, 0xaa, 0xc4, 0xf7, 0xa9, 0xeb, 0xe0, 0x11, 0x19, 0xf9, 0x7e, 0xb4, + 0x3d, 0xc9, 0x4c, 0x7a, 0x9e, 0xdd, 0xae, 0x12, 0xce, 0xa9, 0xd3, 0xf0, 0xf1, 0x76, 0x18, 0x9a, + 0x0a, 0x38, 0x77, 0x1d, 0x15, 0x7b, 0x41, 0xc6, 0x7e, 0x28, 0xbd, 0x98, 0x11, 0x24, 0x02, 0xdf, + 0xd1, 0x11, 0xf8, 0xd6, 0x0e, 0x97, 0x33, 0xb6, 0xd9, 0xf0, 0xf1, 0x4e, 0xe9, 0x2f, 0x13, 0xf8, + 0x94, 0x59, 0xbf, 0x14, 0x78, 0xb2, 0xe4, 0xfb, 0x24, 0x73, 0x00, 0x15, 0x80, 0x65, 0x55, 0x41, + 0xed, 0x87, 0x57, 0x57, 0x52, 0x22, 0xaa, 0x03, 0x52, 0xe7, 0x10, 0xda, 0x95, 0x2a, 0xb9, 0xe9, + 0xfb, 0x5e, 0x93, 0x99, 0x3e, 0x51, 0x52, 0x87, 0xa5, 0xd4, 0xd1, 0x74, 0x11, 0x62, 0x50, 0xa8, + 0x1d, 0xc9, 0xe4, 0x78, 0x0c, 0xed, 0x83, 0xe1, 0x2a, 0x37, 0xb9, 0x96, 0x2e, 0x4b, 0xe9, 0x93, + 0x68, 0x77, 0x0f, 0x5a, 0xe8, 0x2f, 0x64, 0xf4, 0x33, 0xd9, 0x2f, 0x92, 0xba, 0xbb, 0x42, 0x58, + 0x5b, 0xd6, 0xe8, 0x38, 0xdc, 0xb9, 0x17, 0x5c, 0x66, 0x29, 0xd7, 0xe3, 0xf0, 0x0e, 0x15, 0x88, + 0xf0, 0x77, 0x02, 0x56, 0x98, 0x25, 0x5c, 0xf7, 0xf6, 0x5d, 0x70, 0x73, 0x54, 0x09, 0x7f, 0xe0, + 0xf6, 0x99, 0xa2, 0x1b, 0x38, 0x9c, 0x30, 0x7c, 0x9f, 0xae, 0x72, 0x0a, 0x9a, 0xa1, 0xac, 0xb5, + 0x6a, 0x32, 0x52, 0x12, 0x49, 0xe2, 0xeb, 0xa2, 0x9e, 0xfd, 0x9e, 0x00, 0xc7, 0xd2, 0x89, 0x29, + 0xf0, 0x01, 0xcf, 0x76, 0x4d, 0x0b, 0x5f, 0x9f, 0x20, 0x0f, 0xa3, 0x1d, 0x10, 0xa9, 0x12, 0x1c, + 0x2a, 0x0c, 0x5d, 0x51, 0xe8, 0xbe, 0xf4, 0xf6, 0xac, 0x12, 0x7b, 0xb9, 0x26, 0x98, 0xd1, 0x84, + 0x5c, 0xa6, 0xe7, 0x66, 0x09, 0x3f, 0x17, 0x2c, 0xd9, 0xb4, 0x7e, 0x96, 0xb4, 0xf1, 0x06, 0x99, + 0x45, 0x66, 0x5e, 0xc5, 0xc0, 0x46, 0x59, 0xcd, 0x9d, 0xe9, 0x3d, 0x59, 0xa5, 0x0d, 0xa7, 0xb6, + 0x86, 0x6f, 0x84, 0xcd, 0x6b, 0x7a, 0xfb, 0x6f, 0x91, 0xe6, 0x3b, 0xd0, 0x4d, 0x69, 0x40, 0x2c, + 0xc5, 0xd6, 0xae, 0x93, 0x6e, 0xd2, 0xb2, 0x98, 0x98, 0xb6, 0xbb, 0xe0, 0x49, 0xa7, 0x1e, 0xef, + 0x96, 0xea, 0x99, 0xb5, 0x14, 0xc1, 0xc9, 0x7f, 0xe3, 0x83, 0xf0, 0x5a, 0x9e, 0x27, 0x8c, 0x2e, + 0xb7, 0x15, 0x74, 0x48, 0x42, 0x99, 0x61, 0x26, 0xff, 0x5b, 0xc8, 0x85, 0x9d, 0x81, 0xc7, 0xa4, + 0xbf, 0x4c, 0x8f, 0x16, 0xa9, 0xd7, 0x24, 0xec, 0x2c, 0x69, 0x9f, 0x37, 0xed, 0x80, 0xe0, 0x6d, + 0xb0, 0x5a, 0x44, 0x11, 0x4b, 0x73, 0x27, 0xa5, 0x5a, 0x66, 0x7d, 0x84, 0xbb, 0x39, 0x8b, 0x38, + 0x9c, 0xf2, 0x36, 0x3e, 0x05, 0xcf, 0x04, 0xc1, 0x10, 0x4b, 0x53, 0x77, 0xea, 0x41, 0xb5, 0x2b, + 0xfb, 0xca, 0x28, 0x4e, 0xdf, 0x2f, 0x07, 0xa3, 0x58, 0xcd, 0xf7, 0x76, 0x19, 0x31, 0x69, 0xea, + 0x5e, 0x78, 0xc4, 0x14, 0x5d, 0x9f, 0x16, 0xdd, 0x56, 0x8b, 0x72, 0x3c, 0x0b, 0xeb, 0xc4, 0x44, + 0x8b, 0x38, 0x1c, 0xdf, 0x2f, 0x75, 0x32, 0xef, 0x10, 0x41, 0x89, 0x04, 0xf0, 0x1c, 0xbc, 0x36, + 0xea, 0x79, 0x54, 0xf3, 0xf7, 0x49, 0x91, 0x13, 0xe9, 0xdc, 0xa6, 0xc9, 0x52, 0xd0, 0x98, 0xa7, + 0xce, 0xa5, 0x69, 0x52, 0xa7, 0xe1, 0xdc, 0xb7, 0x0a, 0x1b, 0x9f, 0x48, 0x0e, 0x92, 0xa3, 0x5d, + 0x0c, 0x66, 0x09, 0x0f, 0x87, 0x0f, 0x26, 0x85, 0x21, 0x65, 0x90, 0x4d, 0x44, 0xc3, 0x11, 0xb9, + 0x5c, 0x30, 0x9e, 0x04, 0x02, 0x4d, 0x50, 0xae, 0x87, 0x1b, 0x05, 0xe3, 0x09, 0x60, 0x39, 0x35, + 0x34, 0xef, 0x36, 0x70, 0x53, 0x0a, 0x1d, 0x46, 0x7b, 0x40, 0xa6, 0x4c, 0x5a, 0x2e, 0x6b, 0x2f, + 0x12, 0xd3, 0xc2, 0x8e, 0x94, 0xbb, 0x35, 0x3d, 0x0c, 0x32, 0x28, 0x76, 0xa5, 0xe2, 0x11, 0x34, + 0xda, 0x03, 0xbb, 0xc0, 0x28, 0x27, 0xd8, 0x93, 0x92, 0xdd, 0xbc, 0xcf, 0xd8, 0xa6, 0xdf, 0x8c, + 0x06, 0xd7, 0x83, 0x12, 0x3d, 0x9a, 0x96, 0x2d, 0x71, 0xd1, 0xc2, 0x41, 0x2b, 0x35, 0x43, 0x9e, + 0x19, 0x90, 0xeb, 0x38, 0x96, 0xae, 0xb8, 0x82, 0x63, 0xf2, 0x59, 0x75, 0x3c, 0x1a, 0x4b, 0xbf, + 0x16, 0x12, 0xb2, 0x6a, 0x6b, 0xdf, 0x2d, 0x35, 0x33, 0xe9, 0x2b, 0x52, 0x61, 0xef, 0x81, 0x77, + 0xa4, 0xc2, 0xe4, 0x98, 0x9a, 0x80, 0xdf, 0x88, 0x8a, 0x8a, 0xc7, 0xd5, 0x3d, 0x52, 0x2e, 0xb3, + 0xd0, 0x31, 0x28, 0xc6, 0xd6, 0x69, 0xa9, 0x96, 0x29, 0x63, 0xd2, 0xa7, 0x1a, 0x2c, 0x67, 0x24, + 0x7a, 0x14, 0xed, 0x85, 0xd0, 0xf4, 0x14, 0x9a, 0x94, 0xf0, 0x38, 0x3a, 0x00, 0xc1, 0x1d, 0xd3, + 0x68, 0x0a, 0x0e, 0x76, 0xa1, 0x54, 0x4e, 0xd4, 0xb1, 0x08, 0xcf, 0xd8, 0x85, 0x52, 0x59, 0x11, + 0xd3, 0xf0, 0x91, 0x75, 0xa1, 0x54, 0x96, 0xd5, 0x2b, 0xc1, 0x6f, 0x4c, 0x09, 0x10, 0xab, 0xb6, + 0x86, 0x67, 0xe0, 0x01, 0xb4, 0x50, 0x2a, 0x4f, 0x93, 0x3a, 0x6b, 0x7b, 0x5c, 0xe5, 0x78, 0x16, + 0xae, 0x5d, 0x0c, 0x12, 0x4b, 0xa1, 0xf3, 0xf0, 0xd2, 0xce, 0x53, 0xff, 0x52, 0x22, 0x3f, 0x06, + 0x07, 0x27, 0x28, 0x85, 0xf8, 0x5d, 0xce, 0xc3, 0xd4, 0xbf, 0x24, 0x33, 0xe4, 0xf0, 0xe9, 0x4c, + 0x11, 0x61, 0x8a, 0x81, 0x54, 0xc9, 0x34, 0xa4, 0x62, 0x54, 0xd4, 0x2b, 0x52, 0x2a, 0xb3, 0x1f, + 0x05, 0xd6, 0xb1, 0x80, 0xab, 0x70, 0xd5, 0x04, 0x9b, 0xee, 0x8c, 0x35, 0xf8, 0x8d, 0x22, 0x4b, + 0x11, 0xef, 0xaf, 0x36, 0x3c, 0x50, 0x05, 0x17, 0x43, 0x97, 0xf5, 0xc9, 0x3d, 0x95, 0x48, 0x8d, + 0x5c, 0x76, 0xfd, 0x44, 0x61, 0x1f, 0xcb, 0x69, 0xb1, 0x91, 0x0e, 0x4e, 0x41, 0x8f, 0xe7, 0xf4, + 0x3b, 0x6c, 0x5b, 0x07, 0x24, 0x8b, 0x7b, 0x25, 0xa7, 0x5f, 0x16, 0xdb, 0x41, 0x26, 0x2c, 0xef, + 0x27, 0x72, 0x7a, 0x34, 0xec, 0x82, 0xc2, 0x8a, 0xe3, 0xff, 0x64, 0x4e, 0x8f, 0x86, 0x42, 0x07, + 0x19, 0x63, 0x9f, 0xca, 0xe9, 0xfe, 0x49, 0x9f, 0xe2, 0x38, 0xb1, 0x6d, 0x93, 0xc9, 0xe0, 0x7e, + 0x9e, 0xd3, 0x0d, 0xb9, 0x1b, 0xa0, 0x6a, 0x6b, 0x15, 0x4f, 0xcd, 0x86, 0x5f, 0x74, 0x89, 0x50, + 0xa2, 0x89, 0xd2, 0xfd, 0xb2, 0x4b, 0x84, 0x92, 0x54, 0xd8, 0xaf, 0x94, 0xe0, 0xf1, 0xf4, 0x91, + 0x5a, 0x62, 0x45, 0x46, 0xc2, 0x23, 0x72, 0x5d, 0x1c, 0x38, 0x2b, 0x1e, 0x7e, 0x2e, 0xa7, 0xa7, + 0xd8, 0x4e, 0x00, 0x3f, 0x67, 0xb6, 0xc5, 0x4b, 0xb7, 0xe2, 0xe1, 0xe7, 0x73, 0x7a, 0xea, 0x8c, + 0x82, 0x20, 0x6f, 0xc6, 0xf0, 0x0b, 0xbd, 0xe1, 0xb2, 0xe9, 0x98, 0x0d, 0x52, 0x59, 0x5e, 0x26, + 0xac, 0xe2, 0xe1, 0x17, 0x15, 0x7c, 0x3b, 0x3a, 0xd4, 0x35, 0x62, 0x71, 0xc6, 0xa7, 0x2b, 0xda, + 0xe6, 0xa5, 0x9c, 0xde, 0x11, 0x7b, 0xa0, 0x75, 0x20, 0xbc, 0xe2, 0x71, 0xea, 0x3a, 0x7e, 0xc5, + 0xc3, 0x2f, 0xf7, 0x0e, 0x26, 0xba, 0x45, 0xd7, 0x58, 0xe0, 0x8b, 0xc8, 0xaf, 0xf5, 0x16, 0x9e, + 0xb4, 0x6d, 0x77, 0x55, 0xb1, 0xaf, 0x28, 0xf6, 0x58, 0x7a, 0x10, 0x2b, 0x36, 0x2a, 0x72, 0x99, + 0xb0, 0x06, 0xa9, 0x78, 0xf8, 0xd5, 0xde, 0xca, 0x51, 0x4d, 0xa6, 0x4d, 0x6e, 0x56, 0x3c, 0xfc, + 0x5a, 0x6f, 0xe5, 0xa9, 0xa0, 0xe5, 0x55, 0x45, 0x03, 0x39, 0x75, 0xa1, 0xfc, 0x7a, 0x4e, 0xef, + 0xe4, 0x1d, 0x5d, 0x9a, 0x32, 0xdc, 0x0d, 0x6f, 0xe4, 0xf4, 0xb4, 0x49, 0xf7, 0x38, 0x73, 0x9d, + 0x44, 0xa3, 0xbd, 0x99, 0xd3, 0x83, 0x6b, 0x5b, 0x16, 0x53, 0xcc, 0x5b, 0x39, 0x7d, 0x48, 0xde, + 0x9a, 0x65, 0xe4, 0x26, 0x78, 0xbb, 0xdb, 0x56, 0x97, 0x48, 0x18, 0xd2, 0x3b, 0x5d, 0xf6, 0x53, + 0xd1, 0x64, 0x96, 0xe9, 0xb8, 0x52, 0xea, 0x1b, 0x79, 0xb8, 0x49, 0x25, 0x15, 0xbf, 0x69, 0x9f, + 0xca, 0xeb, 0x0f, 0x03, 0x7b, 0x00, 0x30, 0xb5, 0xe3, 0xbf, 0xd9, 0x5b, 0x34, 0x06, 0xbf, 0x95, + 0x87, 0xb7, 0x68, 0x2c, 0xaa, 0xaa, 0xf2, 0xed, 0x3c, 0xbc, 0x45, 0x25, 0xa9, 0xb0, 0xef, 0xe4, + 0xf5, 0x3b, 0x76, 0x04, 0x4c, 0x47, 0x9c, 0x07, 0xae, 0xe6, 0xe1, 0x45, 0x4d, 0x54, 0x26, 0xac, + 0xe0, 0x77, 0x95, 0x58, 0x66, 0xd6, 0x54, 0x1c, 0xee, 0xda, 0x6e, 0xa3, 0x9d, 0x08, 0xef, 0x37, + 0x5d, 0x24, 0x15, 0xaa, 0xb8, 0xdf, 0xe6, 0xf5, 0x15, 0x7e, 0xb4, 0x8b, 0x64, 0x5c, 0x9d, 0xdf, + 0xe5, 0xe1, 0x73, 0x9a, 0x82, 0x63, 0xf2, 0xf7, 0xeb, 0xc8, 0x86, 0x8b, 0xcd, 0x4c, 0xc7, 0x5f, + 0x26, 0x0c, 0xff, 0x41, 0xc9, 0x66, 0xc6, 0x58, 0x12, 0x26, 0x96, 0xc6, 0xff, 0xa8, 0xb4, 0xc7, + 0xd1, 0xfe, 0x6e, 0xf8, 0x05, 0xca, 0x9b, 0x16, 0x33, 0x57, 0x2b, 0x4e, 0x03, 0xff, 0x49, 0xc9, + 0x9f, 0x44, 0xb7, 0x76, 0x97, 0x4f, 0x5a, 0xfc, 0x39, 0xaf, 0x3f, 0x3e, 0x74, 0xb5, 0xa8, 0x38, + 0x7c, 0xce, 0x5a, 0x24, 0x0d, 0xea, 0x8b, 0xbb, 0xfc, 0x1b, 0x79, 0x78, 0xae, 0xa5, 0x7d, 0xa4, + 0x6d, 0xfe, 0xa2, 0xbc, 0x9c, 0x42, 0x47, 0x7a, 0x7a, 0x99, 0xb4, 0xac, 0x49, 0xce, 0x19, 0x5d, + 0x0a, 0x38, 0xf1, 0xf1, 0x5f, 0x95, 0xab, 0xbb, 0xd0, 0xb1, 0x75, 0x5c, 0xa5, 0x0d, 0xff, 0x96, + 0xd7, 0xa7, 0x85, 0xd4, 0x26, 0x58, 0xa4, 0x9e, 0x67, 0x93, 0x44, 0xef, 0x3c, 0x3c, 0x00, 0xbf, + 0x6f, 0x23, 0x50, 0x51, 0x1f, 0x1d, 0x80, 0x3b, 0x3b, 0xa2, 0xe4, 0x6e, 0x7e, 0x64, 0x00, 0xde, + 0x25, 0x31, 0x14, 0x36, 0xf6, 0xa3, 0x0a, 0x7b, 0x37, 0x1a, 0x4b, 0xdd, 0x9f, 0x5d, 0x87, 0x30, + 0x37, 0x5c, 0x79, 0xb3, 0x2e, 0x66, 0xfc, 0x9c, 0x43, 0xb9, 0x1a, 0x00, 0x7f, 0x1f, 0xd0, 0x17, + 0xbb, 0x03, 0xeb, 0x1a, 0x89, 0x6d, 0xf6, 0x0f, 0x65, 0x90, 0xa9, 0x5c, 0x87, 0x41, 0x95, 0xf0, + 0x39, 0xc7, 0x0b, 0xb4, 0xa7, 0x7f, 0x2a, 0xc3, 0xf5, 0xc2, 0x53, 0x86, 0xc2, 0xdb, 0xbf, 0x94, + 0xd1, 0x19, 0x74, 0x6a, 0x9d, 0xf0, 0xbc, 0x80, 0xfb, 0xe7, 0x08, 0x6b, 0x05, 0xdc, 0x14, 0x7f, + 0x50, 0x6e, 0xff, 0xad, 0x14, 0x4e, 0xa3, 0xdb, 0xfe, 0x3f, 0x05, 0xe1, 0xff, 0x4d, 0x65, 0x7d, + 0x37, 0x3a, 0xbe, 0xbe, 0xf5, 0x79, 0xea, 0x50, 0xe5, 0xf7, 0x2d, 0x65, 0x79, 0x07, 0x3a, 0xdc, + 0x9f, 0xa5, 0xf0, 0xf7, 0xb6, 0xb2, 0xba, 0x07, 0x9d, 0xec, 0x69, 0x35, 0x69, 0xdb, 0x51, 0xc0, + 0x55, 0xa2, 0x2b, 0xfc, 0x4e, 0xbf, 0x4b, 0x93, 0x34, 0x16, 0x5e, 0xff, 0xd3, 0x6f, 0x96, 0xe2, + 0x98, 0x10, 0xf0, 0xc4, 0xa2, 0xfe, 0xb7, 0xdf, 0x2c, 0xb5, 0xa5, 0xf0, 0xf7, 0x7e, 0xa3, 0x4f, + 0x7f, 0x93, 0xb6, 0x5d, 0x09, 0x78, 0x22, 0xc5, 0x0f, 0x18, 0x7d, 0xfa, 0xd3, 0x96, 0xc2, 0xdf, + 0x07, 0xfb, 0xf5, 0x17, 0x7e, 0xf4, 0x49, 0x36, 0xed, 0x87, 0xfa, 0xf5, 0xa7, 0x2d, 0x85, 0xbf, + 0x0f, 0xf7, 0x6b, 0x35, 0x43, 0x1d, 0xd3, 0x56, 0xbe, 0x3e, 0x62, 0xc0, 0x03, 0x13, 0xb6, 0x12, + 0x7e, 0x1e, 0x52, 0x16, 0x77, 0xa2, 0xa3, 0x9d, 0x16, 0x67, 0x49, 0x7b, 0xae, 0x65, 0x36, 0x48, + 0x69, 0xcd, 0x73, 0x19, 0x4f, 0x6e, 0xfa, 0x47, 0x94, 0x5d, 0x66, 0xd0, 0x76, 0xb3, 0x13, 0xbe, + 0x1e, 0xed, 0x99, 0x93, 0xb2, 0xa9, 0xb6, 0x9d, 0x7a, 0x95, 0x13, 0x7d, 0x5a, 0xff, 0x58, 0xcf, + 0x9c, 0xb2, 0x56, 0xc2, 0xcf, 0xc7, 0x0d, 0x78, 0xa0, 0x77, 0x5a, 0xa4, 0x8a, 0xf7, 0x98, 0x32, + 0xbb, 0x0d, 0x1d, 0xec, 0xc3, 0x4c, 0x78, 0x7a, 0xdc, 0x80, 0x47, 0x79, 0x64, 0x92, 0x18, 0xe5, + 0x9f, 0x36, 0xe0, 0x51, 0x1e, 0x81, 0x8a, 0xfa, 0x8c, 0x01, 0x9f, 0x7a, 0xb4, 0xdc, 0x05, 0x93, + 0xd7, 0x9b, 0xe2, 0xbd, 0xfe, 0x59, 0x03, 0x9e, 0xe7, 0x11, 0xa9, 0xb1, 0xcf, 0x19, 0xf0, 0xc5, + 0x24, 0xfc, 0x50, 0x14, 0xb1, 0xd3, 0xd4, 0x6c, 0xa8, 0x0a, 0x7c, 0xde, 0x80, 0xef, 0x50, 0x19, + 0x5c, 0x64, 0xfe, 0x05, 0xa5, 0x9c, 0x39, 0x2d, 0xeb, 0x50, 0x6b, 0x6b, 0x67, 0x89, 0xfe, 0xa9, + 0xe3, 0x8b, 0x06, 0x7c, 0x60, 0x49, 0xd3, 0x42, 0xf7, 0x4b, 0x3d, 0x7b, 0x64, 0x9e, 0xae, 0x90, + 0x45, 0xb2, 0xcc, 0x88, 0xdf, 0xac, 0x72, 0x93, 0xe9, 0x6e, 0x7c, 0xd2, 0x80, 0x8f, 0x16, 0xb0, + 0x95, 0xf0, 0xf3, 0x65, 0xa3, 0xd7, 0xab, 0x24, 0x65, 0x11, 0xb7, 0xe2, 0x57, 0x94, 0x1b, 0xf0, + 0x4d, 0x97, 0x31, 0x12, 0x5e, 0xbe, 0xda, 0x6f, 0x36, 0xa9, 0x46, 0xfc, 0x5a, 0xbf, 0xd9, 0xe8, + 0x3e, 0xfc, 0xba, 0x01, 0x7f, 0x0a, 0x28, 0x65, 0x6e, 0xdc, 0xd7, 0x0c, 0xf8, 0x7e, 0x50, 0x4a, + 0xde, 0xb7, 0x5f, 0x31, 0xf4, 0x67, 0x96, 0x2d, 0x19, 0x48, 0x9e, 0x26, 0x5e, 0xed, 0xd2, 0x27, + 0x25, 0xd7, 0x17, 0x07, 0xe9, 0xe4, 0xbb, 0xf3, 0xd7, 0x06, 0x7c, 0xff, 0x49, 0xa0, 0x22, 0x81, + 0xd7, 0x0c, 0xf8, 0xfe, 0x53, 0x4a, 0x7c, 0x58, 0x78, 0xbd, 0xcb, 0xee, 0x98, 0xa2, 0x8e, 0xe9, + 0xd4, 0x93, 0x07, 0xa7, 0x1f, 0x0c, 0xc2, 0xbb, 0x43, 0x92, 0x0a, 0xfb, 0xe1, 0x20, 0x7c, 0x73, + 0x89, 0x05, 0xe3, 0xa2, 0xfc, 0x68, 0x10, 0xbe, 0xb9, 0x48, 0x36, 0x06, 0x7f, 0x3c, 0x08, 0xdf, + 0xae, 0x24, 0x28, 0x2b, 0xf8, 0x74, 0x6f, 0xb9, 0xf8, 0x76, 0xf5, 0x93, 0x41, 0xf8, 0xaa, 0xa1, + 0x40, 0x79, 0x18, 0x2f, 0xfb, 0x0d, 0xfc, 0xcc, 0x20, 0x7c, 0xd5, 0x90, 0x68, 0x85, 0x59, 0x11, + 0xf7, 0x6c, 0x6f, 0xdf, 0xd1, 0x8f, 0xb4, 0x02, 0xfc, 0x69, 0x6f, 0x41, 0xbd, 0x30, 0x3f, 0x93, + 0x31, 0x4e, 0x9c, 0x46, 0xd7, 0xaf, 0x52, 0x46, 0x2e, 0x52, 0x67, 0x78, 0xef, 0x78, 0xf4, 0x4b, + 0xff, 0xb8, 0xfa, 0xa5, 0x7f, 0xbc, 0xe4, 0x04, 0xad, 0xf0, 0xe7, 0x12, 0xf9, 0x95, 0x60, 0xe4, + 0xb9, 0x87, 0x06, 0x46, 0x73, 0x63, 0x43, 0x8b, 0xd7, 0x09, 0x9b, 0x39, 0x67, 0xe2, 0x5e, 0x34, + 0x14, 0x5a, 0xbb, 0x01, 0xef, 0xc7, 0xfc, 0x79, 0x69, 0x1e, 0xba, 0xac, 0x04, 0x7c, 0x62, 0x16, + 0x6d, 0x0a, 0xed, 0x2d, 0x31, 0xad, 0xfa, 0x8c, 0xe1, 0x05, 0x29, 0xb2, 0x41, 0x58, 0x86, 0x63, + 0x6e, 0xce, 0x99, 0x98, 0x43, 0x9b, 0x13, 0x42, 0x7d, 0x86, 0xf3, 0xa2, 0x54, 0xda, 0xa8, 0x95, + 0x44, 0x4c, 0x67, 0xd0, 0x0d, 0xa1, 0x14, 0xa7, 0x4e, 0xbb, 0x1f, 0x95, 0x97, 0xa4, 0x4a, 0x58, + 0x89, 0x1a, 0x75, 0xda, 0x13, 0xf3, 0xe8, 0xc6, 0x50, 0x61, 0xc9, 0x75, 0xb9, 0xed, 0x9a, 0x16, + 0x61, 0xfd, 0xe8, 0xbc, 0x2c, 0x75, 0xc2, 0x44, 0xa6, 0xb4, 0xe9, 0x44, 0x11, 0x85, 0x99, 0x5e, + 0x74, 0xdc, 0x8b, 0xcb, 0x7e, 0xab, 0x1f, 0xa5, 0x6b, 0x52, 0x29, 0xcc, 0x63, 0xc1, 0x9d, 0xf1, + 0x5b, 0x53, 0x77, 0xa0, 0xfd, 0x75, 0xb7, 0x35, 0xee, 0x9b, 0xdc, 0xf5, 0x9b, 0xd4, 0x36, 0x97, + 0x7c, 0xf5, 0xff, 0x79, 0xd8, 0x74, 0x49, 0x4b, 0x4d, 0x6d, 0xaa, 0x85, 0x7f, 0x94, 0x9d, 0xf3, + 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x69, 0x67, 0x5d, 0x1f, 0x22, 0x00, 0x00, } diff --git a/accounts/usbwallet/trezor/messages.proto b/accounts/usbwallet/trezor/messages.proto index 8cb9c8cc25..3e0482e344 100644 --- a/accounts/usbwallet/trezor/messages.proto +++ b/accounts/usbwallet/trezor/messages.proto @@ -1,8 +1,9 @@ // This file originates from the SatoshiLabs Trezor `common` repository at: // https://github.com/trezor/trezor-common/blob/master/protob/messages.proto -// dated 28.07.2017, commit dd8ec3231fb5f7992360aff9bdfe30bb58130f4b. +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. syntax = "proto2"; +package hw.trezor.messages; /** * Messages for TREZOR communication @@ -12,894 +13,252 @@ syntax = "proto2"; option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessage"; -import "types.proto"; +import "google/protobuf/descriptor.proto"; /** - * Mapping between Trezor wire identifier (uint) and a protobuf message + * Options for specifying message direction and type of wire (normal/debug) + */ +extend google.protobuf.EnumValueOptions { + optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR + optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC + optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR + optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC + optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode + optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader + optional bool wire_no_fsm = 50008; // message is not handled by TREZOR unless the USB stack is in tiny mode +} + +/** + * Mapping between TREZOR wire identifier (uint) and a protobuf message */ enum MessageType { - MessageType_Initialize = 0 [(wire_in) = true]; - MessageType_Ping = 1 [(wire_in) = true]; - MessageType_Success = 2 [(wire_out) = true]; - MessageType_Failure = 3 [(wire_out) = true]; - MessageType_ChangePin = 4 [(wire_in) = true]; - MessageType_WipeDevice = 5 [(wire_in) = true]; - MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; - MessageType_GetEntropy = 9 [(wire_in) = true]; - MessageType_Entropy = 10 [(wire_out) = true]; - MessageType_GetPublicKey = 11 [(wire_in) = true]; - MessageType_PublicKey = 12 [(wire_out) = true]; - MessageType_LoadDevice = 13 [(wire_in) = true]; - MessageType_ResetDevice = 14 [(wire_in) = true]; - MessageType_SignTx = 15 [(wire_in) = true]; - MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true]; - MessageType_Features = 17 [(wire_out) = true]; - MessageType_PinMatrixRequest = 18 [(wire_out) = true]; - MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true]; - MessageType_Cancel = 20 [(wire_in) = true]; - MessageType_TxRequest = 21 [(wire_out) = true]; - MessageType_TxAck = 22 [(wire_in) = true]; - MessageType_CipherKeyValue = 23 [(wire_in) = true]; - MessageType_ClearSession = 24 [(wire_in) = true]; - MessageType_ApplySettings = 25 [(wire_in) = true]; - MessageType_ButtonRequest = 26 [(wire_out) = true]; - MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true]; - MessageType_ApplyFlags = 28 [(wire_in) = true]; - MessageType_GetAddress = 29 [(wire_in) = true]; - MessageType_Address = 30 [(wire_out) = true]; - MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; - MessageType_BackupDevice = 34 [(wire_in) = true]; - MessageType_EntropyRequest = 35 [(wire_out) = true]; - MessageType_EntropyAck = 36 [(wire_in) = true]; - MessageType_SignMessage = 38 [(wire_in) = true]; - MessageType_VerifyMessage = 39 [(wire_in) = true]; - MessageType_MessageSignature = 40 [(wire_out) = true]; - MessageType_PassphraseRequest = 41 [(wire_out) = true]; - MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true]; - MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true]; - MessageType_TxSize = 44 [(wire_out) = true, deprecated = true]; - MessageType_RecoveryDevice = 45 [(wire_in) = true]; - MessageType_WordRequest = 46 [(wire_out) = true]; - MessageType_WordAck = 47 [(wire_in) = true]; - MessageType_CipheredKeyValue = 48 [(wire_out) = true]; - MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true]; - MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true]; - MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true]; - MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true]; - MessageType_SignIdentity = 53 [(wire_in) = true]; - MessageType_SignedIdentity = 54 [(wire_out) = true]; - MessageType_GetFeatures = 55 [(wire_in) = true]; - MessageType_EthereumGetAddress = 56 [(wire_in) = true]; - MessageType_EthereumAddress = 57 [(wire_out) = true]; - MessageType_EthereumSignTx = 58 [(wire_in) = true]; - MessageType_EthereumTxRequest = 59 [(wire_out) = true]; - MessageType_EthereumTxAck = 60 [(wire_in) = true]; - MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; - MessageType_ECDHSessionKey = 62 [(wire_out) = true]; - MessageType_SetU2FCounter = 63 [(wire_in) = true]; - MessageType_EthereumSignMessage = 64 [(wire_in) = true]; - MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; - MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; - MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true]; - MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true]; - MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; - MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; - MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; - MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; - MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; - MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; -} - -//////////////////// -// Basic messages // -//////////////////// - -/** - * Request: Reset device to default state and ask for device details - * @next Features - */ -message Initialize { -} - -/** - * Request: Ask for device details (no device reset) - * @next Features - */ -message GetFeatures { -} - -/** - * Response: Reports various information about the device - * @prev Initialize - * @prev GetFeatures - */ -message Features { - optional string vendor = 1; // name of the manufacturer, e.g. "bitcointrezor.com" - optional uint32 major_version = 2; // major version of the device, e.g. 1 - optional uint32 minor_version = 3; // minor version of the device, e.g. 0 - optional uint32 patch_version = 4; // patch version of the device, e.g. 0 - optional bool bootloader_mode = 5; // is device in bootloader mode? - optional string device_id = 6; // device's unique identifier - optional bool pin_protection = 7; // is device protected by PIN? - optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase? - optional string language = 9; // device language - optional string label = 10; // device description label - repeated CoinType coins = 11; // supported coins - optional bool initialized = 12; // does device contain seed? - optional bytes revision = 13; // SCM revision of firmware - optional bytes bootloader_hash = 14; // hash of the bootloader - optional bool imported = 15; // was storage imported from an external source? - optional bool pin_cached = 16; // is PIN already cached in session? - optional bool passphrase_cached = 17; // is passphrase already cached in session? - optional bool firmware_present = 18; // is valid firmware loaded? - optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup) - optional uint32 flags = 20; // device flags (equals to Storage.flags) -} - -/** - * Request: clear session (removes cached PIN, passphrase, etc). - * @next Success - */ -message ClearSession { -} - -/** - * Request: change language and/or label of the device - * @next Success - * @next Failure - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ApplySettings { - optional string language = 1; - optional string label = 2; - optional bool use_passphrase = 3; - optional bytes homescreen = 4; -} - -/** - * Request: set flags of the device - * @next Success - * @next Failure - */ -message ApplyFlags { - optional uint32 flags = 1; // bitmask, can only set bits, not unset -} - -/** - * Request: Starts workflow for setting/changing/removing the PIN - * @next ButtonRequest - * @next PinMatrixRequest - */ -message ChangePin { - optional bool remove = 1; // is PIN removal requested? -} - -/** - * Request: Test if the device is alive, device sends back the message in Success response - * @next Success - */ -message Ping { - optional string message = 1; // message to send back in Success message - optional bool button_protection = 2; // ask for button press - optional bool pin_protection = 3; // ask for PIN if set in device - optional bool passphrase_protection = 4; // ask for passphrase if set in device -} - -/** - * Response: Success of the previous request - */ -message Success { - optional string message = 1; // human readable description of action or request-specific payload -} - -/** - * Response: Failure of the previous request - */ -message Failure { - optional FailureType code = 1; // computer-readable definition of the error state - optional string message = 2; // human-readable message of the error state -} - -/** - * Response: Device is waiting for HW button press. - * @next ButtonAck - * @next Cancel - */ -message ButtonRequest { - optional ButtonRequestType code = 1; - optional string data = 2; -} - -/** - * Request: Computer agrees to wait for HW button press - * @prev ButtonRequest - */ -message ButtonAck { -} - -/** - * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme - * @next PinMatrixAck - * @next Cancel - */ -message PinMatrixRequest { - optional PinMatrixRequestType type = 1; -} - -/** - * Request: Computer responds with encoded PIN - * @prev PinMatrixRequest - */ -message PinMatrixAck { - required string pin = 1; // matrix encoded PIN entered by user -} - -/** - * Request: Abort last operation that required user interaction - * @prev ButtonRequest - * @prev PinMatrixRequest - * @prev PassphraseRequest - */ -message Cancel { -} - -/** - * Response: Device awaits encryption passphrase - * @next PassphraseAck - * @next Cancel - */ -message PassphraseRequest { -} - -/** - * Request: Send passphrase back - * @prev PassphraseRequest - */ -message PassphraseAck { - required string passphrase = 1; -} - -/** - * Request: Request a sample of random data generated by hardware RNG. May be used for testing. - * @next ButtonRequest - * @next Entropy - * @next Failure - */ -message GetEntropy { - required uint32 size = 1; // size of requested entropy -} - -/** - * Response: Reply with random data generated by internal RNG - * @prev GetEntropy - */ -message Entropy { - required bytes entropy = 1; // stream of random generated bytes -} - -/** - * Request: Ask device for public key corresponding to address_n path - * @next PassphraseRequest - * @next PublicKey - * @next Failure - */ -message GetPublicKey { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string ecdsa_curve_name = 2; // ECDSA curve name to use - optional bool show_display = 3; // optionally show on display before sending the result - optional string coin_name = 4 [default='Bitcoin']; -} - -/** - * Response: Contains public key derived from device private seed - * @prev GetPublicKey - */ -message PublicKey { - required HDNodeType node = 1; // BIP32 public node - optional string xpub = 2; // serialized form of public node -} - -/** - * Request: Ask device for address corresponding to address_n path - * @next PassphraseRequest - * @next Address - * @next Failure - */ -message GetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string coin_name = 2 [default='Bitcoin']; - optional bool show_display = 3 ; // optionally show on display before sending the result - optional MultisigRedeemScriptType multisig = 4; // filled if we are showing a multisig address - optional InputScriptType script_type = 5 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device for Ethereum address corresponding to address_n path - * @next PassphraseRequest - * @next EthereumAddress - * @next Failure - */ -message EthereumGetAddress { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bool show_display = 2; // optionally show on display before sending the result -} - -/** - * Response: Contains address derived from device private seed - * @prev GetAddress - */ -message Address { - required string address = 1; // Coin address in Base58 encoding -} - -/** - * Response: Contains an Ethereum address derived from device private seed - * @prev EthereumGetAddress - */ -message EthereumAddress { - required bytes address = 1; // Coin address as an Ethereum 160 bit hash -} - -/** - * Request: Request device to wipe all sensitive data and settings - * @next ButtonRequest - */ -message WipeDevice { -} - -/** - * Request: Load seed and related internal settings from the computer - * @next ButtonRequest - * @next Success - * @next Failure - */ -message LoadDevice { - optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) - optional HDNodeType node = 2; // BIP-32 node - optional string pin = 3; // set PIN protection - optional bool passphrase_protection = 4; // enable master node encryption using passphrase - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum - optional uint32 u2f_counter = 8; // U2F counter -} - -/** - * Request: Ask device to do initialization involving user interaction - * @next EntropyRequest - * @next Failure - */ -message ResetDevice { - optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy - optional uint32 strength = 2 [default=256]; // strength of seed in bits - optional bool passphrase_protection = 3; // enable master node encryption using passphrase - optional bool pin_protection = 4; // enable PIN protection - optional string language = 5 [default='english']; // device language - optional string label = 6; // device label - optional uint32 u2f_counter = 7; // U2F counter - optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow -} - -/** - * Request: Perform backup of the device seed if not backed up using ResetDevice - * @next ButtonRequest - */ -message BackupDevice { -} - -/** - * Response: Ask for additional entropy from host computer - * @prev ResetDevice - * @next EntropyAck - */ -message EntropyRequest { -} - -/** - * Request: Provide additional entropy for seed generation function - * @prev EntropyRequest - * @next ButtonRequest - */ -message EntropyAck { - optional bytes entropy = 1; // 256 bits (32 bytes) of random data -} - -/** - * Request: Start recovery workflow asking user for specific words of mnemonic - * Used to recovery device safely even on untrusted computer. - * @next WordRequest - */ -message RecoveryDevice { - optional uint32 word_count = 1; // number of words in BIP-39 mnemonic - optional bool passphrase_protection = 2; // enable master node encryption using passphrase - optional bool pin_protection = 3; // enable PIN protection - optional string language = 4 [default='english']; // device language - optional string label = 5; // device label - optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process - // 7 reserved for unused recovery method - optional uint32 type = 8; // supported recovery type (see RecoveryType) - optional uint32 u2f_counter = 9; // U2F counter - optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation) -} - -/** - * Response: Device is waiting for user to enter word of the mnemonic - * Its position is shown only on device's internal display. - * @prev RecoveryDevice - * @prev WordAck - */ -message WordRequest { - optional WordRequestType type = 1; -} - -/** - * Request: Computer replies with word from the mnemonic - * @prev WordRequest - * @next WordRequest - * @next Success - * @next Failure - */ -message WordAck { - required string word = 1; // one word of mnemonic on asked position -} - -////////////////////////////// -// Message signing messages // -////////////////////////////// - -/** - * Request: Ask device to sign message - * @next MessageSignature - * @next Failure - */ -message SignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed - optional string coin_name = 3 [default='Bitcoin']; // coin to use for signing - optional InputScriptType script_type = 4 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.) -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message VerifyMessage { - optional string address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify - optional string coin_name = 4 [default='Bitcoin']; // coin to use for verifying -} - -/** - * Response: Signed message - * @prev SignMessage - */ -message MessageSignature { - optional string address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////////// -// Encryption/decryption // -/////////////////////////// - -/** - * Request: Ask device to encrypt message - * @next EncryptedMessage - * @next Failure - */ -message EncryptMessage { - optional bytes pubkey = 1; // public key - optional bytes message = 2; // message to encrypt - optional bool display_only = 3; // show just on display? (don't send back via wire) - repeated uint32 address_n = 4; // BIP-32 path to derive the signing key from master node - optional string coin_name = 5 [default='Bitcoin']; // coin to use for signing -} - -/** - * Response: Encrypted message - * @prev EncryptMessage - */ -message EncryptedMessage { - optional bytes nonce = 1; // nonce used during encryption - optional bytes message = 2; // encrypted message - optional bytes hmac = 3; // message hmac -} - -/** - * Request: Ask device to decrypt message - * @next Success - * @next Failure - */ -message DecryptMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the decryption key from master node - optional bytes nonce = 2; // nonce used during encryption - optional bytes message = 3; // message to decrypt - optional bytes hmac = 4; // message hmac -} - -/** - * Response: Decrypted message - * @prev DecryptedMessage - */ -message DecryptedMessage { - optional bytes message = 1; // decrypted message - optional string address = 2; // address used to sign the message (if used) -} - -/** - * Request: Ask device to encrypt or decrypt value of given key - * @next CipheredKeyValue - * @next Failure - */ -message CipherKeyValue { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional string key = 2; // key component of key:value - optional bytes value = 3; // value component of key:value - optional bool encrypt = 4; // are we encrypting (True) or decrypting (False)? - optional bool ask_on_encrypt = 5; // should we ask on encrypt operation? - optional bool ask_on_decrypt = 6; // should we ask on decrypt operation? - optional bytes iv = 7; // initialization vector (will be computed if not set) -} - -/** - * Response: Return ciphered/deciphered value - * @prev CipherKeyValue - */ -message CipheredKeyValue { - optional bytes value = 1; // ciphered/deciphered value -} - -////////////////////////////////// -// Transaction signing messages // -////////////////////////////////// - -/** - * Request: Estimated size of the transaction - * This behaves exactly like SignTx, which means that it can ask using TxRequest - * This call is non-blocking (except possible PassphraseRequest to unlock the seed) - * @next TxSize - * @next Failure - */ -message EstimateTxSize { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use -} - -/** - * Response: Estimated size of the transaction - * @prev EstimateTxSize - */ -message TxSize { - optional uint32 tx_size = 1; // estimated size of transaction in bytes -} - -/** - * Request: Ask device to sign transaction - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SignTx { - required uint32 outputs_count = 1; // number of transaction outputs - required uint32 inputs_count = 2; // number of transaction inputs - optional string coin_name = 3 [default='Bitcoin']; // coin to use - optional uint32 version = 4 [default=1]; // transaction version - optional uint32 lock_time = 5 [default=0]; // transaction lock_time -} - -/** - * Request: Simplified transaction signing - * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs. - * In case of success, the result is returned using TxRequest message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next TxRequest - * @next Failure - */ -message SimpleSignTx { - repeated TxInputType inputs = 1; // transaction inputs - repeated TxOutputType outputs = 2; // transaction outputs - repeated TransactionType transactions = 3; // transactions whose outputs are used to build current inputs - optional string coin_name = 4 [default='Bitcoin']; // coin to use - optional uint32 version = 5 [default=1]; // transaction version - optional uint32 lock_time = 6 [default=0]; // transaction lock_time -} - -/** - * Response: Device asks for information for signing transaction or returns the last result - * If request_index is set, device awaits TxAck message (with fields filled in according to request_type) - * If signature_index is set, 'signature' contains signed input of signature_index's input - * @prev SignTx - * @prev SimpleSignTx - * @prev TxAck - */ -message TxRequest { - optional RequestType request_type = 1; // what should be filled in TxAck message? - optional TxRequestDetailsType details = 2; // request for tx details - optional TxRequestSerializedType serialized = 3; // serialized data and request for next -} - -/** - * Request: Reported transaction data - * @prev TxRequest - * @next TxRequest - */ -message TxAck { - optional TransactionType tx = 1; -} - -/** - * Request: Ask device to sign transaction - * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing. - * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message. - * @next PassphraseRequest - * @next PinMatrixRequest - * @next EthereumTxRequest - * @next Failure - */ -message EthereumSignTx { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - optional bytes nonce = 2; // <=256 bit unsigned big endian - optional bytes gas_price = 3; // <=256 bit unsigned big endian (in wei) - optional bytes gas_limit = 4; // <=256 bit unsigned big endian - optional bytes to = 5; // 160 bit address hash - optional bytes value = 6; // <=256 bit unsigned big endian (in wei) - optional bytes data_initial_chunk = 7; // The initial data chunk (<= 1024 bytes) - optional uint32 data_length = 8; // Length of transaction payload - optional uint32 chain_id = 9; // Chain Id for EIP 155 -} - -/** - * Response: Device asks for more data from transaction payload, or returns the signature. - * If data_length is set, device awaits that many more bytes of payload. - * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present. - * @prev EthereumSignTx - * @next EthereumTxAck - */ -message EthereumTxRequest { - optional uint32 data_length = 1; // Number of bytes being requested (<= 1024) - optional uint32 signature_v = 2; // Computed signature (recovery parameter, limited to 27 or 28) - optional bytes signature_r = 3; // Computed signature R component (256 bit) - optional bytes signature_s = 4; // Computed signature S component (256 bit) -} - -/** - * Request: Transaction payload data. - * @prev EthereumTxRequest - * @next EthereumTxRequest - */ -message EthereumTxAck { - optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes) -} - -//////////////////////////////////////// -// Ethereum: Message signing messages // -//////////////////////////////////////// - -/** - * Request: Ask device to sign message - * @next EthereumMessageSignature - * @next Failure - */ -message EthereumSignMessage { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes message = 2; // message to be signed -} - -/** - * Request: Ask device to verify message - * @next Success - * @next Failure - */ -message EthereumVerifyMessage { - optional bytes address = 1; // address to verify - optional bytes signature = 2; // signature to verify - optional bytes message = 3; // message to verify -} - -/** - * Response: Signed message - * @prev EthereumSignMessage - */ -message EthereumMessageSignature { - optional bytes address = 1; // address used to sign the message - optional bytes signature = 2; // signature of the message -} - -/////////////////////// -// Identity messages // -/////////////////////// - -/** - * Request: Ask device to sign identity - * @next SignedIdentity - * @next Failure - */ -message SignIdentity { - optional IdentityType identity = 1; // identity - optional bytes challenge_hidden = 2; // non-visible challenge - optional string challenge_visual = 3; // challenge shown on display (e.g. date+time) - optional string ecdsa_curve_name = 4; // ECDSA curve name to use -} - -/** - * Response: Device provides signed identity - * @prev SignIdentity - */ -message SignedIdentity { - optional string address = 1; // identity address - optional bytes public_key = 2; // identity public key - optional bytes signature = 3; // signature of the identity data -} - -/////////////////// -// ECDH messages // -/////////////////// - -/** - * Request: Ask device to generate ECDH session key - * @next ECDHSessionKey - * @next Failure - */ -message GetECDHSessionKey { - optional IdentityType identity = 1; // identity - optional bytes peer_public_key = 2; // peer's public key - optional string ecdsa_curve_name = 3; // ECDSA curve name to use -} - -/** - * Response: Device provides ECDH session key - * @prev GetECDHSessionKey - */ -message ECDHSessionKey { - optional bytes session_key = 1; // ECDH session key -} - -/////////////////// -// U2F messages // -/////////////////// - -/** - * Request: Set U2F counter - * @next Success - */ -message SetU2FCounter { - optional uint32 u2f_counter = 1; // counter -} - -///////////////////////// -// Bootloader messages // -///////////////////////// - -/** - * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload) - * @next Success - * @next FirmwareRequest - * @next Failure - */ -message FirmwareErase { - optional uint32 length = 1; // length of new firmware -} - -/** - * Response: Ask for firmware chunk - * @next FirmwareUpload - */ -message FirmwareRequest { - optional uint32 offset = 1; // offset of requested firmware chunk - optional uint32 length = 2; // length of requested firmware chunk -} - -/** - * Request: Send firmware in binary form to the device - * @next Success - * @next Failure - */ -message FirmwareUpload { - required bytes payload = 1; // firmware to be loaded into device - optional bytes hash = 2; // hash of the payload -} - - -/** - * Request: Perform a device self-test - * @next Success - * @next Failure - */ -message SelfTest { - optional bytes payload = 1; // payload to be used in self-test -} - -///////////////////////////////////////////////////////////// -// Debug messages (only available if DebugLink is enabled) // -///////////////////////////////////////////////////////////// - -/** - * Request: "Press" the button on the device - * @next Success - */ -message DebugLinkDecision { - required bool yes_no = 1; // true for "Confirm", false for "Cancel" -} - -/** - * Request: Computer asks for device state - * @next DebugLinkState - */ -message DebugLinkGetState { -} - -/** - * Response: Device current state - * @prev DebugLinkGetState - */ -message DebugLinkState { - optional bytes layout = 1; // raw buffer of display - optional string pin = 2; // current PIN, blank if PIN is not set/enabled - optional string matrix = 3; // current PIN matrix - optional string mnemonic = 4; // current BIP-39 mnemonic - optional HDNodeType node = 5; // current BIP-32 node - optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase? - optional string reset_word = 7; // word on device display during ResetDevice workflow - optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow - optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow - optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow -} - -/** - * Request: Ask device to restart - */ -message DebugLinkStop { -} - -/** - * Response: Device wants host to log event - */ -message DebugLinkLog { - optional uint32 level = 1; - optional string bucket = 2; - optional string text = 3; -} - -/** - * Request: Read memory from device - * @next DebugLinkMemory - */ -message DebugLinkMemoryRead { - optional uint32 address = 1; - optional uint32 length = 2; -} - -/** - * Response: Device sends memory back - * @prev DebugLinkMemoryRead - */ -message DebugLinkMemory { - optional bytes memory = 1; -} - -/** - * Request: Write memory to device. - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkMemoryWrite { - optional uint32 address = 1; - optional bytes memory = 2; - optional bool flash = 3; -} -/** - * Request: Erase block of flash on device - * WARNING: Writing to the wrong location can irreparably break the device. - */ -message DebugLinkFlashErase { - optional uint32 sector = 1; + // Management + MessageType_Initialize = 0 [(wire_in) = true, (wire_tiny) = true]; + MessageType_Ping = 1 [(wire_in) = true]; + MessageType_Success = 2 [(wire_out) = true]; + MessageType_Failure = 3 [(wire_out) = true]; + MessageType_ChangePin = 4 [(wire_in) = true]; + MessageType_WipeDevice = 5 [(wire_in) = true]; + MessageType_GetEntropy = 9 [(wire_in) = true]; + MessageType_Entropy = 10 [(wire_out) = true]; + MessageType_LoadDevice = 13 [(wire_in) = true]; + MessageType_ResetDevice = 14 [(wire_in) = true]; + MessageType_Features = 17 [(wire_out) = true]; + MessageType_PinMatrixRequest = 18 [(wire_out) = true]; + MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_Cancel = 20 [(wire_in) = true, (wire_tiny) = true]; + MessageType_ClearSession = 24 [(wire_in) = true]; + MessageType_ApplySettings = 25 [(wire_in) = true]; + MessageType_ButtonRequest = 26 [(wire_out) = true]; + MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_ApplyFlags = 28 [(wire_in) = true]; + MessageType_BackupDevice = 34 [(wire_in) = true]; + MessageType_EntropyRequest = 35 [(wire_out) = true]; + MessageType_EntropyAck = 36 [(wire_in) = true]; + MessageType_PassphraseRequest = 41 [(wire_out) = true]; + MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_PassphraseStateRequest = 77 [(wire_out) = true]; + MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_RecoveryDevice = 45 [(wire_in) = true]; + MessageType_WordRequest = 46 [(wire_out) = true]; + MessageType_WordAck = 47 [(wire_in) = true]; + MessageType_GetFeatures = 55 [(wire_in) = true]; + MessageType_SetU2FCounter = 63 [(wire_in) = true]; + + // Bootloader + MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true]; + MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true]; + MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true]; + + // Bitcoin + MessageType_GetPublicKey = 11 [(wire_in) = true]; + MessageType_PublicKey = 12 [(wire_out) = true]; + MessageType_SignTx = 15 [(wire_in) = true]; + MessageType_TxRequest = 21 [(wire_out) = true]; + MessageType_TxAck = 22 [(wire_in) = true]; + MessageType_GetAddress = 29 [(wire_in) = true]; + MessageType_Address = 30 [(wire_out) = true]; + MessageType_SignMessage = 38 [(wire_in) = true]; + MessageType_VerifyMessage = 39 [(wire_in) = true]; + MessageType_MessageSignature = 40 [(wire_out) = true]; + + // Crypto + MessageType_CipherKeyValue = 23 [(wire_in) = true]; + MessageType_CipheredKeyValue = 48 [(wire_out) = true]; + MessageType_SignIdentity = 53 [(wire_in) = true]; + MessageType_SignedIdentity = 54 [(wire_out) = true]; + MessageType_GetECDHSessionKey = 61 [(wire_in) = true]; + MessageType_ECDHSessionKey = 62 [(wire_out) = true]; + MessageType_CosiCommit = 71 [(wire_in) = true]; + MessageType_CosiCommitment = 72 [(wire_out) = true]; + MessageType_CosiSign = 73 [(wire_in) = true]; + MessageType_CosiSignature = 74 [(wire_out) = true]; + + // Debug + MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true]; + MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true, (wire_tiny) = true]; + MessageType_DebugLinkState = 102 [(wire_debug_out) = true]; + MessageType_DebugLinkStop = 103 [(wire_debug_in) = true]; + MessageType_DebugLinkLog = 104 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true]; + MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true]; + MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true]; + MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true]; + + // Ethereum + MessageType_EthereumGetPublicKey = 450 [(wire_in) = true]; + MessageType_EthereumPublicKey = 451 [(wire_out) = true]; + MessageType_EthereumGetAddress = 56 [(wire_in) = true]; + MessageType_EthereumAddress = 57 [(wire_out) = true]; + MessageType_EthereumSignTx = 58 [(wire_in) = true]; + MessageType_EthereumTxRequest = 59 [(wire_out) = true]; + MessageType_EthereumTxAck = 60 [(wire_in) = true]; + MessageType_EthereumSignMessage = 64 [(wire_in) = true]; + MessageType_EthereumVerifyMessage = 65 [(wire_in) = true]; + MessageType_EthereumMessageSignature = 66 [(wire_out) = true]; + + // NEM + MessageType_NEMGetAddress = 67 [(wire_in) = true]; + MessageType_NEMAddress = 68 [(wire_out) = true]; + MessageType_NEMSignTx = 69 [(wire_in) = true]; + MessageType_NEMSignedTx = 70 [(wire_out) = true]; + MessageType_NEMDecryptMessage = 75 [(wire_in) = true]; + MessageType_NEMDecryptedMessage = 76 [(wire_out) = true]; + + // Lisk + MessageType_LiskGetAddress = 114 [(wire_in) = true]; + MessageType_LiskAddress = 115 [(wire_out) = true]; + MessageType_LiskSignTx = 116 [(wire_in) = true]; + MessageType_LiskSignedTx = 117 [(wire_out) = true]; + MessageType_LiskSignMessage = 118 [(wire_in) = true]; + MessageType_LiskMessageSignature = 119 [(wire_out) = true]; + MessageType_LiskVerifyMessage = 120 [(wire_in) = true]; + MessageType_LiskGetPublicKey = 121 [(wire_in) = true]; + MessageType_LiskPublicKey = 122 [(wire_out) = true]; + + // Tezos + MessageType_TezosGetAddress = 150 [(wire_in) = true]; + MessageType_TezosAddress = 151 [(wire_out) = true]; + MessageType_TezosSignTx = 152 [(wire_in) = true]; + MessageType_TezosSignedTx = 153 [(wire_out) = true]; + MessageType_TezosGetPublicKey = 154 [(wire_in) = true]; + MessageType_TezosPublicKey = 155 [(wire_out) = true]; + + // Stellar + MessageType_StellarSignTx = 202 [(wire_in) = true]; + MessageType_StellarTxOpRequest = 203 [(wire_out) = true]; + MessageType_StellarGetAddress = 207 [(wire_in) = true]; + MessageType_StellarAddress = 208 [(wire_out) = true]; + MessageType_StellarCreateAccountOp = 210 [(wire_in) = true]; + MessageType_StellarPaymentOp = 211 [(wire_in) = true]; + MessageType_StellarPathPaymentOp = 212 [(wire_in) = true]; + MessageType_StellarManageOfferOp = 213 [(wire_in) = true]; + MessageType_StellarCreatePassiveOfferOp = 214 [(wire_in) = true]; + MessageType_StellarSetOptionsOp = 215 [(wire_in) = true]; + MessageType_StellarChangeTrustOp = 216 [(wire_in) = true]; + MessageType_StellarAllowTrustOp = 217 [(wire_in) = true]; + MessageType_StellarAccountMergeOp = 218 [(wire_in) = true]; + // omitted: StellarInflationOp is not a supported operation, would be 219 + MessageType_StellarManageDataOp = 220 [(wire_in) = true]; + MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true]; + MessageType_StellarSignedTx = 230 [(wire_out) = true]; + + // TRON + MessageType_TronGetAddress = 250 [(wire_in) = true]; + MessageType_TronAddress = 251 [(wire_out) = true]; + MessageType_TronSignTx = 252 [(wire_in) = true]; + MessageType_TronSignedTx = 253 [(wire_out) = true]; + + // Cardano + // dropped Sign/VerifyMessage ids 300-302 + MessageType_CardanoSignTx = 303 [(wire_in) = true]; + MessageType_CardanoTxRequest = 304 [(wire_out) = true]; + MessageType_CardanoGetPublicKey = 305 [(wire_in) = true]; + MessageType_CardanoPublicKey = 306 [(wire_out) = true]; + MessageType_CardanoGetAddress = 307 [(wire_in) = true]; + MessageType_CardanoAddress = 308 [(wire_out) = true]; + MessageType_CardanoTxAck = 309 [(wire_in) = true]; + MessageType_CardanoSignedTx = 310 [(wire_out) = true]; + + // Ontology + MessageType_OntologyGetAddress = 350 [(wire_in) = true]; + MessageType_OntologyAddress = 351 [(wire_out) = true]; + MessageType_OntologyGetPublicKey = 352 [(wire_in) = true]; + MessageType_OntologyPublicKey = 353 [(wire_out) = true]; + MessageType_OntologySignTransfer = 354 [(wire_in) = true]; + MessageType_OntologySignedTransfer = 355 [(wire_out) = true]; + MessageType_OntologySignWithdrawOng = 356 [(wire_in) = true]; + MessageType_OntologySignedWithdrawOng = 357 [(wire_out) = true]; + MessageType_OntologySignOntIdRegister = 358 [(wire_in) = true]; + MessageType_OntologySignedOntIdRegister = 359 [(wire_out) = true]; + MessageType_OntologySignOntIdAddAttributes = 360 [(wire_in) = true]; + MessageType_OntologySignedOntIdAddAttributes = 361 [(wire_out) = true]; + + // Ripple + MessageType_RippleGetAddress = 400 [(wire_in) = true]; + MessageType_RippleAddress = 401 [(wire_out) = true]; + MessageType_RippleSignTx = 402 [(wire_in) = true]; + MessageType_RippleSignedTx = 403 [(wire_in) = true]; + + // Monero + MessageType_MoneroTransactionInitRequest = 501 [(wire_out) = true]; + MessageType_MoneroTransactionInitAck = 502 [(wire_out) = true]; + MessageType_MoneroTransactionSetInputRequest = 503 [(wire_out) = true]; + MessageType_MoneroTransactionSetInputAck = 504 [(wire_out) = true]; + MessageType_MoneroTransactionInputsPermutationRequest = 505 [(wire_out) = true]; + MessageType_MoneroTransactionInputsPermutationAck = 506 [(wire_out) = true]; + MessageType_MoneroTransactionInputViniRequest = 507 [(wire_out) = true]; + MessageType_MoneroTransactionInputViniAck = 508 [(wire_out) = true]; + MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_out) = true]; + MessageType_MoneroTransactionAllInputsSetAck = 510 [(wire_out) = true]; + MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_out) = true]; + MessageType_MoneroTransactionSetOutputAck = 512 [(wire_out) = true]; + MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_out) = true]; + MessageType_MoneroTransactionAllOutSetAck = 514 [(wire_out) = true]; + MessageType_MoneroTransactionSignInputRequest = 515 [(wire_out) = true]; + MessageType_MoneroTransactionSignInputAck = 516 [(wire_out) = true]; + MessageType_MoneroTransactionFinalRequest = 517 [(wire_out) = true]; + MessageType_MoneroTransactionFinalAck = 518 [(wire_out) = true]; + MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_out) = true]; + MessageType_MoneroKeyImageExportInitAck = 531 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncStepAck = 533 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_out) = true]; + MessageType_MoneroKeyImageSyncFinalAck = 535 [(wire_out) = true]; + MessageType_MoneroGetAddress = 540 [(wire_in) = true]; + MessageType_MoneroAddress = 541 [(wire_out) = true]; + MessageType_MoneroGetWatchKey = 542 [(wire_in) = true]; + MessageType_MoneroWatchKey = 543 [(wire_out) = true]; + MessageType_DebugMoneroDiagRequest = 546 [(wire_in) = true]; + MessageType_DebugMoneroDiagAck = 547 [(wire_out) = true]; + MessageType_MoneroGetTxKeyRequest = 550 [(wire_in) = true]; + MessageType_MoneroGetTxKeyAck = 551 [(wire_out) = true]; + MessageType_MoneroLiveRefreshStartRequest = 552 [(wire_in) = true]; + MessageType_MoneroLiveRefreshStartAck = 553 [(wire_out) = true]; + MessageType_MoneroLiveRefreshStepRequest = 554 [(wire_in) = true]; + MessageType_MoneroLiveRefreshStepAck = 555 [(wire_out) = true]; + MessageType_MoneroLiveRefreshFinalRequest = 556 [(wire_in) = true]; + MessageType_MoneroLiveRefreshFinalAck = 557 [(wire_out) = true]; + + // EOS + MessageType_EosGetPublicKey = 600 [(wire_in) = true]; + MessageType_EosPublicKey = 601 [(wire_out) = true]; + MessageType_EosSignTx = 602 [(wire_in) = true]; + MessageType_EosTxActionRequest = 603 [(wire_out) = true]; + MessageType_EosTxActionAck = 604 [(wire_in) = true]; + MessageType_EosSignedTx = 605 [(wire_out) = true]; + + // Binance + MessageType_BinanceGetAddress = 700 [(wire_in) = true]; + MessageType_BinanceAddress = 701 [(wire_out) = true]; + MessageType_BinanceGetPublicKey = 702 [(wire_in) = true]; + MessageType_BinancePublicKey = 703 [(wire_out) = true]; + MessageType_BinanceSignTx = 704 [(wire_in) = true]; + MessageType_BinanceTxRequest = 705 [(wire_out) = true]; + MessageType_BinanceTransferMsg = 706 [(wire_in) = true]; + MessageType_BinanceOrderMsg = 707 [(wire_in) = true]; + MessageType_BinanceCancelMsg = 708 [(wire_in) = true]; + MessageType_BinanceSignedTx = 709 [(wire_out) = true]; } diff --git a/accounts/usbwallet/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go index 80cc75efc4..a259c1dce9 100644 --- a/accounts/usbwallet/trezor/trezor.go +++ b/accounts/usbwallet/trezor/trezor.go @@ -1,4 +1,4 @@ -// Copyright 2017 The go-ethereum Authors +// Copyright 2019 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 @@ -16,11 +16,35 @@ // This file contains the implementation for interacting with the Trezor hardware // wallets. The wire protocol spec can be found on the SatoshiLabs website: -// https://doc.satoshilabs.com/trezor-tech/api-protobuf.html +// https://wiki.trezor.io/Developers_guide-Message_Workflows -//go:generate protoc --go_out=import_path=trezor:. types.proto messages.proto +// !!! STAHP !!! +// +// Before you touch the protocol files, you need to be aware of a breaking change +// that occurred between firmware versions 1.7.3->1.8.0 (Model One) and 2.0.10-> +// 2.1.0 (Model T). The Ethereum address representation was changed from the 20 +// byte binary blob to a 42 byte hex string. The upstream protocol buffer files +// only support the new format, so blindly pulling in a new spec will break old +// devices! +// +// The Trezor devs had the foresight to add the string version as a new message +// code instead of replacing the binary one. This means that the proto file can +// actually define both the old and the new versions as optional. Please ensure +// that you add back the old addresses everywhere (to avoid name clash. use the +// addressBin and addressHex names). +// +// If in doubt, reach out to @karalabe. -// Package trezor contains the wire protocol wrapper in Go. +// To regenerate the protocol files in this package: +// - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases +// - Build with the usual `./configure && make` and ensure it's on your $PATH +// - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor +// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go` +// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...` + +//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto + +// Package trezor contains the wire protocol. package trezor import ( diff --git a/accounts/usbwallet/trezor/types.pb.go b/accounts/usbwallet/trezor/types.pb.go deleted file mode 100644 index 25b7672d23..0000000000 --- a/accounts/usbwallet/trezor/types.pb.go +++ /dev/null @@ -1,1333 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: types.proto - -/* -Package trezor is a generated protocol buffer package. - -It is generated from these files: - types.proto - messages.proto - -It has these top-level messages: - HDNodeType - HDNodePathType - CoinType - MultisigRedeemScriptType - TxInputType - TxOutputType - TxOutputBinType - TransactionType - TxRequestDetailsType - TxRequestSerializedType - IdentityType - Initialize - GetFeatures - Features - ClearSession - ApplySettings - ApplyFlags - ChangePin - Ping - Success - Failure - ButtonRequest - ButtonAck - PinMatrixRequest - PinMatrixAck - Cancel - PassphraseRequest - PassphraseAck - GetEntropy - Entropy - GetPublicKey - PublicKey - GetAddress - EthereumGetAddress - Address - EthereumAddress - WipeDevice - LoadDevice - ResetDevice - BackupDevice - EntropyRequest - EntropyAck - RecoveryDevice - WordRequest - WordAck - SignMessage - VerifyMessage - MessageSignature - EncryptMessage - EncryptedMessage - DecryptMessage - DecryptedMessage - CipherKeyValue - CipheredKeyValue - EstimateTxSize - TxSize - SignTx - SimpleSignTx - TxRequest - TxAck - EthereumSignTx - EthereumTxRequest - EthereumTxAck - EthereumSignMessage - EthereumVerifyMessage - EthereumMessageSignature - SignIdentity - SignedIdentity - GetECDHSessionKey - ECDHSessionKey - SetU2FCounter - FirmwareErase - FirmwareRequest - FirmwareUpload - SelfTest - DebugLinkDecision - DebugLinkGetState - DebugLinkState - DebugLinkStop - DebugLinkLog - DebugLinkMemoryRead - DebugLinkMemory - DebugLinkMemoryWrite - DebugLinkFlashErase -*/ -package trezor - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// * -// Type of failures returned by Failure message -// @used_in Failure -type FailureType int32 - -const ( - FailureType_Failure_UnexpectedMessage FailureType = 1 - FailureType_Failure_ButtonExpected FailureType = 2 - FailureType_Failure_DataError FailureType = 3 - FailureType_Failure_ActionCancelled FailureType = 4 - FailureType_Failure_PinExpected FailureType = 5 - FailureType_Failure_PinCancelled FailureType = 6 - FailureType_Failure_PinInvalid FailureType = 7 - FailureType_Failure_InvalidSignature FailureType = 8 - FailureType_Failure_ProcessError FailureType = 9 - FailureType_Failure_NotEnoughFunds FailureType = 10 - FailureType_Failure_NotInitialized FailureType = 11 - FailureType_Failure_FirmwareError FailureType = 99 -) - -var FailureType_name = map[int32]string{ - 1: "Failure_UnexpectedMessage", - 2: "Failure_ButtonExpected", - 3: "Failure_DataError", - 4: "Failure_ActionCancelled", - 5: "Failure_PinExpected", - 6: "Failure_PinCancelled", - 7: "Failure_PinInvalid", - 8: "Failure_InvalidSignature", - 9: "Failure_ProcessError", - 10: "Failure_NotEnoughFunds", - 11: "Failure_NotInitialized", - 99: "Failure_FirmwareError", -} -var FailureType_value = map[string]int32{ - "Failure_UnexpectedMessage": 1, - "Failure_ButtonExpected": 2, - "Failure_DataError": 3, - "Failure_ActionCancelled": 4, - "Failure_PinExpected": 5, - "Failure_PinCancelled": 6, - "Failure_PinInvalid": 7, - "Failure_InvalidSignature": 8, - "Failure_ProcessError": 9, - "Failure_NotEnoughFunds": 10, - "Failure_NotInitialized": 11, - "Failure_FirmwareError": 99, -} - -func (x FailureType) Enum() *FailureType { - p := new(FailureType) - *p = x - return p -} -func (x FailureType) String() string { - return proto.EnumName(FailureType_name, int32(x)) -} -func (x *FailureType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FailureType_value, data, "FailureType") - if err != nil { - return err - } - *x = FailureType(value) - return nil -} -func (FailureType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -// * -// Type of script which will be used for transaction output -// @used_in TxOutputType -type OutputScriptType int32 - -const ( - OutputScriptType_PAYTOADDRESS OutputScriptType = 0 - OutputScriptType_PAYTOSCRIPTHASH OutputScriptType = 1 - OutputScriptType_PAYTOMULTISIG OutputScriptType = 2 - OutputScriptType_PAYTOOPRETURN OutputScriptType = 3 - OutputScriptType_PAYTOWITNESS OutputScriptType = 4 - OutputScriptType_PAYTOP2SHWITNESS OutputScriptType = 5 -) - -var OutputScriptType_name = map[int32]string{ - 0: "PAYTOADDRESS", - 1: "PAYTOSCRIPTHASH", - 2: "PAYTOMULTISIG", - 3: "PAYTOOPRETURN", - 4: "PAYTOWITNESS", - 5: "PAYTOP2SHWITNESS", -} -var OutputScriptType_value = map[string]int32{ - "PAYTOADDRESS": 0, - "PAYTOSCRIPTHASH": 1, - "PAYTOMULTISIG": 2, - "PAYTOOPRETURN": 3, - "PAYTOWITNESS": 4, - "PAYTOP2SHWITNESS": 5, -} - -func (x OutputScriptType) Enum() *OutputScriptType { - p := new(OutputScriptType) - *p = x - return p -} -func (x OutputScriptType) String() string { - return proto.EnumName(OutputScriptType_name, int32(x)) -} -func (x *OutputScriptType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(OutputScriptType_value, data, "OutputScriptType") - if err != nil { - return err - } - *x = OutputScriptType(value) - return nil -} -func (OutputScriptType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -// * -// Type of script which will be used for transaction output -// @used_in TxInputType -type InputScriptType int32 - -const ( - InputScriptType_SPENDADDRESS InputScriptType = 0 - InputScriptType_SPENDMULTISIG InputScriptType = 1 - InputScriptType_EXTERNAL InputScriptType = 2 - InputScriptType_SPENDWITNESS InputScriptType = 3 - InputScriptType_SPENDP2SHWITNESS InputScriptType = 4 -) - -var InputScriptType_name = map[int32]string{ - 0: "SPENDADDRESS", - 1: "SPENDMULTISIG", - 2: "EXTERNAL", - 3: "SPENDWITNESS", - 4: "SPENDP2SHWITNESS", -} -var InputScriptType_value = map[string]int32{ - "SPENDADDRESS": 0, - "SPENDMULTISIG": 1, - "EXTERNAL": 2, - "SPENDWITNESS": 3, - "SPENDP2SHWITNESS": 4, -} - -func (x InputScriptType) Enum() *InputScriptType { - p := new(InputScriptType) - *p = x - return p -} -func (x InputScriptType) String() string { - return proto.EnumName(InputScriptType_name, int32(x)) -} -func (x *InputScriptType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(InputScriptType_value, data, "InputScriptType") - if err != nil { - return err - } - *x = InputScriptType(value) - return nil -} -func (InputScriptType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -// * -// Type of information required by transaction signing process -// @used_in TxRequest -type RequestType int32 - -const ( - RequestType_TXINPUT RequestType = 0 - RequestType_TXOUTPUT RequestType = 1 - RequestType_TXMETA RequestType = 2 - RequestType_TXFINISHED RequestType = 3 - RequestType_TXEXTRADATA RequestType = 4 -) - -var RequestType_name = map[int32]string{ - 0: "TXINPUT", - 1: "TXOUTPUT", - 2: "TXMETA", - 3: "TXFINISHED", - 4: "TXEXTRADATA", -} -var RequestType_value = map[string]int32{ - "TXINPUT": 0, - "TXOUTPUT": 1, - "TXMETA": 2, - "TXFINISHED": 3, - "TXEXTRADATA": 4, -} - -func (x RequestType) Enum() *RequestType { - p := new(RequestType) - *p = x - return p -} -func (x RequestType) String() string { - return proto.EnumName(RequestType_name, int32(x)) -} -func (x *RequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RequestType_value, data, "RequestType") - if err != nil { - return err - } - *x = RequestType(value) - return nil -} -func (RequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -// * -// Type of button request -// @used_in ButtonRequest -type ButtonRequestType int32 - -const ( - ButtonRequestType_ButtonRequest_Other ButtonRequestType = 1 - ButtonRequestType_ButtonRequest_FeeOverThreshold ButtonRequestType = 2 - ButtonRequestType_ButtonRequest_ConfirmOutput ButtonRequestType = 3 - ButtonRequestType_ButtonRequest_ResetDevice ButtonRequestType = 4 - ButtonRequestType_ButtonRequest_ConfirmWord ButtonRequestType = 5 - ButtonRequestType_ButtonRequest_WipeDevice ButtonRequestType = 6 - ButtonRequestType_ButtonRequest_ProtectCall ButtonRequestType = 7 - ButtonRequestType_ButtonRequest_SignTx ButtonRequestType = 8 - ButtonRequestType_ButtonRequest_FirmwareCheck ButtonRequestType = 9 - ButtonRequestType_ButtonRequest_Address ButtonRequestType = 10 - ButtonRequestType_ButtonRequest_PublicKey ButtonRequestType = 11 -) - -var ButtonRequestType_name = map[int32]string{ - 1: "ButtonRequest_Other", - 2: "ButtonRequest_FeeOverThreshold", - 3: "ButtonRequest_ConfirmOutput", - 4: "ButtonRequest_ResetDevice", - 5: "ButtonRequest_ConfirmWord", - 6: "ButtonRequest_WipeDevice", - 7: "ButtonRequest_ProtectCall", - 8: "ButtonRequest_SignTx", - 9: "ButtonRequest_FirmwareCheck", - 10: "ButtonRequest_Address", - 11: "ButtonRequest_PublicKey", -} -var ButtonRequestType_value = map[string]int32{ - "ButtonRequest_Other": 1, - "ButtonRequest_FeeOverThreshold": 2, - "ButtonRequest_ConfirmOutput": 3, - "ButtonRequest_ResetDevice": 4, - "ButtonRequest_ConfirmWord": 5, - "ButtonRequest_WipeDevice": 6, - "ButtonRequest_ProtectCall": 7, - "ButtonRequest_SignTx": 8, - "ButtonRequest_FirmwareCheck": 9, - "ButtonRequest_Address": 10, - "ButtonRequest_PublicKey": 11, -} - -func (x ButtonRequestType) Enum() *ButtonRequestType { - p := new(ButtonRequestType) - *p = x - return p -} -func (x ButtonRequestType) String() string { - return proto.EnumName(ButtonRequestType_name, int32(x)) -} -func (x *ButtonRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ButtonRequestType_value, data, "ButtonRequestType") - if err != nil { - return err - } - *x = ButtonRequestType(value) - return nil -} -func (ButtonRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -// * -// Type of PIN request -// @used_in PinMatrixRequest -type PinMatrixRequestType int32 - -const ( - PinMatrixRequestType_PinMatrixRequestType_Current PinMatrixRequestType = 1 - PinMatrixRequestType_PinMatrixRequestType_NewFirst PinMatrixRequestType = 2 - PinMatrixRequestType_PinMatrixRequestType_NewSecond PinMatrixRequestType = 3 -) - -var PinMatrixRequestType_name = map[int32]string{ - 1: "PinMatrixRequestType_Current", - 2: "PinMatrixRequestType_NewFirst", - 3: "PinMatrixRequestType_NewSecond", -} -var PinMatrixRequestType_value = map[string]int32{ - "PinMatrixRequestType_Current": 1, - "PinMatrixRequestType_NewFirst": 2, - "PinMatrixRequestType_NewSecond": 3, -} - -func (x PinMatrixRequestType) Enum() *PinMatrixRequestType { - p := new(PinMatrixRequestType) - *p = x - return p -} -func (x PinMatrixRequestType) String() string { - return proto.EnumName(PinMatrixRequestType_name, int32(x)) -} -func (x *PinMatrixRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(PinMatrixRequestType_value, data, "PinMatrixRequestType") - if err != nil { - return err - } - *x = PinMatrixRequestType(value) - return nil -} -func (PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -// * -// Type of recovery procedure. These should be used as bitmask, e.g., -// `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` -// listing every method supported by the host computer. -// -// Note that ScrambledWords must be supported by every implementation -// for backward compatibility; there is no way to not support it. -// -// @used_in RecoveryDevice -type RecoveryDeviceType int32 - -const ( - // use powers of two when extending this field - RecoveryDeviceType_RecoveryDeviceType_ScrambledWords RecoveryDeviceType = 0 - RecoveryDeviceType_RecoveryDeviceType_Matrix RecoveryDeviceType = 1 -) - -var RecoveryDeviceType_name = map[int32]string{ - 0: "RecoveryDeviceType_ScrambledWords", - 1: "RecoveryDeviceType_Matrix", -} -var RecoveryDeviceType_value = map[string]int32{ - "RecoveryDeviceType_ScrambledWords": 0, - "RecoveryDeviceType_Matrix": 1, -} - -func (x RecoveryDeviceType) Enum() *RecoveryDeviceType { - p := new(RecoveryDeviceType) - *p = x - return p -} -func (x RecoveryDeviceType) String() string { - return proto.EnumName(RecoveryDeviceType_name, int32(x)) -} -func (x *RecoveryDeviceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RecoveryDeviceType_value, data, "RecoveryDeviceType") - if err != nil { - return err - } - *x = RecoveryDeviceType(value) - return nil -} -func (RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -// * -// Type of Recovery Word request -// @used_in WordRequest -type WordRequestType int32 - -const ( - WordRequestType_WordRequestType_Plain WordRequestType = 0 - WordRequestType_WordRequestType_Matrix9 WordRequestType = 1 - WordRequestType_WordRequestType_Matrix6 WordRequestType = 2 -) - -var WordRequestType_name = map[int32]string{ - 0: "WordRequestType_Plain", - 1: "WordRequestType_Matrix9", - 2: "WordRequestType_Matrix6", -} -var WordRequestType_value = map[string]int32{ - "WordRequestType_Plain": 0, - "WordRequestType_Matrix9": 1, - "WordRequestType_Matrix6": 2, -} - -func (x WordRequestType) Enum() *WordRequestType { - p := new(WordRequestType) - *p = x - return p -} -func (x WordRequestType) String() string { - return proto.EnumName(WordRequestType_name, int32(x)) -} -func (x *WordRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(WordRequestType_value, data, "WordRequestType") - if err != nil { - return err - } - *x = WordRequestType(value) - return nil -} -func (WordRequestType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -// * -// Structure representing BIP32 (hierarchical deterministic) node -// Used for imports of private key into the device and exporting public key out of device -// @used_in PublicKey -// @used_in LoadDevice -// @used_in DebugLinkState -// @used_in Storage -type HDNodeType struct { - Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` - Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` - ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` - ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` - PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` - PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *HDNodeType) Reset() { *m = HDNodeType{} } -func (m *HDNodeType) String() string { return proto.CompactTextString(m) } -func (*HDNodeType) ProtoMessage() {} -func (*HDNodeType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *HDNodeType) GetDepth() uint32 { - if m != nil && m.Depth != nil { - return *m.Depth - } - return 0 -} - -func (m *HDNodeType) GetFingerprint() uint32 { - if m != nil && m.Fingerprint != nil { - return *m.Fingerprint - } - return 0 -} - -func (m *HDNodeType) GetChildNum() uint32 { - if m != nil && m.ChildNum != nil { - return *m.ChildNum - } - return 0 -} - -func (m *HDNodeType) GetChainCode() []byte { - if m != nil { - return m.ChainCode - } - return nil -} - -func (m *HDNodeType) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey - } - return nil -} - -func (m *HDNodeType) GetPublicKey() []byte { - if m != nil { - return m.PublicKey - } - return nil -} - -type HDNodePathType struct { - Node *HDNodeType `protobuf:"bytes,1,req,name=node" json:"node,omitempty"` - AddressN []uint32 `protobuf:"varint,2,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *HDNodePathType) Reset() { *m = HDNodePathType{} } -func (m *HDNodePathType) String() string { return proto.CompactTextString(m) } -func (*HDNodePathType) ProtoMessage() {} -func (*HDNodePathType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *HDNodePathType) GetNode() *HDNodeType { - if m != nil { - return m.Node - } - return nil -} - -func (m *HDNodePathType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -// * -// Structure representing Coin -// @used_in Features -type CoinType struct { - CoinName *string `protobuf:"bytes,1,opt,name=coin_name,json=coinName" json:"coin_name,omitempty"` - CoinShortcut *string `protobuf:"bytes,2,opt,name=coin_shortcut,json=coinShortcut" json:"coin_shortcut,omitempty"` - AddressType *uint32 `protobuf:"varint,3,opt,name=address_type,json=addressType,def=0" json:"address_type,omitempty"` - MaxfeeKb *uint64 `protobuf:"varint,4,opt,name=maxfee_kb,json=maxfeeKb" json:"maxfee_kb,omitempty"` - AddressTypeP2Sh *uint32 `protobuf:"varint,5,opt,name=address_type_p2sh,json=addressTypeP2sh,def=5" json:"address_type_p2sh,omitempty"` - SignedMessageHeader *string `protobuf:"bytes,8,opt,name=signed_message_header,json=signedMessageHeader" json:"signed_message_header,omitempty"` - XpubMagic *uint32 `protobuf:"varint,9,opt,name=xpub_magic,json=xpubMagic,def=76067358" json:"xpub_magic,omitempty"` - XprvMagic *uint32 `protobuf:"varint,10,opt,name=xprv_magic,json=xprvMagic,def=76066276" json:"xprv_magic,omitempty"` - Segwit *bool `protobuf:"varint,11,opt,name=segwit" json:"segwit,omitempty"` - Forkid *uint32 `protobuf:"varint,12,opt,name=forkid" json:"forkid,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *CoinType) Reset() { *m = CoinType{} } -func (m *CoinType) String() string { return proto.CompactTextString(m) } -func (*CoinType) ProtoMessage() {} -func (*CoinType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -const Default_CoinType_AddressType uint32 = 0 -const Default_CoinType_AddressTypeP2Sh uint32 = 5 -const Default_CoinType_XpubMagic uint32 = 76067358 -const Default_CoinType_XprvMagic uint32 = 76066276 - -func (m *CoinType) GetCoinName() string { - if m != nil && m.CoinName != nil { - return *m.CoinName - } - return "" -} - -func (m *CoinType) GetCoinShortcut() string { - if m != nil && m.CoinShortcut != nil { - return *m.CoinShortcut - } - return "" -} - -func (m *CoinType) GetAddressType() uint32 { - if m != nil && m.AddressType != nil { - return *m.AddressType - } - return Default_CoinType_AddressType -} - -func (m *CoinType) GetMaxfeeKb() uint64 { - if m != nil && m.MaxfeeKb != nil { - return *m.MaxfeeKb - } - return 0 -} - -func (m *CoinType) GetAddressTypeP2Sh() uint32 { - if m != nil && m.AddressTypeP2Sh != nil { - return *m.AddressTypeP2Sh - } - return Default_CoinType_AddressTypeP2Sh -} - -func (m *CoinType) GetSignedMessageHeader() string { - if m != nil && m.SignedMessageHeader != nil { - return *m.SignedMessageHeader - } - return "" -} - -func (m *CoinType) GetXpubMagic() uint32 { - if m != nil && m.XpubMagic != nil { - return *m.XpubMagic - } - return Default_CoinType_XpubMagic -} - -func (m *CoinType) GetXprvMagic() uint32 { - if m != nil && m.XprvMagic != nil { - return *m.XprvMagic - } - return Default_CoinType_XprvMagic -} - -func (m *CoinType) GetSegwit() bool { - if m != nil && m.Segwit != nil { - return *m.Segwit - } - return false -} - -func (m *CoinType) GetForkid() uint32 { - if m != nil && m.Forkid != nil { - return *m.Forkid - } - return 0 -} - -// * -// Type of redeem script used in input -// @used_in TxInputType -type MultisigRedeemScriptType struct { - Pubkeys []*HDNodePathType `protobuf:"bytes,1,rep,name=pubkeys" json:"pubkeys,omitempty"` - Signatures [][]byte `protobuf:"bytes,2,rep,name=signatures" json:"signatures,omitempty"` - M *uint32 `protobuf:"varint,3,opt,name=m" json:"m,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *MultisigRedeemScriptType) Reset() { *m = MultisigRedeemScriptType{} } -func (m *MultisigRedeemScriptType) String() string { return proto.CompactTextString(m) } -func (*MultisigRedeemScriptType) ProtoMessage() {} -func (*MultisigRedeemScriptType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -func (m *MultisigRedeemScriptType) GetPubkeys() []*HDNodePathType { - if m != nil { - return m.Pubkeys - } - return nil -} - -func (m *MultisigRedeemScriptType) GetSignatures() [][]byte { - if m != nil { - return m.Signatures - } - return nil -} - -func (m *MultisigRedeemScriptType) GetM() uint32 { - if m != nil && m.M != nil { - return *m.M - } - return 0 -} - -// * -// Structure representing transaction input -// @used_in SimpleSignTx -// @used_in TransactionType -type TxInputType struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - PrevHash []byte `protobuf:"bytes,2,req,name=prev_hash,json=prevHash" json:"prev_hash,omitempty"` - PrevIndex *uint32 `protobuf:"varint,3,req,name=prev_index,json=prevIndex" json:"prev_index,omitempty"` - ScriptSig []byte `protobuf:"bytes,4,opt,name=script_sig,json=scriptSig" json:"script_sig,omitempty"` - Sequence *uint32 `protobuf:"varint,5,opt,name=sequence,def=4294967295" json:"sequence,omitempty"` - ScriptType *InputScriptType `protobuf:"varint,6,opt,name=script_type,json=scriptType,enum=InputScriptType,def=0" json:"script_type,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,7,opt,name=multisig" json:"multisig,omitempty"` - Amount *uint64 `protobuf:"varint,8,opt,name=amount" json:"amount,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxInputType) Reset() { *m = TxInputType{} } -func (m *TxInputType) String() string { return proto.CompactTextString(m) } -func (*TxInputType) ProtoMessage() {} -func (*TxInputType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -const Default_TxInputType_Sequence uint32 = 4294967295 -const Default_TxInputType_ScriptType InputScriptType = InputScriptType_SPENDADDRESS - -func (m *TxInputType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *TxInputType) GetPrevHash() []byte { - if m != nil { - return m.PrevHash - } - return nil -} - -func (m *TxInputType) GetPrevIndex() uint32 { - if m != nil && m.PrevIndex != nil { - return *m.PrevIndex - } - return 0 -} - -func (m *TxInputType) GetScriptSig() []byte { - if m != nil { - return m.ScriptSig - } - return nil -} - -func (m *TxInputType) GetSequence() uint32 { - if m != nil && m.Sequence != nil { - return *m.Sequence - } - return Default_TxInputType_Sequence -} - -func (m *TxInputType) GetScriptType() InputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return Default_TxInputType_ScriptType -} - -func (m *TxInputType) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *TxInputType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -// * -// Structure representing transaction output -// @used_in SimpleSignTx -// @used_in TransactionType -type TxOutputType struct { - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - AddressN []uint32 `protobuf:"varint,2,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Amount *uint64 `protobuf:"varint,3,req,name=amount" json:"amount,omitempty"` - ScriptType *OutputScriptType `protobuf:"varint,4,req,name=script_type,json=scriptType,enum=OutputScriptType" json:"script_type,omitempty"` - Multisig *MultisigRedeemScriptType `protobuf:"bytes,5,opt,name=multisig" json:"multisig,omitempty"` - OpReturnData []byte `protobuf:"bytes,6,opt,name=op_return_data,json=opReturnData" json:"op_return_data,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxOutputType) Reset() { *m = TxOutputType{} } -func (m *TxOutputType) String() string { return proto.CompactTextString(m) } -func (*TxOutputType) ProtoMessage() {} -func (*TxOutputType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -func (m *TxOutputType) GetAddress() string { - if m != nil && m.Address != nil { - return *m.Address - } - return "" -} - -func (m *TxOutputType) GetAddressN() []uint32 { - if m != nil { - return m.AddressN - } - return nil -} - -func (m *TxOutputType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -func (m *TxOutputType) GetScriptType() OutputScriptType { - if m != nil && m.ScriptType != nil { - return *m.ScriptType - } - return OutputScriptType_PAYTOADDRESS -} - -func (m *TxOutputType) GetMultisig() *MultisigRedeemScriptType { - if m != nil { - return m.Multisig - } - return nil -} - -func (m *TxOutputType) GetOpReturnData() []byte { - if m != nil { - return m.OpReturnData - } - return nil -} - -// * -// Structure representing compiled transaction output -// @used_in TransactionType -type TxOutputBinType struct { - Amount *uint64 `protobuf:"varint,1,req,name=amount" json:"amount,omitempty"` - ScriptPubkey []byte `protobuf:"bytes,2,req,name=script_pubkey,json=scriptPubkey" json:"script_pubkey,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxOutputBinType) Reset() { *m = TxOutputBinType{} } -func (m *TxOutputBinType) String() string { return proto.CompactTextString(m) } -func (*TxOutputBinType) ProtoMessage() {} -func (*TxOutputBinType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -func (m *TxOutputBinType) GetAmount() uint64 { - if m != nil && m.Amount != nil { - return *m.Amount - } - return 0 -} - -func (m *TxOutputBinType) GetScriptPubkey() []byte { - if m != nil { - return m.ScriptPubkey - } - return nil -} - -// * -// Structure representing transaction -// @used_in SimpleSignTx -type TransactionType struct { - Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` - Inputs []*TxInputType `protobuf:"bytes,2,rep,name=inputs" json:"inputs,omitempty"` - BinOutputs []*TxOutputBinType `protobuf:"bytes,3,rep,name=bin_outputs,json=binOutputs" json:"bin_outputs,omitempty"` - Outputs []*TxOutputType `protobuf:"bytes,5,rep,name=outputs" json:"outputs,omitempty"` - LockTime *uint32 `protobuf:"varint,4,opt,name=lock_time,json=lockTime" json:"lock_time,omitempty"` - InputsCnt *uint32 `protobuf:"varint,6,opt,name=inputs_cnt,json=inputsCnt" json:"inputs_cnt,omitempty"` - OutputsCnt *uint32 `protobuf:"varint,7,opt,name=outputs_cnt,json=outputsCnt" json:"outputs_cnt,omitempty"` - ExtraData []byte `protobuf:"bytes,8,opt,name=extra_data,json=extraData" json:"extra_data,omitempty"` - ExtraDataLen *uint32 `protobuf:"varint,9,opt,name=extra_data_len,json=extraDataLen" json:"extra_data_len,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TransactionType) Reset() { *m = TransactionType{} } -func (m *TransactionType) String() string { return proto.CompactTextString(m) } -func (*TransactionType) ProtoMessage() {} -func (*TransactionType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -func (m *TransactionType) GetVersion() uint32 { - if m != nil && m.Version != nil { - return *m.Version - } - return 0 -} - -func (m *TransactionType) GetInputs() []*TxInputType { - if m != nil { - return m.Inputs - } - return nil -} - -func (m *TransactionType) GetBinOutputs() []*TxOutputBinType { - if m != nil { - return m.BinOutputs - } - return nil -} - -func (m *TransactionType) GetOutputs() []*TxOutputType { - if m != nil { - return m.Outputs - } - return nil -} - -func (m *TransactionType) GetLockTime() uint32 { - if m != nil && m.LockTime != nil { - return *m.LockTime - } - return 0 -} - -func (m *TransactionType) GetInputsCnt() uint32 { - if m != nil && m.InputsCnt != nil { - return *m.InputsCnt - } - return 0 -} - -func (m *TransactionType) GetOutputsCnt() uint32 { - if m != nil && m.OutputsCnt != nil { - return *m.OutputsCnt - } - return 0 -} - -func (m *TransactionType) GetExtraData() []byte { - if m != nil { - return m.ExtraData - } - return nil -} - -func (m *TransactionType) GetExtraDataLen() uint32 { - if m != nil && m.ExtraDataLen != nil { - return *m.ExtraDataLen - } - return 0 -} - -// * -// Structure representing request details -// @used_in TxRequest -type TxRequestDetailsType struct { - RequestIndex *uint32 `protobuf:"varint,1,opt,name=request_index,json=requestIndex" json:"request_index,omitempty"` - TxHash []byte `protobuf:"bytes,2,opt,name=tx_hash,json=txHash" json:"tx_hash,omitempty"` - ExtraDataLen *uint32 `protobuf:"varint,3,opt,name=extra_data_len,json=extraDataLen" json:"extra_data_len,omitempty"` - ExtraDataOffset *uint32 `protobuf:"varint,4,opt,name=extra_data_offset,json=extraDataOffset" json:"extra_data_offset,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxRequestDetailsType) Reset() { *m = TxRequestDetailsType{} } -func (m *TxRequestDetailsType) String() string { return proto.CompactTextString(m) } -func (*TxRequestDetailsType) ProtoMessage() {} -func (*TxRequestDetailsType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *TxRequestDetailsType) GetRequestIndex() uint32 { - if m != nil && m.RequestIndex != nil { - return *m.RequestIndex - } - return 0 -} - -func (m *TxRequestDetailsType) GetTxHash() []byte { - if m != nil { - return m.TxHash - } - return nil -} - -func (m *TxRequestDetailsType) GetExtraDataLen() uint32 { - if m != nil && m.ExtraDataLen != nil { - return *m.ExtraDataLen - } - return 0 -} - -func (m *TxRequestDetailsType) GetExtraDataOffset() uint32 { - if m != nil && m.ExtraDataOffset != nil { - return *m.ExtraDataOffset - } - return 0 -} - -// * -// Structure representing serialized data -// @used_in TxRequest -type TxRequestSerializedType struct { - SignatureIndex *uint32 `protobuf:"varint,1,opt,name=signature_index,json=signatureIndex" json:"signature_index,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - SerializedTx []byte `protobuf:"bytes,3,opt,name=serialized_tx,json=serializedTx" json:"serialized_tx,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *TxRequestSerializedType) Reset() { *m = TxRequestSerializedType{} } -func (m *TxRequestSerializedType) String() string { return proto.CompactTextString(m) } -func (*TxRequestSerializedType) ProtoMessage() {} -func (*TxRequestSerializedType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *TxRequestSerializedType) GetSignatureIndex() uint32 { - if m != nil && m.SignatureIndex != nil { - return *m.SignatureIndex - } - return 0 -} - -func (m *TxRequestSerializedType) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *TxRequestSerializedType) GetSerializedTx() []byte { - if m != nil { - return m.SerializedTx - } - return nil -} - -// * -// Structure representing identity data -// @used_in IdentityType -type IdentityType struct { - Proto *string `protobuf:"bytes,1,opt,name=proto" json:"proto,omitempty"` - User *string `protobuf:"bytes,2,opt,name=user" json:"user,omitempty"` - Host *string `protobuf:"bytes,3,opt,name=host" json:"host,omitempty"` - Port *string `protobuf:"bytes,4,opt,name=port" json:"port,omitempty"` - Path *string `protobuf:"bytes,5,opt,name=path" json:"path,omitempty"` - Index *uint32 `protobuf:"varint,6,opt,name=index,def=0" json:"index,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *IdentityType) Reset() { *m = IdentityType{} } -func (m *IdentityType) String() string { return proto.CompactTextString(m) } -func (*IdentityType) ProtoMessage() {} -func (*IdentityType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -const Default_IdentityType_Index uint32 = 0 - -func (m *IdentityType) GetProto() string { - if m != nil && m.Proto != nil { - return *m.Proto - } - return "" -} - -func (m *IdentityType) GetUser() string { - if m != nil && m.User != nil { - return *m.User - } - return "" -} - -func (m *IdentityType) GetHost() string { - if m != nil && m.Host != nil { - return *m.Host - } - return "" -} - -func (m *IdentityType) GetPort() string { - if m != nil && m.Port != nil { - return *m.Port - } - return "" -} - -func (m *IdentityType) GetPath() string { - if m != nil && m.Path != nil { - return *m.Path - } - return "" -} - -func (m *IdentityType) GetIndex() uint32 { - if m != nil && m.Index != nil { - return *m.Index - } - return Default_IdentityType_Index -} - -var E_WireIn = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50002, - Name: "wire_in", - Tag: "varint,50002,opt,name=wire_in,json=wireIn", - Filename: "types.proto", -} - -var E_WireOut = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50003, - Name: "wire_out", - Tag: "varint,50003,opt,name=wire_out,json=wireOut", - Filename: "types.proto", -} - -var E_WireDebugIn = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50004, - Name: "wire_debug_in", - Tag: "varint,50004,opt,name=wire_debug_in,json=wireDebugIn", - Filename: "types.proto", -} - -var E_WireDebugOut = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50005, - Name: "wire_debug_out", - Tag: "varint,50005,opt,name=wire_debug_out,json=wireDebugOut", - Filename: "types.proto", -} - -var E_WireTiny = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50006, - Name: "wire_tiny", - Tag: "varint,50006,opt,name=wire_tiny,json=wireTiny", - Filename: "types.proto", -} - -var E_WireBootloader = &proto.ExtensionDesc{ - ExtendedType: (*google_protobuf.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50007, - Name: "wire_bootloader", - Tag: "varint,50007,opt,name=wire_bootloader,json=wireBootloader", - Filename: "types.proto", -} - -func init() { - proto.RegisterType((*HDNodeType)(nil), "HDNodeType") - proto.RegisterType((*HDNodePathType)(nil), "HDNodePathType") - proto.RegisterType((*CoinType)(nil), "CoinType") - proto.RegisterType((*MultisigRedeemScriptType)(nil), "MultisigRedeemScriptType") - proto.RegisterType((*TxInputType)(nil), "TxInputType") - proto.RegisterType((*TxOutputType)(nil), "TxOutputType") - proto.RegisterType((*TxOutputBinType)(nil), "TxOutputBinType") - proto.RegisterType((*TransactionType)(nil), "TransactionType") - proto.RegisterType((*TxRequestDetailsType)(nil), "TxRequestDetailsType") - proto.RegisterType((*TxRequestSerializedType)(nil), "TxRequestSerializedType") - proto.RegisterType((*IdentityType)(nil), "IdentityType") - proto.RegisterEnum("FailureType", FailureType_name, FailureType_value) - proto.RegisterEnum("OutputScriptType", OutputScriptType_name, OutputScriptType_value) - proto.RegisterEnum("InputScriptType", InputScriptType_name, InputScriptType_value) - proto.RegisterEnum("RequestType", RequestType_name, RequestType_value) - proto.RegisterEnum("ButtonRequestType", ButtonRequestType_name, ButtonRequestType_value) - proto.RegisterEnum("PinMatrixRequestType", PinMatrixRequestType_name, PinMatrixRequestType_value) - proto.RegisterEnum("RecoveryDeviceType", RecoveryDeviceType_name, RecoveryDeviceType_value) - proto.RegisterEnum("WordRequestType", WordRequestType_name, WordRequestType_value) - proto.RegisterExtension(E_WireIn) - proto.RegisterExtension(E_WireOut) - proto.RegisterExtension(E_WireDebugIn) - proto.RegisterExtension(E_WireDebugOut) - proto.RegisterExtension(E_WireTiny) - proto.RegisterExtension(E_WireBootloader) -} - -func init() { proto.RegisterFile("types.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 1899 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xdb, 0x72, 0x1a, 0xc9, - 0x19, 0xf6, 0x00, 0x92, 0xe0, 0x07, 0xc4, 0xa8, 0x7d, 0xd0, 0x78, 0x6d, 0xaf, 0x31, 0x76, 0x62, - 0x45, 0x55, 0x61, 0x77, 0xc9, 0x5a, 0x8e, 0x55, 0xa9, 0x24, 0x3a, 0xa0, 0x15, 0x65, 0x0b, 0x51, - 0xc3, 0x28, 0x56, 0x72, 0x33, 0x35, 0xcc, 0xb4, 0xa0, 0x4b, 0x43, 0x37, 0xe9, 0xe9, 0x91, 0xd1, - 0xde, 0xe4, 0x2a, 0xc9, 0x55, 0x5e, 0x23, 0x6f, 0x91, 0xaa, 0xbc, 0x41, 0xaa, 0x36, 0xa7, 0xcb, - 0xbc, 0x41, 0xae, 0xf2, 0x00, 0xa9, 0x3e, 0x0c, 0x02, 0xc9, 0xde, 0xd2, 0x1d, 0xfd, 0x7d, 0xff, - 0xf9, 0xd0, 0x3d, 0x40, 0x59, 0x5c, 0x4e, 0x70, 0xd2, 0x9c, 0x70, 0x26, 0xd8, 0x67, 0xf5, 0x21, - 0x63, 0xc3, 0x18, 0x7f, 0xa1, 0x4e, 0x83, 0xf4, 0xec, 0x8b, 0x08, 0x27, 0x21, 0x27, 0x13, 0xc1, - 0xb8, 0x96, 0x68, 0xfc, 0xd5, 0x02, 0x38, 0xdc, 0xef, 0xb2, 0x08, 0x7b, 0x97, 0x13, 0x8c, 0xee, - 0xc1, 0x52, 0x84, 0x27, 0x62, 0xe4, 0x58, 0xf5, 0xdc, 0x46, 0xd5, 0xd5, 0x07, 0x54, 0x87, 0xf2, - 0x19, 0xa1, 0x43, 0xcc, 0x27, 0x9c, 0x50, 0xe1, 0xe4, 0x14, 0x37, 0x0f, 0xa1, 0x47, 0x50, 0x0a, - 0x47, 0x24, 0x8e, 0x7c, 0x9a, 0x8e, 0x9d, 0xbc, 0xe2, 0x8b, 0x0a, 0xe8, 0xa6, 0x63, 0xf4, 0x04, - 0x20, 0x1c, 0x05, 0x84, 0xfa, 0x21, 0x8b, 0xb0, 0x53, 0xa8, 0xe7, 0x36, 0x2a, 0x6e, 0x49, 0x21, - 0x7b, 0x2c, 0xc2, 0xe8, 0x29, 0x94, 0x27, 0x9c, 0x5c, 0x04, 0x02, 0xfb, 0xe7, 0xf8, 0xd2, 0x59, - 0xaa, 0x5b, 0x1b, 0x15, 0x17, 0x0c, 0xf4, 0x16, 0x5f, 0x4a, 0xfd, 0x49, 0x3a, 0x88, 0x49, 0xa8, - 0xf8, 0x65, 0xc5, 0x97, 0x34, 0xf2, 0x16, 0x5f, 0x36, 0xba, 0xb0, 0xaa, 0x33, 0xe8, 0x05, 0x62, - 0xa4, 0xb2, 0x78, 0x0a, 0x05, 0x2a, 0x5d, 0xc9, 0x24, 0xca, 0xad, 0x72, 0xf3, 0x2a, 0x41, 0x57, - 0x11, 0x32, 0xdc, 0x20, 0x8a, 0x38, 0x4e, 0x12, 0x9f, 0x3a, 0xb9, 0x7a, 0x5e, 0x86, 0x6b, 0x80, - 0x6e, 0xe3, 0x7f, 0x39, 0x28, 0xee, 0x31, 0x42, 0x95, 0x29, 0x99, 0x18, 0x23, 0xd4, 0xa7, 0xc1, - 0x58, 0xda, 0xb3, 0x36, 0x4a, 0x6e, 0x51, 0x02, 0xdd, 0x60, 0x8c, 0xd1, 0x73, 0xa8, 0x2a, 0x32, - 0x19, 0x31, 0x2e, 0xc2, 0x54, 0x56, 0x46, 0x0a, 0x54, 0x24, 0xd8, 0x37, 0x18, 0x7a, 0x01, 0x95, - 0xcc, 0x97, 0x6c, 0x8d, 0x93, 0xaf, 0x5b, 0x1b, 0xd5, 0x6d, 0xeb, 0x4b, 0xb7, 0x6c, 0xe0, 0xcc, - 0xcf, 0x38, 0x98, 0x9e, 0x61, 0xec, 0x9f, 0x0f, 0x9c, 0x42, 0xdd, 0xda, 0x28, 0xb8, 0x45, 0x0d, - 0xbc, 0x1d, 0xa0, 0x1f, 0xc3, 0xda, 0xbc, 0x09, 0x7f, 0xd2, 0x4a, 0x46, 0xaa, 0x4e, 0xd5, 0x6d, - 0xeb, 0x95, 0x5b, 0x9b, 0xb3, 0xd3, 0x6b, 0x25, 0x23, 0xd4, 0x82, 0xfb, 0x09, 0x19, 0x52, 0x1c, - 0xf9, 0x63, 0x9c, 0x24, 0xc1, 0x10, 0xfb, 0x23, 0x1c, 0x44, 0x98, 0x3b, 0x45, 0x15, 0xde, 0x5d, - 0x4d, 0x1e, 0x69, 0xee, 0x50, 0x51, 0xe8, 0x25, 0xc0, 0x74, 0x92, 0x0e, 0xfc, 0x71, 0x30, 0x24, - 0xa1, 0x53, 0x52, 0xb6, 0x8b, 0xaf, 0xb7, 0xbe, 0xdc, 0x7a, 0xfd, 0x93, 0x57, 0x3f, 0x75, 0x4b, - 0x92, 0x3b, 0x92, 0x94, 0x16, 0xe4, 0x17, 0x46, 0x10, 0xae, 0x04, 0xb7, 0x5a, 0xaf, 0xb7, 0xa4, - 0x20, 0xbf, 0xd0, 0x82, 0x0f, 0x60, 0x39, 0xc1, 0xc3, 0x0f, 0x44, 0x38, 0xe5, 0xba, 0xb5, 0x51, - 0x74, 0xcd, 0x49, 0xe2, 0x67, 0x8c, 0x9f, 0x93, 0xc8, 0xa9, 0x48, 0x65, 0xd7, 0x9c, 0x1a, 0x09, - 0x38, 0x47, 0x69, 0x2c, 0x48, 0x42, 0x86, 0x2e, 0x8e, 0x30, 0x1e, 0xf7, 0xd5, 0xa4, 0xaa, 0xea, - 0xfc, 0x08, 0x56, 0x26, 0xe9, 0xe0, 0x1c, 0x5f, 0x26, 0x8e, 0x55, 0xcf, 0x6f, 0x94, 0x5b, 0xb5, - 0xe6, 0x62, 0xcb, 0xdd, 0x8c, 0x47, 0x9f, 0x03, 0xc8, 0xfc, 0x02, 0x91, 0x72, 0x9c, 0xa8, 0xde, - 0x56, 0xdc, 0x39, 0x04, 0x55, 0xc0, 0x1a, 0xeb, 0x1e, 0xb8, 0xd6, 0xb8, 0xf1, 0x97, 0x1c, 0x94, - 0xbd, 0x69, 0x87, 0x4e, 0x52, 0x91, 0xb5, 0xe1, 0x6a, 0x30, 0xac, 0xc5, 0xc1, 0x90, 0xe4, 0x84, - 0xe3, 0x0b, 0x7f, 0x14, 0x24, 0x23, 0xb5, 0x04, 0x15, 0xb7, 0x28, 0x81, 0xc3, 0x20, 0x19, 0xa9, - 0x21, 0x95, 0x24, 0xa1, 0x11, 0x9e, 0x9a, 0x15, 0x50, 0xe2, 0x1d, 0x09, 0x48, 0x5a, 0x6f, 0x9e, - 0x9f, 0x90, 0xa1, 0x6a, 0x70, 0xc5, 0x2d, 0x69, 0xa4, 0x4f, 0x86, 0xe8, 0x87, 0x50, 0x4c, 0xf0, - 0x6f, 0x53, 0x4c, 0x43, 0x6c, 0x1a, 0x0b, 0x5f, 0xb7, 0xde, 0x7c, 0xfd, 0x66, 0xeb, 0x75, 0xeb, - 0xcd, 0x2b, 0x77, 0xc6, 0xa1, 0x5f, 0x40, 0xd9, 0x98, 0x51, 0xb3, 0x24, 0x77, 0x61, 0xb5, 0x65, - 0x37, 0x55, 0x02, 0x57, 0xf5, 0xda, 0xae, 0xf4, 0x7b, 0xed, 0xee, 0xfe, 0xce, 0xfe, 0xbe, 0xdb, - 0xee, 0xf7, 0x5d, 0xe3, 0x59, 0x25, 0xf8, 0x0a, 0x8a, 0x63, 0x53, 0x65, 0x67, 0xa5, 0x6e, 0x6d, - 0x94, 0x5b, 0x0f, 0x9b, 0x9f, 0x2a, 0xbb, 0x3b, 0x13, 0x95, 0x4d, 0x0b, 0xc6, 0x2c, 0xa5, 0x42, - 0xcd, 0x50, 0xc1, 0x35, 0xa7, 0xc6, 0x7f, 0x2d, 0xa8, 0x78, 0xd3, 0xe3, 0x54, 0x64, 0x05, 0x74, - 0x60, 0xc5, 0xd4, 0xcb, 0x6c, 0x4b, 0x76, 0xfc, 0xde, 0x9d, 0x9b, 0xb3, 0x2f, 0x2b, 0x37, 0xb3, - 0x8f, 0x5a, 0x8b, 0xf9, 0xca, 0xbb, 0x63, 0xb5, 0xb5, 0xd6, 0xd4, 0x0e, 0xe7, 0x22, 0xfd, 0x54, - 0x8a, 0x4b, 0xb7, 0x4f, 0xf1, 0x05, 0xac, 0xb2, 0x89, 0xcf, 0xb1, 0x48, 0x39, 0xf5, 0xa3, 0x40, - 0x04, 0xe6, 0xa6, 0xa9, 0xb0, 0x89, 0xab, 0xc0, 0xfd, 0x40, 0x04, 0x8d, 0x2e, 0xd4, 0xb2, 0x7c, - 0x77, 0xcd, 0x15, 0x71, 0x15, 0xbb, 0xb5, 0x10, 0xfb, 0x73, 0xa8, 0x9a, 0xd8, 0xf5, 0x6c, 0x9a, - 0x91, 0xa9, 0x68, 0xb0, 0xa7, 0xb0, 0xc6, 0xdf, 0x72, 0x50, 0xf3, 0x78, 0x40, 0x93, 0x20, 0x14, - 0x84, 0xd1, 0xac, 0x86, 0x17, 0x98, 0x27, 0x84, 0x51, 0x55, 0xc3, 0xaa, 0x9b, 0x1d, 0xd1, 0x0b, - 0x58, 0x26, 0xb2, 0xd5, 0x7a, 0xb0, 0xcb, 0xad, 0x4a, 0x73, 0x6e, 0x78, 0x5d, 0xc3, 0xa1, 0xaf, - 0xa0, 0x3c, 0x20, 0xd4, 0x67, 0x2a, 0xca, 0xc4, 0xc9, 0x2b, 0x51, 0xbb, 0x79, 0x2d, 0x6e, 0x17, - 0x06, 0x84, 0x6a, 0x24, 0x41, 0x2f, 0x61, 0x25, 0x13, 0x5f, 0x52, 0xe2, 0xd5, 0xe6, 0x7c, 0x5b, - 0xdd, 0x8c, 0x95, 0x5d, 0x8c, 0x59, 0x78, 0xee, 0x0b, 0x32, 0xc6, 0x6a, 0x8c, 0xab, 0x6e, 0x51, - 0x02, 0x1e, 0x19, 0x63, 0x39, 0xe4, 0x3a, 0x04, 0x3f, 0xa4, 0x42, 0x95, 0xaf, 0xea, 0x96, 0x34, - 0xb2, 0x47, 0x85, 0xbc, 0xe8, 0x8d, 0x19, 0xc5, 0xaf, 0x28, 0x1e, 0x0c, 0x24, 0x05, 0x9e, 0x00, - 0xe0, 0xa9, 0xe0, 0x81, 0x2e, 0x7f, 0x51, 0x2f, 0x89, 0x42, 0x64, 0xed, 0x65, 0x87, 0xae, 0x68, - 0x3f, 0xc6, 0x54, 0xdf, 0x53, 0x6e, 0x65, 0x26, 0xf2, 0x0e, 0xd3, 0xc6, 0x9f, 0x2d, 0xb8, 0xe7, - 0x4d, 0x5d, 0xb9, 0x31, 0x89, 0xd8, 0xc7, 0x22, 0x20, 0xb1, 0xbe, 0x62, 0x9f, 0x43, 0x95, 0x6b, - 0xd4, 0x2c, 0xa9, 0x2e, 0x6e, 0xc5, 0x80, 0x7a, 0x4f, 0xd7, 0x61, 0x45, 0x4c, 0xb3, 0x0d, 0x97, - 0xfe, 0x97, 0xc5, 0x54, 0xed, 0xf7, 0x4d, 0xe7, 0xf9, 0x9b, 0xce, 0xd1, 0x26, 0xac, 0xcd, 0x49, - 0xb1, 0xb3, 0xb3, 0x04, 0x0b, 0x53, 0xa6, 0xda, 0x4c, 0xf0, 0x58, 0xc1, 0x8d, 0xdf, 0x5b, 0xb0, - 0x3e, 0x0b, 0xb4, 0x8f, 0x39, 0x09, 0x62, 0xf2, 0x2d, 0x8e, 0x54, 0xac, 0x2f, 0xa1, 0x36, 0xbb, - 0xb3, 0x16, 0xa2, 0x5d, 0x9d, 0xc1, 0x3a, 0xde, 0xc7, 0x50, 0x9a, 0x21, 0x26, 0xe2, 0x2b, 0x40, - 0x8d, 0xe0, 0xcc, 0xb0, 0x2f, 0xa6, 0x2a, 0x66, 0x39, 0x82, 0x57, 0xde, 0xa6, 0x8d, 0x3f, 0x59, - 0x50, 0xe9, 0x44, 0x98, 0x0a, 0x22, 0x2e, 0xb3, 0x8f, 0x00, 0xf5, 0x71, 0x60, 0x36, 0x58, 0x1f, - 0x10, 0x82, 0x42, 0x9a, 0x60, 0x6e, 0xde, 0x38, 0xf5, 0x5b, 0x62, 0x23, 0x96, 0x08, 0x65, 0xb6, - 0xe4, 0xaa, 0xdf, 0x12, 0x9b, 0x30, 0xae, 0xb3, 0x2e, 0xb9, 0xea, 0xb7, 0xc2, 0x02, 0xa1, 0xdf, - 0x2c, 0x89, 0x05, 0x62, 0x84, 0xd6, 0x61, 0x49, 0x27, 0xb6, 0x9c, 0x3d, 0x88, 0xfa, 0xbc, 0xf9, - 0x5d, 0x0e, 0xca, 0x07, 0x01, 0x89, 0x53, 0xae, 0xbf, 0x49, 0x9e, 0xc0, 0x43, 0x73, 0xf4, 0x4f, - 0x28, 0x9e, 0x4e, 0x70, 0x28, 0x66, 0xaf, 0x97, 0x6d, 0xa1, 0xcf, 0xe0, 0x41, 0x46, 0xef, 0xa6, - 0x42, 0x30, 0xda, 0x36, 0x22, 0x76, 0x0e, 0xdd, 0x87, 0xb5, 0x8c, 0x93, 0x85, 0x6f, 0x73, 0xce, - 0xb8, 0x9d, 0x47, 0x8f, 0x60, 0x3d, 0x83, 0x77, 0xd4, 0xda, 0xed, 0x05, 0x34, 0xc4, 0x71, 0x8c, - 0x23, 0xbb, 0x80, 0xd6, 0xe1, 0x6e, 0x46, 0xf6, 0xc8, 0x95, 0xb1, 0x25, 0xe4, 0xc0, 0xbd, 0x39, - 0xe2, 0x4a, 0x65, 0x19, 0x3d, 0x00, 0x34, 0xc7, 0x74, 0xe8, 0x45, 0x10, 0x93, 0xc8, 0x5e, 0x41, - 0x8f, 0xc1, 0xc9, 0x70, 0x03, 0xf6, 0xb3, 0xd6, 0xd8, 0xc5, 0x05, 0x7b, 0x9c, 0x85, 0x38, 0x49, - 0x74, 0x7c, 0xa5, 0xf9, 0x94, 0xba, 0x4c, 0xb4, 0x29, 0x4b, 0x87, 0xa3, 0x83, 0x94, 0x46, 0x89, - 0x0d, 0xd7, 0xb8, 0x0e, 0x25, 0xc2, 0x74, 0xd2, 0x2e, 0xa3, 0x87, 0x70, 0x3f, 0xe3, 0x0e, 0x08, - 0x1f, 0x7f, 0x08, 0x38, 0xd6, 0x26, 0xc3, 0xcd, 0x3f, 0x5a, 0x60, 0x5f, 0xbf, 0x35, 0x91, 0x0d, - 0x95, 0xde, 0xce, 0xaf, 0xbd, 0x63, 0xf3, 0x50, 0xd8, 0x77, 0xd0, 0x5d, 0xa8, 0x29, 0xa4, 0xbf, - 0xe7, 0x76, 0x7a, 0xde, 0xe1, 0x4e, 0xff, 0xd0, 0xb6, 0xd0, 0x1a, 0x54, 0x15, 0x78, 0x74, 0xf2, - 0xce, 0xeb, 0xf4, 0x3b, 0xdf, 0xd8, 0xb9, 0x19, 0x74, 0xdc, 0x73, 0xdb, 0xde, 0x89, 0xdb, 0xb5, - 0xf3, 0x33, 0x63, 0xef, 0x3b, 0x5e, 0x57, 0x1a, 0x2b, 0xa0, 0x7b, 0x60, 0x2b, 0xa4, 0xd7, 0xea, - 0x1f, 0x66, 0xe8, 0xd2, 0x66, 0x0c, 0xb5, 0x6b, 0xcf, 0x95, 0x54, 0x9d, 0x7f, 0xb0, 0xec, 0x3b, - 0xd2, 0xbe, 0x42, 0x66, 0x2e, 0x2d, 0x54, 0x81, 0x62, 0xfb, 0xd4, 0x6b, 0xbb, 0xdd, 0x9d, 0x77, - 0x76, 0x6e, 0xa6, 0x92, 0xd9, 0xcd, 0x4b, 0x6f, 0x0a, 0x99, 0xf7, 0x56, 0xd8, 0x3c, 0x81, 0xb2, - 0xd9, 0x30, 0xe5, 0xa9, 0x0c, 0x2b, 0xde, 0x69, 0xa7, 0xdb, 0x3b, 0xf1, 0xec, 0x3b, 0xd2, 0xa2, - 0x77, 0x7a, 0x7c, 0xe2, 0xc9, 0x93, 0x85, 0x00, 0x96, 0xbd, 0xd3, 0xa3, 0xb6, 0xb7, 0x63, 0xe7, - 0xd0, 0x2a, 0x80, 0x77, 0x7a, 0xd0, 0xe9, 0x76, 0xfa, 0x87, 0xed, 0x7d, 0x3b, 0x8f, 0x6a, 0x50, - 0xf6, 0x4e, 0xdb, 0xa7, 0x9e, 0xbb, 0xb3, 0xbf, 0xe3, 0xed, 0xd8, 0x85, 0xcd, 0xff, 0xe4, 0x60, - 0x4d, 0x4f, 0xdb, 0xbc, 0xf5, 0x75, 0xb8, 0xbb, 0x00, 0xfa, 0xc7, 0x62, 0x84, 0xb9, 0x6d, 0xa1, - 0x06, 0x7c, 0xbe, 0x48, 0x1c, 0x60, 0x7c, 0x7c, 0x81, 0xb9, 0x37, 0xe2, 0x38, 0x19, 0xb1, 0x58, - 0xce, 0xea, 0x53, 0x78, 0xb4, 0x28, 0xb3, 0xc7, 0xe8, 0x19, 0xe1, 0x63, 0xdd, 0x35, 0x3b, 0x2f, - 0xf7, 0x60, 0x51, 0xc0, 0xc5, 0x09, 0x16, 0xfb, 0xf8, 0x82, 0x84, 0xd8, 0x2e, 0xdc, 0xa4, 0x8d, - 0xfe, 0x7b, 0xc6, 0xe5, 0xf4, 0x3e, 0x06, 0x67, 0x91, 0x7e, 0x4f, 0x26, 0xd8, 0x28, 0x2f, 0xdf, - 0x54, 0xee, 0x71, 0x26, 0x70, 0x28, 0xf6, 0x82, 0x38, 0xb6, 0x57, 0xe4, 0xa8, 0x2e, 0xd2, 0x72, - 0x8e, 0xbd, 0xa9, 0x5d, 0xbc, 0x19, 0x75, 0x36, 0x78, 0x7b, 0x23, 0x1c, 0x9e, 0xdb, 0x25, 0x39, - 0x93, 0x8b, 0x02, 0x3b, 0xfa, 0xcd, 0xb7, 0x41, 0xae, 0xe1, 0x35, 0xa7, 0xd9, 0x37, 0xbd, 0x5d, - 0xde, 0xfc, 0x1d, 0xdc, 0xeb, 0x11, 0x7a, 0x14, 0x08, 0x4e, 0xa6, 0xf3, 0x35, 0xae, 0xc3, 0xe3, - 0x8f, 0xe1, 0xfe, 0x5e, 0xca, 0x39, 0xa6, 0xc2, 0xb6, 0xd0, 0x33, 0x78, 0xf2, 0x51, 0x89, 0x2e, - 0xfe, 0x70, 0x40, 0x78, 0x22, 0xec, 0x9c, 0xec, 0xc7, 0xa7, 0x44, 0xfa, 0x38, 0x64, 0x34, 0xb2, - 0xf3, 0x9b, 0xbf, 0x01, 0xe4, 0xe2, 0x90, 0x5d, 0x60, 0x7e, 0xa9, 0xcb, 0xa4, 0xdc, 0xff, 0x00, - 0x9e, 0xdd, 0x44, 0xfd, 0x7e, 0xc8, 0x83, 0xf1, 0x20, 0xc6, 0x91, 0x2c, 0x76, 0x62, 0xdf, 0x91, - 0xf5, 0xfc, 0x88, 0x98, 0x76, 0x68, 0x5b, 0x9b, 0x67, 0x50, 0x93, 0x92, 0xf3, 0x79, 0x3d, 0x84, - 0xfb, 0xd7, 0x20, 0xbf, 0x17, 0x07, 0x84, 0xda, 0x77, 0x64, 0x9d, 0xae, 0x53, 0xda, 0xd2, 0x1b, - 0xdb, 0xfa, 0x34, 0xb9, 0x65, 0xe7, 0xb6, 0x7f, 0x06, 0x2b, 0x1f, 0x88, 0x7a, 0x41, 0xd0, 0xb3, - 0xa6, 0xfe, 0x2f, 0xd8, 0xcc, 0xfe, 0x0b, 0x36, 0xdb, 0x34, 0x1d, 0xff, 0x2a, 0x88, 0x53, 0x7c, - 0x3c, 0x91, 0x77, 0x60, 0xe2, 0x7c, 0xf7, 0x87, 0xbc, 0xfe, 0x52, 0x97, 0x3a, 0x1d, 0xba, 0xfd, - 0x73, 0x28, 0x2a, 0x6d, 0x96, 0x8a, 0xdb, 0xa8, 0xff, 0xdd, 0xa8, 0x2b, 0x97, 0xc7, 0xa9, 0xd8, - 0xfe, 0x06, 0xaa, 0x4a, 0x3f, 0xc2, 0x83, 0x74, 0x78, 0xcb, 0x18, 0xfe, 0x61, 0x8c, 0x94, 0xa5, - 0xe6, 0xbe, 0x54, 0xec, 0xd0, 0xed, 0x0e, 0xac, 0xce, 0x19, 0xba, 0x65, 0x38, 0xff, 0x34, 0x96, - 0x2a, 0x33, 0x4b, 0x32, 0xa6, 0x5f, 0x42, 0x49, 0x99, 0x12, 0x84, 0x5e, 0xde, 0xc6, 0xca, 0xbf, - 0x8c, 0x15, 0x55, 0x09, 0x8f, 0xd0, 0xcb, 0xed, 0x77, 0x50, 0x53, 0x16, 0x06, 0x8c, 0x89, 0x98, - 0xa9, 0x3f, 0x4f, 0xb7, 0xb0, 0xf3, 0x6f, 0x63, 0x47, 0x25, 0xb2, 0x3b, 0x53, 0xdd, 0xfd, 0x0a, - 0x9e, 0x87, 0x6c, 0xdc, 0x4c, 0x02, 0xc1, 0x92, 0x11, 0x89, 0x83, 0x41, 0xd2, 0x14, 0x1c, 0x7f, - 0xcb, 0x78, 0x33, 0x26, 0x83, 0x99, 0xbd, 0x5d, 0xf0, 0x14, 0x28, 0xdb, 0xfb, 0xff, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x70, 0x88, 0xcd, 0x71, 0xe2, 0x0f, 0x00, 0x00, -} diff --git a/accounts/usbwallet/trezor/types.proto b/accounts/usbwallet/trezor/types.proto deleted file mode 100644 index acbe79e3ff..0000000000 --- a/accounts/usbwallet/trezor/types.proto +++ /dev/null @@ -1,278 +0,0 @@ -// This file originates from the SatoshiLabs Trezor `common` repository at: -// https://github.com/trezor/trezor-common/blob/master/protob/types.proto -// dated 28.07.2017, commit dd8ec3231fb5f7992360aff9bdfe30bb58130f4b. - -syntax = "proto2"; - -/** - * Types for TREZOR communication - * - * @author Marek Palatinus - * @version 1.2 - */ - -// Sugar for easier handling in Java -option java_package = "com.satoshilabs.trezor.lib.protobuf"; -option java_outer_classname = "TrezorType"; - -import "google/protobuf/descriptor.proto"; - -/** - * Options for specifying message direction and type of wire (normal/debug) - */ -extend google.protobuf.EnumValueOptions { - optional bool wire_in = 50002; // message can be transmitted via wire from PC to TREZOR - optional bool wire_out = 50003; // message can be transmitted via wire from TREZOR to PC - optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to TREZOR - optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from TREZOR to PC - optional bool wire_tiny = 50006; // message is handled by TREZOR when the USB stack is in tiny mode - optional bool wire_bootloader = 50007; // message is only handled by TREZOR Bootloader -} - -/** - * Type of failures returned by Failure message - * @used_in Failure - */ -enum FailureType { - Failure_UnexpectedMessage = 1; - Failure_ButtonExpected = 2; - Failure_DataError = 3; - Failure_ActionCancelled = 4; - Failure_PinExpected = 5; - Failure_PinCancelled = 6; - Failure_PinInvalid = 7; - Failure_InvalidSignature = 8; - Failure_ProcessError = 9; - Failure_NotEnoughFunds = 10; - Failure_NotInitialized = 11; - Failure_FirmwareError = 99; -} - -/** - * Type of script which will be used for transaction output - * @used_in TxOutputType - */ -enum OutputScriptType { - PAYTOADDRESS = 0; // used for all addresses (bitcoin, p2sh, witness) - PAYTOSCRIPTHASH = 1; // p2sh address (deprecated; use PAYTOADDRESS) - PAYTOMULTISIG = 2; // only for change output - PAYTOOPRETURN = 3; // op_return - PAYTOWITNESS = 4; // only for change output - PAYTOP2SHWITNESS = 5; // only for change output -} - -/** - * Type of script which will be used for transaction output - * @used_in TxInputType - */ -enum InputScriptType { - SPENDADDRESS = 0; // standard p2pkh address - SPENDMULTISIG = 1; // p2sh multisig address - EXTERNAL = 2; // reserved for external inputs (coinjoin) - SPENDWITNESS = 3; // native segwit - SPENDP2SHWITNESS = 4; // segwit over p2sh (backward compatible) -} - -/** - * Type of information required by transaction signing process - * @used_in TxRequest - */ -enum RequestType { - TXINPUT = 0; - TXOUTPUT = 1; - TXMETA = 2; - TXFINISHED = 3; - TXEXTRADATA = 4; -} - -/** - * Type of button request - * @used_in ButtonRequest - */ -enum ButtonRequestType { - ButtonRequest_Other = 1; - ButtonRequest_FeeOverThreshold = 2; - ButtonRequest_ConfirmOutput = 3; - ButtonRequest_ResetDevice = 4; - ButtonRequest_ConfirmWord = 5; - ButtonRequest_WipeDevice = 6; - ButtonRequest_ProtectCall = 7; - ButtonRequest_SignTx = 8; - ButtonRequest_FirmwareCheck = 9; - ButtonRequest_Address = 10; - ButtonRequest_PublicKey = 11; -} - -/** - * Type of PIN request - * @used_in PinMatrixRequest - */ -enum PinMatrixRequestType { - PinMatrixRequestType_Current = 1; - PinMatrixRequestType_NewFirst = 2; - PinMatrixRequestType_NewSecond = 3; -} - -/** - * Type of recovery procedure. These should be used as bitmask, e.g., - * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix` - * listing every method supported by the host computer. - * - * Note that ScrambledWords must be supported by every implementation - * for backward compatibility; there is no way to not support it. - * - * @used_in RecoveryDevice - */ -enum RecoveryDeviceType { - // use powers of two when extending this field - RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order - RecoveryDeviceType_Matrix = 1; // matrix recovery type -} - -/** - * Type of Recovery Word request - * @used_in WordRequest - */ -enum WordRequestType { - WordRequestType_Plain = 0; - WordRequestType_Matrix9 = 1; - WordRequestType_Matrix6 = 2; -} - -/** - * Structure representing BIP32 (hierarchical deterministic) node - * Used for imports of private key into the device and exporting public key out of device - * @used_in PublicKey - * @used_in LoadDevice - * @used_in DebugLinkState - * @used_in Storage - */ -message HDNodeType { - required uint32 depth = 1; - required uint32 fingerprint = 2; - required uint32 child_num = 3; - required bytes chain_code = 4; - optional bytes private_key = 5; - optional bytes public_key = 6; -} - -message HDNodePathType { - required HDNodeType node = 1; // BIP-32 node in deserialized form - repeated uint32 address_n = 2; // BIP-32 path to derive the key from node -} - -/** - * Structure representing Coin - * @used_in Features - */ -message CoinType { - optional string coin_name = 1; - optional string coin_shortcut = 2; - optional uint32 address_type = 3 [default=0]; - optional uint64 maxfee_kb = 4; - optional uint32 address_type_p2sh = 5 [default=5]; - optional string signed_message_header = 8; - optional uint32 xpub_magic = 9 [default=76067358]; // default=0x0488b21e - optional uint32 xprv_magic = 10 [default=76066276]; // default=0x0488ade4 - optional bool segwit = 11; - optional uint32 forkid = 12; -} - -/** - * Type of redeem script used in input - * @used_in TxInputType - */ -message MultisigRedeemScriptType { - repeated HDNodePathType pubkeys = 1; // pubkeys from multisig address (sorted lexicographically) - repeated bytes signatures = 2; // existing signatures for partially signed input - optional uint32 m = 3; // "m" from n, how many valid signatures is necessary for spending -} - -/** - * Structure representing transaction input - * @used_in SimpleSignTx - * @used_in TransactionType - */ -message TxInputType { - repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node - required bytes prev_hash = 2; // hash of previous transaction output to spend by this input - required uint32 prev_index = 3; // index of previous output to spend - optional bytes script_sig = 4; // script signature, unset for tx to sign - optional uint32 sequence = 5 [default=4294967295]; // sequence (default=0xffffffff) - optional InputScriptType script_type = 6 [default=SPENDADDRESS]; // defines template of input script - optional MultisigRedeemScriptType multisig = 7; // Filled if input is going to spend multisig tx - optional uint64 amount = 8; // amount of previous transaction output (for segwit only) -} - -/** - * Structure representing transaction output - * @used_in SimpleSignTx - * @used_in TransactionType - */ -message TxOutputType { - optional string address = 1; // target coin address in Base58 encoding - repeated uint32 address_n = 2; // BIP-32 path to derive the key from master node; has higher priority than "address" - required uint64 amount = 3; // amount to spend in satoshis - required OutputScriptType script_type = 4; // output script type - optional MultisigRedeemScriptType multisig = 5; // defines multisig address; script_type must be PAYTOMULTISIG - optional bytes op_return_data = 6; // defines op_return data; script_type must be PAYTOOPRETURN, amount must be 0 -} - -/** - * Structure representing compiled transaction output - * @used_in TransactionType - */ -message TxOutputBinType { - required uint64 amount = 1; - required bytes script_pubkey = 2; -} - -/** - * Structure representing transaction - * @used_in SimpleSignTx - */ -message TransactionType { - optional uint32 version = 1; - repeated TxInputType inputs = 2; - repeated TxOutputBinType bin_outputs = 3; - repeated TxOutputType outputs = 5; - optional uint32 lock_time = 4; - optional uint32 inputs_cnt = 6; - optional uint32 outputs_cnt = 7; - optional bytes extra_data = 8; - optional uint32 extra_data_len = 9; -} - -/** - * Structure representing request details - * @used_in TxRequest - */ -message TxRequestDetailsType { - optional uint32 request_index = 1; // device expects TxAck message from the computer - optional bytes tx_hash = 2; // tx_hash of requested transaction - optional uint32 extra_data_len = 3; // length of requested extra data - optional uint32 extra_data_offset = 4; // offset of requested extra data -} - -/** - * Structure representing serialized data - * @used_in TxRequest - */ -message TxRequestSerializedType { - optional uint32 signature_index = 1; // 'signature' field contains signed input of this index - optional bytes signature = 2; // signature of the signature_index input - optional bytes serialized_tx = 3; // part of serialized and signed transaction -} - -/** - * Structure representing identity data - * @used_in IdentityType - */ -message IdentityType { - optional string proto = 1; // proto part of URI - optional string user = 2; // user part of URI - optional string host = 3; // host part of URI - optional string port = 4; // port part of URI - optional string path = 5; // path part of URI - optional uint32 index = 6 [default=0]; // identity index -} diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 64d07e1aeb..289b086d09 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -31,7 +31,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/karalabe/hid" + "github.com/karalabe/usb" ) // Maximum time between wallet health checks to detect USB unplugs. @@ -77,8 +77,8 @@ type wallet struct { driver driver // Hardware implementation of the low level device operations url *accounts.URL // Textual URL uniquely identifying this wallet - info hid.DeviceInfo // Known USB device infos about the wallet - device *hid.Device // USB device advertising itself as a hardware wallet + info usb.DeviceInfo // Known USB device infos about the wallet + device usb.Device // USB device advertising itself as a hardware wallet accounts []accounts.Account // List of derive accounts pinned on the hardware wallet paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations diff --git a/go.mod b/go.mod index 4fbdf262a5..537a08dcf8 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/huin/goupnp v1.3.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/julienschmidt/httprouter v1.3.0 - github.com/karalabe/hid v1.0.0 github.com/mattn/go-colorable v0.1.13 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 @@ -54,6 +53,7 @@ require ( github.com/go-yaml/yaml v2.1.0+incompatible github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c + github.com/karalabe/usb v0.0.2 github.com/kevinburke/go-bindata v3.23.0+incompatible github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-isatty v0.0.17 diff --git a/go.sum b/go.sum index 738d5a7e35..414e385db7 100644 --- a/go.sum +++ b/go.sum @@ -111,8 +111,8 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karalabe/hid v1.0.0 h1:+/CIMNXhSU/zIJgnIvBD2nKHxS/bnRHhhs9xBryLpPo= -github.com/karalabe/hid v1.0.0/go.mod h1:Vr51f8rUOLYrfrWDFlV12GGQgM5AT8sVh+2fY4MPeu8= +github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kevinburke/go-bindata v3.23.0+incompatible h1:rqNOXZlqrYhMVVAsQx8wuc+LaA73YcfbQ407wAykyS8= github.com/kevinburke/go-bindata v3.23.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= diff --git a/node/config.go b/node/config.go index 086053aad8..b4af885535 100644 --- a/node/config.go +++ b/node/config.go @@ -443,9 +443,15 @@ func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { } else { backends = append(backends, ledgerhub) } - // Start a USB hub for Trezor hardware wallets - if trezorhub, err := usbwallet.NewTrezorHub(); err != nil { - log.Warn(fmt.Sprintf("Failed to start Trezor hub, disabling: %v", err)) + // Start a USB hub for Trezor hardware wallets (HID version) + if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { + log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) + } else { + backends = append(backends, trezorhub) + } + // Start a USB hub for Trezor hardware wallets (WebUSB version) + if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { + log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) } else { backends = append(backends, trezorhub) } From e6df5f8798247533075a625445701113b5fd63d5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 070/280] account/usbwallet: abort usb enumeration after failures (#19671) --- accounts/usbwallet/hub.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index f2656bdf47..4041359ad3 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -20,6 +20,7 @@ import ( "errors" "runtime" "sync" + "sync/atomic" "time" "github.com/XinFinOrg/XDPoSChain/accounts" @@ -64,6 +65,7 @@ type Hub struct { // TODO(karalabe): remove if hotplug lands on Windows commsPend int // Number of operations blocking enumeration commsLock sync.Mutex // Lock protecting the pending counter and enumeration + enumFails uint32 // Number of times enumeration has failed } // NewLedgerHub creates a new hardware wallet manager for Ledger devices. @@ -138,6 +140,10 @@ func (hub *Hub) refreshWallets() { if elapsed < refreshThrottling { return } + // If USB enumeration is continually failing, don't keep trying indefinitely + if atomic.LoadUint32(&hub.enumFails) > 2 { + return + } // Retrieve the current list of USB wallet devices var devices []usb.DeviceInfo @@ -156,13 +162,17 @@ func (hub *Hub) refreshWallets() { } infos, err := usb.Enumerate(hub.vendorID, 0) if err != nil { + failcount := atomic.AddUint32(&hub.enumFails, 1) if runtime.GOOS == "linux" { // See rationale before the enumeration why this is needed and only on Linux. hub.commsLock.Unlock() } - log.Error("error enumerating USB enumeration: ", "code", err) + log.Error("Failed to enumerate USB devices", "hub", hub.scheme, + "vendor", hub.vendorID, "failcount", failcount, "err", err) return } + atomic.StoreUint32(&hub.enumFails, 0) + for _, info := range infos { for _, id := range hub.productIDs { // Windows and Macos use UsageID matching, Linux uses Interface matching From 313018496f6b5cb442749d10bc071dc15f6bc550 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 071/280] accounts: added transactorFromKeyStore (#19685) --- accounts/abi/bind/auth.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index a53aeef366..b661a29f4d 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -53,6 +53,25 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { return NewKeyedTransactor(key.PrivateKey), nil } +// NewTransactor is a utility method to easily create a transaction signer from +// an decrypted key from a keystore +func NewTransactorFromKeyStore(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { + signer := types.HomesteadSigner{} + return &TransactOpts{ + From: account.Address, + Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { + if address != account.Address { + return nil, errors.New("not authorized to sign this account") + } + signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) + if err != nil { + return nil, err + } + return tx.WithSignature(signer, signature) + }, + }, nil +} + // NewKeyedTransactor is a utility method to easily create a transaction signer // from a single private key. // From 6aeab6a207227e0fabcf1c0c66371a27bb34659c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 072/280] accounts/abi/bind: rename NewKeystoreTransactor (#19703) renamed NewKeyStoreFromTransactor to NewKeystoreTransactor fixed godoc --- accounts/abi/bind/auth.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index b661a29f4d..5949fed395 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -53,9 +53,9 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { return NewKeyedTransactor(key.PrivateKey), nil } -// NewTransactor is a utility method to easily create a transaction signer from +// NewKeystoreTransactor is a utility method to easily create a transaction signer from // an decrypted key from a keystore -func NewTransactorFromKeyStore(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { +func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { signer := types.HomesteadSigner{} return &TransactOpts{ From: account.Address, From 07ebb5ef129f5e0ed8a175cbe33bfdbce83b8aa5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 073/280] accounts/keystore: fix #19707, avoid keyword as variable name (#19731) --- accounts/keystore/keystore_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 4b6b307ad1..d74ab0d7e3 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -378,9 +378,9 @@ func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { if err != nil { t.Fatal(err) } - new := NewPlaintextKeyStore + newKs := NewPlaintextKeyStore if encrypted { - new = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } + newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } } - return d, new(d) + return d, newKs(d) } From 894bed5b7e3b8f155ccd6f00d53f1e824eef94f5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 074/280] accounts/abi: adding the method EventById and its test (#19359) --- accounts/abi/abi.go | 12 +++++++ accounts/abi/abi_test.go | 68 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 537f6c0f59..f4d9e8cbe6 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -23,6 +23,7 @@ import ( "fmt" "io" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -169,6 +170,17 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { return nil, fmt.Errorf("no method with id: %#x", sigdata[:4]) } +// EventByID looks an event up by its topic hash in the +// ABI and returns nil if none found. +func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { + for _, event := range abi.Events { + if bytes.Equal(event.Id().Bytes(), topic.Bytes()) { + return &event, nil + } + } + return nil, fmt.Errorf("no event with id: %#x", topic.Hex()) +} + // revertSelector is a special function selector for revert reason unpacking. var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 01a9fb33da..5f2fcfba29 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -968,3 +968,71 @@ func TestUnpackRevert(t *testing.T) { }) } } + +func TestABI_EventById(t *testing.T) { + tests := []struct { + name string + json string + event string + }{ + { + name: "", + json: `[ + {"type":"event","name":"received","anonymous":false,"inputs":[ + {"indexed":false,"name":"sender","type":"address"}, + {"indexed":false,"name":"amount","type":"uint256"}, + {"indexed":false,"name":"memo","type":"bytes"} + ] + }]`, + event: "received(address,uint256,bytes)", + }, { + name: "", + json: `[ + { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": true, "inputs": [ { "name": "_owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "balance", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [ { "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, + { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" } + ]`, + event: "Transfer(address,address,uint256)", + }, + } + + for testnum, test := range tests { + abi, err := JSON(strings.NewReader(test.json)) + if err != nil { + t.Error(err) + } + + topic := test.event + topicID := crypto.Keccak256Hash([]byte(topic)) + + event, err := abi.EventByID(topicID) + if err != nil { + t.Fatalf("Failed to look up ABI method: %v, test #%d", err, testnum) + } + if event == nil { + t.Errorf("We should find a event for topic %s, test #%d", topicID.Hex(), testnum) + } + + if event.Id() != topicID { + t.Errorf("Event id %s does not match topic %s, test #%d", event.Id().Hex(), topicID.Hex(), testnum) + } + + unknowntopicID := crypto.Keccak256Hash([]byte("unknownEvent")) + unknownEvent, err := abi.EventByID(unknowntopicID) + if err == nil { + t.Errorf("EventByID should return an error if a topic is not found, test #%d", testnum) + } + if unknownEvent != nil { + t.Errorf("We should not find any event for topic %s, test #%d", unknowntopicID.Hex(), testnum) + } + } +} From f542e463d39036a87aa05ff34aef361c81b1f6fe Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 075/280] accounts: implement simple checkpoint syncing (#19543) --- accounts/abi/bind/backends/simulated.go | 14 ++++---- accounts/abi/bind/bind_test.go | 3 +- accounts/abi/bind/template.go | 12 +++++++ accounts/abi/bind/util_test.go | 4 ++- consensus/tests/api_test.go | 4 +-- consensus/tests/engine_v1_tests/helper.go | 2 +- consensus/tests/engine_v2_tests/api_test.go | 36 ++++++++++----------- consensus/tests/engine_v2_tests/helper.go | 6 ++-- contracts/validator/validator_test.go | 2 +- 9 files changed, 50 insertions(+), 33 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index b129609e31..e955a18324 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -55,7 +55,9 @@ import ( // This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend. var _ bind.ContractBackend = (*SimulatedBackend)(nil) -var errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") +var ( + errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") +) // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in // the background. Its main purpose is to allow easily testing contract bindings. @@ -96,7 +98,7 @@ func SimulateWalletAddressAndSignFn() (common.Address, func(account accounts.Acc return a1.Address, ks.SignHash, nil } -// XDC simulated backend for testing purpose. +// NewXDCSimulatedBackend creates a new backend for testing purpose. func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfig *params.ChainConfig) *SimulatedBackend { database := rawdb.NewMemoryDatabase() genesis := core.Genesis{ @@ -139,9 +141,8 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi return backend } -// NewSimulatedBackend creates a new binding backend using a simulated blockchain -// for testing purposes. -// +// NewSimulatedBackend creates a new binding backend based on the given database +// and uses a simulated blockchain for testing purposes. // A simulated backend always uses chainID 1337. func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { database := rawdb.NewMemoryDatabase() @@ -625,7 +626,8 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { return nil } -func (b *SimulatedBackend) GetBlockChain() *core.BlockChain { +// Blockchain returns the underlying blockchain. +func (b *SimulatedBackend) BlockChain() *core.BlockChain { return b.blockchain } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index ed1d9f0c14..a4f7dc5af5 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -520,11 +520,12 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/params" `, ` // Create a simulator and wrap a non-deployed contract - sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000), params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000), params.TestXDPoSMockChainConfig) nonexistent, err := NewNonExistent(common.Address{}, sim) if err != nil { diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index f7b1ebb62a..e743d4064b 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -453,6 +453,18 @@ var ( } }), nil } + + // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.Id}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { + event := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { + return nil, err + } + return event, nil + } + {{end}} {{end}} ` diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 5b52249209..b836165708 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -59,7 +59,9 @@ func TestWaitDeployed(t *testing.T) { backend := backends.NewXDCSimulatedBackend( core.GenesisAlloc{ crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(100000000000000000)}, - }, 10000000, &config, + }, + 10000000, + &config, ) // Create the transaction diff --git a/consensus/tests/api_test.go b/consensus/tests/api_test.go index ed3e0897d0..64cbf80431 100644 --- a/consensus/tests/api_test.go +++ b/consensus/tests/api_test.go @@ -22,9 +22,9 @@ func TestConfigApi(t *testing.T) { voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, }, 10000000, params.TestXDPoSMockChainConfig) - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) - info := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).NetworkInformation() + info := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).NetworkInformation() assert.Equal(t, info.NetworkId, big.NewInt(1337)) assert.Equal(t, info.ConsensusConfigs.V2.CurrentConfig.MaxMasternodes, 18) diff --git a/consensus/tests/engine_v1_tests/helper.go b/consensus/tests/engine_v1_tests/helper.go index afc1a22cf0..e1a66d1308 100644 --- a/consensus/tests/engine_v1_tests/helper.go +++ b/consensus/tests/engine_v1_tests/helper.go @@ -244,7 +244,7 @@ func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int, chainConfig *params signer, signFn, err := backends.SimulateWalletAddressAndSignFn() backend := getCommonBackend(t, chainConfig) - blockchain := backend.GetBlockChain() + blockchain := backend.BlockChain() blockchain.Client = backend if err != nil { diff --git a/consensus/tests/engine_v2_tests/api_test.go b/consensus/tests/engine_v2_tests/api_test.go index 0b1258d2a4..d02790d894 100644 --- a/consensus/tests/engine_v2_tests/api_test.go +++ b/consensus/tests/engine_v2_tests/api_test.go @@ -15,10 +15,10 @@ import ( func TestGetMissedRoundsInEpochByBlockNumOnlyForV2Consensus(t *testing.T) { _, bc, _, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) blockNum := rpc.BlockNumber(123) - data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.EqualError(t, err, "not supported in the v1 consensus") assert.Nil(t, data) @@ -27,10 +27,10 @@ func TestGetMissedRoundsInEpochByBlockNumOnlyForV2Consensus(t *testing.T) { func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2(t *testing.T) { _, bc, cb, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) blockNum := rpc.BlockNumber(cb.NumberU64()) - data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.Nil(t, err) assert.Equal(t, types.Round(900), data.EpochRound) @@ -39,7 +39,7 @@ func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2(t *testing.T) { blockNum = rpc.BlockNumber(1800) - data, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.Nil(t, err) assert.Equal(t, types.Round(900), data.EpochRound) @@ -48,7 +48,7 @@ func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2(t *testing.T) { blockNum = rpc.BlockNumber(1801) - data, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.Nil(t, err) assert.Equal(t, types.Round(900), data.EpochRound) @@ -59,10 +59,10 @@ func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2(t *testing.T) { func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2FistEpoch(t *testing.T) { _, bc, _, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) blockNum := rpc.BlockNumber(901) - data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.Nil(t, err) assert.Equal(t, types.Round(1), data.EpochRound) @@ -73,7 +73,7 @@ func TestGetMissedRoundsInEpochByBlockNumReturnEmptyForV2FistEpoch(t *testing.T) func TestGetMissedRoundsInEpochByBlockNum(t *testing.T) { blockchain, bc, currentBlock, signer, signFn := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) chainConfig := params.TestXDPoSMockChainConfig - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) blockCoinBase := signer.Hex() startingBlockNum := currentBlock.Number().Int64() + 1 @@ -93,7 +93,7 @@ func TestGetMissedRoundsInEpochByBlockNum(t *testing.T) { blockNum := rpc.BlockNumber(1803) - data, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) + data, err := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetMissedRoundsInEpochByBlockNum(&blockNum) assert.Nil(t, err) assert.Equal(t, types.Round(900), data.EpochRound) @@ -114,32 +114,32 @@ func TestGetMissedRoundsInEpochByBlockNum(t *testing.T) { func TestGetEpochNumbersBetween(t *testing.T) { _, bc, _, _, _ := PrepareXDCTestBlockChainWith128Candidates(t, 1802, params.TestXDPoSMockChainConfig) - engine := bc.GetBlockChain().Engine().(*XDPoS.XDPoS) + engine := bc.BlockChain().Engine().(*XDPoS.XDPoS) begin := rpc.BlockNumber(1800) end := rpc.BlockNumber(1802) - numbers, err := engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err := engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers)) assert.Nil(t, err) begin = rpc.BlockNumber(1799) end = rpc.BlockNumber(1802) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers)) assert.Nil(t, err) begin = rpc.BlockNumber(1799) end = rpc.BlockNumber(1802) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.True(t, reflect.DeepEqual([]uint64{1800}, numbers)) assert.Nil(t, err) begin = rpc.BlockNumber(901) end = rpc.BlockNumber(1802) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.True(t, reflect.DeepEqual([]uint64{901, 1800}, numbers)) assert.Nil(t, err) @@ -147,7 +147,7 @@ func TestGetEpochNumbersBetween(t *testing.T) { // 900 is V1, not V2, so error begin = rpc.BlockNumber(900) end = rpc.BlockNumber(1802) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.Nil(t, numbers) assert.EqualError(t, err, "not supported in the v1 consensus") @@ -155,7 +155,7 @@ func TestGetEpochNumbersBetween(t *testing.T) { // 1803 not exist begin = rpc.BlockNumber(901) end = rpc.BlockNumber(1803) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.Nil(t, numbers) assert.EqualError(t, err, "illegal end block number") @@ -163,7 +163,7 @@ func TestGetEpochNumbersBetween(t *testing.T) { // 1803 not exist begin = rpc.BlockNumber(1803) end = rpc.BlockNumber(1803) - numbers, err = engine.APIs(bc.GetBlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) + numbers, err = engine.APIs(bc.BlockChain())[0].Service.(*XDPoS.API).GetEpochNumbersBetween(&begin, &end) assert.Nil(t, numbers) assert.EqualError(t, err, "illegal begin block number") diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index 1e9b6d14b9..c13b289b34 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -373,7 +373,7 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon panic(fmt.Errorf("error while creating simulated wallet for generating singer address and signer fn: %v", err)) } backend := getCommonBackend(t, chainConfig) - blockchain := backend.GetBlockChain() + blockchain := backend.BlockChain() blockchain.Client = backend engine := blockchain.Engine().(*XDPoS.XDPoS) @@ -463,7 +463,7 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in t.Fatal("Error while creating simulated wallet for generating singer address and signer fn: ", err) } backend := getCommonBackend(t, chainConfig) - blockchain := backend.GetBlockChain() + blockchain := backend.BlockChain() blockchain.Client = backend // Authorise @@ -514,7 +514,7 @@ func PrepareXDCTestBlockChainWith128Candidates(t *testing.T, numOfBlocks int, ch t.Fatal("Error while creating simulated wallet for generating singer address and signer fn: ", err) } backend := getMultiCandidatesBackend(t, chainConfig, 128) - blockchain := backend.GetBlockChain() + blockchain := backend.BlockChain() blockchain.Client = backend engine := blockchain.Engine().(*XDPoS.XDPoS) diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index c2b5d0fde1..090d261770 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -320,7 +320,7 @@ func TestStatedbUtils(t *testing.T) { if err != nil { t.Fatalf("can't get validator object: %v", err) } - statedb, err := contractBackendForValidator.GetBlockChain().State() + statedb, err := contractBackendForValidator.BlockChain().State() if err != nil { t.Fatalf("can't get statedb: %v", err) } From 71e4c0609afc780179b11790c84aabb7ab695b61 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 076/280] accounts/abi: Fix method overwritten by same name methods (#17099) * accounts/abi: Fix method overwritten by same name methods. * accounts/abi: Fix method overwritten by same name methods. * accounts/abi: avoid possible name conflict Co-authored-by: Guillaume Ballet --- accounts/abi/abi.go | 20 ++++++++++++--- accounts/abi/abi_test.go | 45 +++++++++++++++++++++++++++++++--- accounts/abi/bind/base_test.go | 26 -------------------- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index f4d9e8cbe6..cea58ae301 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -138,15 +138,27 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } // empty defaults to function according to the abi spec case "function", "": - abi.Methods[field.Name] = Method{ - Name: field.Name, + name := field.Name + _, ok := abi.Methods[name] + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", field.Name, idx) + _, ok = abi.Methods[name] + } + abi.Methods[name] = Method{ + Name: name, Const: field.Constant, Inputs: field.Inputs, Outputs: field.Outputs, } case "event": - abi.Events[field.Name] = Event{ - Name: field.Name, + name := field.Name + _, ok := abi.Events[name] + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", field.Name, idx) + _, ok = abi.Events[name] + } + abi.Events[name] = Event{ + Name: name, Anonymous: field.Anonymous, Inputs: field.Inputs, } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 5f2fcfba29..52d73992eb 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -838,9 +838,6 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) { if err = abi.UnpackIntoMap(receivedMap, "received", data); err != nil { t.Error("naming conflict between two events; no error expected") } - if len(receivedMap) != 1 { - t.Error("naming conflict between two events; event defined latest in the abi expected to be used") - } // Method and event have the same name abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"received","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` @@ -1036,3 +1033,45 @@ func TestABI_EventById(t *testing.T) { } } } + +func TestDuplicateMethodNames(t *testing.T) { + abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` + contractAbi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + if _, ok := contractAbi.Methods["transfer"]; !ok { + t.Fatalf("Could not find original method") + } + if _, ok := contractAbi.Methods["transfer0"]; !ok { + t.Fatalf("Could not find duplicate method") + } + if _, ok := contractAbi.Methods["transfer1"]; !ok { + t.Fatalf("Could not find duplicate method") + } + if _, ok := contractAbi.Methods["transfer2"]; ok { + t.Fatalf("Should not have found extra method") + } +} + +// TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name +// conflict and that the second transfer method will be renamed transfer1. +func TestDoubleDuplicateMethodNames(t *testing.T) { + abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer0","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` + contractAbi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + if _, ok := contractAbi.Methods["transfer"]; !ok { + t.Fatalf("Could not find original method") + } + if _, ok := contractAbi.Methods["transfer0"]; !ok { + t.Fatalf("Could not find duplicate method") + } + if _, ok := contractAbi.Methods["transfer1"]; !ok { + t.Fatalf("Could not find duplicate method") + } + if _, ok := contractAbi.Methods["transfer2"]; ok { + t.Fatalf("Should not have found extra method") + } +} diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 6fbbcdf727..5ab9300c33 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -443,29 +443,3 @@ func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { t.Error("unpacked map does not match expected map") } } - -func TestUnpackIntoMapNamingConflict(t *testing.T) { - hash := crypto.Keccak256Hash([]byte("testName")) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x0"), - hash, - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x0"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, - } - - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err == nil { - t.Error("naming conflict between two events; error expected") - } -} From 0050f84142e54886076c01fa074bbb8baffe76b3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 077/280] accounts/abi: enable struct golang binding generation (#18491) * accounts/abi, cmd/abigen: support tuple accounts/abi/bind, cmd/abigen: add objc back accounts/abi/bind: use byte[24] as function indicator accounts/abi/bind: resolve struct slice or array accounts/abi/bind: remove sort logic accounts: fix issues in abi * accounts/abi: address comment --- accounts/abi/argument.go | 17 ++++- accounts/abi/bind/bind.go | 127 +++++++++++++++++++++++++++++++--- accounts/abi/bind/template.go | 67 ++++++++++++------ accounts/abi/method_test.go | 73 ++++++++++++++++++- accounts/abi/reflect.go | 8 +++ accounts/abi/type.go | 9 +-- accounts/abi/unpack_test.go | 16 ++--- 7 files changed, 264 insertions(+), 53 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index ff1265a8cb..8cfa8db1a9 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -131,11 +131,22 @@ func unpack(t *Type, dst interface{}, src interface{}) error { dstVal = reflect.ValueOf(dst).Elem() srcVal = reflect.ValueOf(src) ) - - if t.T != TupleTy && !((t.T == SliceTy || t.T == ArrayTy) && t.Elem.T == TupleTy) { + tuple, typ := false, t + for { + if typ.T == SliceTy || typ.T == ArrayTy { + typ = typ.Elem + continue + } + tuple = typ.T == TupleTy + break + } + if !tuple { return set(dstVal, srcVal) } + // Dereferences interface or pointer wrapper + dstVal = indirectInterfaceOrPtr(dstVal) + switch t.T { case TupleTy: if dstVal.Kind() != reflect.Struct { @@ -203,7 +214,7 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interfac argument := arguments.NonIndexed()[0] elem := reflect.ValueOf(v).Elem() - if elem.Kind() == reflect.Struct { + if elem.Kind() == reflect.Struct && argument.Type.T != TupleTy { fieldmap, err := mapArgNamesToStructFields([]string{argument.Name}, elem) if err != nil { return err diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 92dd5ba374..d2c20489d3 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -65,11 +65,12 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] return r }, abis[i]) - // Extract the call and transact methods; events; and sort them alphabetically + // Extract the call and transact methods; events, struct definitions; and sort them alphabetically var ( calls = make(map[string]*tmplMethod) transacts = make(map[string]*tmplMethod) events = make(map[string]*tmplEvent) + structs = make(map[string]*tmplStruct) ) for _, original := range evmABI.Methods { // Normalize the method for capital cases and non-anonymous inputs/outputs @@ -82,6 +83,9 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if input.Name == "" { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } + if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist { + bindStructType[lang](input.Type, structs) + } } normalized.Outputs = make([]abi.Argument, len(original.Outputs)) copy(normalized.Outputs, original.Outputs) @@ -89,6 +93,9 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if output.Name != "" { normalized.Outputs[j].Name = capitalise(output.Name) } + if _, exist := structs[output.Type.String()]; output.Type.T == abi.TupleTy && !exist { + bindStructType[lang](output.Type, structs) + } } // Append the methods to the call or transact lists if original.Const { @@ -114,6 +121,9 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if input.Name == "" { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } + if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist { + bindStructType[lang](input.Type, structs) + } } } // Append the event to the accumulator list @@ -129,6 +139,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] Transacts: transacts, Events: events, Libraries: make(map[string]string), + Structs: structs, } // Function 4-byte signatures are stored in the same sequence // as types, if available. @@ -167,6 +178,8 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] "bindtype": bindType[lang], "bindtopictype": bindTopicType[lang], "namedtype": namedType[lang], + "formatmethod": formatMethod, + "formatevent": formatEvent, "capitalise": capitalise, "decapitalise": decapitalise, } @@ -188,7 +201,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // bindType is a set of type binders that convert Solidity types to some supported // programming language types. -var bindType = map[Lang]func(kind abi.Type) string{ +var bindType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ LangGo: bindTypeGo, } @@ -219,13 +232,14 @@ func bindBasicTypeGo(kind abi.Type) string { // bindTypeGo converts solidity types to Go ones. Since there is no clear mapping // from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly // mapped will use an upscaled type (e.g. BigDecimal). -func bindTypeGo(kind abi.Type) string { - // todo(rjl493456442) tuple +func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { + case abi.TupleTy: + return structs[kind.String()].Name case abi.ArrayTy: - return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem) + return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs) case abi.SliceTy: - return "[]" + bindTypeGo(*kind.Elem) + return "[]" + bindTypeGo(*kind.Elem, structs) default: return bindBasicTypeGo(kind) } @@ -233,20 +247,55 @@ func bindTypeGo(kind abi.Type) string { // bindTopicType is a set of type binders that convert Solidity types to some // supported programming language topic types. -var bindTopicType = map[Lang]func(kind abi.Type) string{ +var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ LangGo: bindTopicTypeGo, } // bindTypeGo converts a Solidity topic type to a Go one. It is almost the same // funcionality as for simple types, but dynamic types get converted to hashes. -func bindTopicTypeGo(kind abi.Type) string { - bound := bindTypeGo(kind) +func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { + bound := bindTypeGo(kind, structs) if bound == "string" || bound == "[]byte" { bound = "common.Hash" } return bound } +// bindStructType is a set of type binders that convert Solidity tuple types to some supported +// programming language struct definition. +var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{ + LangGo: bindStructTypeGo, +} + +// bindStructTypeGo converts a Solidity tuple type to a Go one and records the mapping +// in the given map. +// Notably, this function will resolve and record nested struct recursively. +func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { + switch kind.T { + case abi.TupleTy: + if s, exist := structs[kind.String()]; exist { + return s.Name + } + var fields []*tmplField + for i, elem := range kind.TupleElems { + field := bindStructTypeGo(*elem, structs) + fields = append(fields, &tmplField{Type: field, Name: capitalise(kind.TupleRawNames[i]), SolKind: *elem}) + } + name := fmt.Sprintf("Struct%d", len(structs)) + structs[kind.String()] = &tmplStruct{ + Name: name, + Fields: fields, + } + return name + case abi.ArrayTy: + return fmt.Sprintf("[%d]", kind.Size) + bindStructTypeGo(*kind.Elem, structs) + case abi.SliceTy: + return "[]" + bindStructTypeGo(*kind.Elem, structs) + default: + return bindBasicTypeGo(kind) + } +} + // namedType is a set of functions that transform language specific types to // named versions that my be used inside method names. var namedType = map[Lang]func(string, abi.Type) string{ @@ -296,3 +345,63 @@ func structured(args abi.Arguments) bool { } return true } + +// resolveArgName converts a raw argument representation into a user friendly format. +func resolveArgName(arg abi.Argument, structs map[string]*tmplStruct) string { + var ( + prefix string + embedded string + typ = &arg.Type + ) +loop: + for { + switch typ.T { + case abi.SliceTy: + prefix += "[]" + case abi.ArrayTy: + prefix += fmt.Sprintf("[%d]", typ.Size) + default: + embedded = typ.String() + break loop + } + typ = typ.Elem + } + if s, exist := structs[embedded]; exist { + return prefix + s.Name + } else { + return arg.Type.String() + } +} + +// formatMethod transforms raw method representation into a user friendly one. +func formatMethod(method abi.Method, structs map[string]*tmplStruct) string { + inputs := make([]string, len(method.Inputs)) + for i, input := range method.Inputs { + inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name) + } + outputs := make([]string, len(method.Outputs)) + for i, output := range method.Outputs { + outputs[i] = resolveArgName(output, structs) + if len(output.Name) > 0 { + outputs[i] += fmt.Sprintf(" %v", output.Name) + } + } + constant := "" + if method.Const { + constant = "constant " + } + return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) +} + +// formatEvent transforms raw event representation into a user friendly one. +func formatEvent(event abi.Event, structs map[string]*tmplStruct) string { + inputs := make([]string, len(event.Inputs)) + for i, input := range event.Inputs { + if input.Indexed { + inputs[i] = fmt.Sprintf("%v indexed %v", resolveArgName(input, structs), input.Name) + } else { + inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name) + } + } + return fmt.Sprintf("event %v(%v)", event.Name, strings.Join(inputs, ", ")) +} diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index e743d4064b..f941d595ad 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -36,6 +36,7 @@ type tmplContract struct { Transacts map[string]*tmplMethod // Contract calls that write state data Events map[string]*tmplEvent // Contract events accessors Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs + Structs map[string]*tmplStruct // Contract struct type definitions Library bool } @@ -53,6 +54,21 @@ type tmplEvent struct { Normalized abi.Event // Normalized version of the parsed fields } +// tmplField is a wrapper around a struct field with binding language +// struct type definition and relative filed name. +type tmplField struct { + Type string // Field type representation depends on target binding language + Name string // Field name converted from the raw user-defined field name + SolKind abi.Type // Raw abi type information +} + +// tmplStruct is a wrapper around an abi.tuple contains a auto-generated +// struct name. +type tmplStruct struct { + Name string // Auto-generated struct name(We can't obtain the raw struct name through abi) + Fields []*tmplField // Struct fields definition depends on the binding language. +} + // tmplSource is language to template mapping containing all the supported // programming languages the package can generate to. var tmplSource = map[Lang]string{ @@ -91,6 +107,7 @@ var ( ) {{range $contract := .Contracts}} + {{$structs := $contract.Structs}} // {{.Type}}ABI is the input ABI used to generate the binding from. const {{.Type}}ABI = "{{.InputABI}}" @@ -107,7 +124,7 @@ var ( var {{.Type}}Bin = "0x{{.InputBin}}" // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. - func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { + func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI)) if err != nil { return common.Address{}, nil, nil, err @@ -128,7 +145,7 @@ var ( type {{.Type}} struct { {{.Type}}Caller // Read-only binding to the contract {{.Type}}Transactor // Write-only binding to the contract - {{.Type}}Filterer // Log filterer for contract events + {{.Type}}Filterer // Log filterer for contract events } // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract. @@ -266,16 +283,24 @@ var ( return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) } + {{range .Structs}} + // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. + type {{.Name}} struct { + {{range $field := .Fields}} + {{$field.Name}} {{$field.Type}}{{end}} + } + {{end}} + {{range .Calls}} // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type}},{{end}}{{end}} error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { {{if .Structured}}ret := new(struct{ - {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type}} + {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}} {{end}} }){{else}}var ( - {{range $i, $_ := .Normalized.Outputs}}ret{{$i}} = new({{bindtype .Type}}) + {{range $i, $_ := .Normalized.Outputs}}ret{{$i}} = new({{bindtype .Type $structs}}) {{end}} ){{end}} out := {{if .Structured}}ret{{else}}{{if eq (len .Normalized.Outputs) 1}}ret0{{else}}&[]interface{}{ @@ -288,15 +313,15 @@ var ( // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type}},{{end}} {{end}} error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type}},{{end}} {{end}} error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } {{end}} @@ -304,22 +329,22 @@ var ( {{range .Transacts}} // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type}} {{end}}) (*types.Transaction, error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type}} {{end}}) (*types.Transaction, error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type}} {{end}}) (*types.Transaction, error) { + // Solidity: {{formatmethod .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) } {{end}} @@ -391,14 +416,14 @@ var ( // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract. type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}} - {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type}}{{else}}{{bindtype .Type}}{{end}}; {{end}} + {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}} Raw types.Log // Blockchain specific contextual infos } // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { + // Solidity: {{formatevent .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { {{range .Normalized.Inputs}} {{if .Indexed}}var {{.Name}}Rule []interface{} for _, {{.Name}}Item := range {{.Name}} { @@ -414,8 +439,8 @@ var ( // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.Id}}. // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type}}{{end}}{{end}}) (event.Subscription, error) { + // Solidity: {{formatevent .Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { {{range .Normalized.Inputs}} {{if .Indexed}}var {{.Name}}Rule []interface{} for _, {{.Name}}Item := range {{.Name}} { diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go index a98f1cd31f..92c360f0d2 100644 --- a/accounts/abi/method_test.go +++ b/accounts/abi/method_test.go @@ -23,9 +23,13 @@ import ( const methoddata = ` [ - { "type" : "function", "name" : "balance", "constant" : true }, - { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, - { "type" : "function", "name" : "transfer", "constant" : false, "inputs" : [ { "name" : "from", "type" : "address" }, { "name" : "to", "type" : "address" }, { "name" : "value", "type" : "uint256" } ], "outputs" : [ { "name" : "success", "type" : "bool" } ] } + {"type": "function", "name": "balance", "constant": true }, + {"type": "function", "name": "send", "constant": false, "inputs": [{ "name": "amount", "type": "uint256" }]}, + {"type": "function", "name": "transfer", "constant": false, "inputs": [{"name": "from", "type": "address"}, {"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}], "outputs": [{"name": "success", "type": "bool"}]}, + {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple"}],"name":"tuple","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, + {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[]"}],"name":"tupleSlice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, + {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[5]"}],"name":"tupleArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, + {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[5][]"}],"name":"complexTuple","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"} ]` func TestMethodString(t *testing.T) { @@ -45,6 +49,22 @@ func TestMethodString(t *testing.T) { method: "transfer", expectation: "function transfer(address from, address to, uint256 value) returns(bool success)", }, + { + method: "tuple", + expectation: "function tuple((uint256,uint256) a) returns()", + }, + { + method: "tupleArray", + expectation: "function tupleArray((uint256,uint256)[5] a) returns()", + }, + { + method: "tupleSlice", + expectation: "function tupleSlice((uint256,uint256)[] a) returns()", + }, + { + method: "complexTuple", + expectation: "function complexTuple((uint256,uint256)[5][] a) returns()", + }, } abi, err := JSON(strings.NewReader(methoddata)) @@ -59,3 +79,50 @@ func TestMethodString(t *testing.T) { } } } + +func TestMethodSig(t *testing.T) { + var cases = []struct { + method string + expect string + }{ + { + method: "balance", + expect: "balance()", + }, + { + method: "send", + expect: "send(uint256)", + }, + { + method: "transfer", + expect: "transfer(address,address,uint256)", + }, + { + method: "tuple", + expect: "tuple((uint256,uint256))", + }, + { + method: "tupleArray", + expect: "tupleArray((uint256,uint256)[5])", + }, + { + method: "tupleSlice", + expect: "tupleSlice((uint256,uint256)[])", + }, + { + method: "complexTuple", + expect: "complexTuple((uint256,uint256)[5][])", + }, + } + abi, err := JSON(strings.NewReader(methoddata)) + if err != nil { + t.Fatal(err) + } + + for _, test := range cases { + got := abi.Methods[test.method].Sig() + if got != test.expect { + t.Errorf("expected string to be %s, got %s", test.expect, got) + } + } +} diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index fc2faa6869..83e4059d2d 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -31,6 +31,14 @@ func indirect(v reflect.Value) reflect.Value { return v } +// indirectInterfaceOrPtr recursively dereferences the value until value is not interface. +func indirectInterfaceOrPtr(v reflect.Value) reflect.Value { + if (v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr) && v.Elem().IsValid() { + return indirect(v.Elem()) + } + return v +} + // reflectIntKind returns the reflect using the given size and // unsignedness. func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 90ebb75ab2..0b15dcc401 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -68,7 +68,6 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { if strings.Count(t, "[") != strings.Count(t, "]") { return Type{}, errors.New("invalid arg type in abi") } - typ.stringKind = t // if there are brackets, get ready to go into slice/array mode and @@ -92,9 +91,7 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { typ.Kind = reflect.Slice typ.Elem = &embeddedType typ.Type = reflect.SliceOf(embeddedType.Type) - if embeddedType.T == TupleTy { - typ.stringKind = embeddedType.stringKind + sliced - } + typ.stringKind = embeddedType.stringKind + sliced } else if len(intz) == 1 { // is a array typ.T = ArrayTy @@ -105,9 +102,7 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) } typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type) - if embeddedType.T == TupleTy { - typ.stringKind = embeddedType.stringKind + sliced - } + typ.stringKind = embeddedType.stringKind + sliced } else { return Type{}, errors.New("invalid formatting of array type") } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index e8f8995f5c..391927dc8b 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -965,25 +965,21 @@ func TestUnpackTuple(t *testing.T) { buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) // ret[a] = 1 buff.Write(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) // ret[b] = -1 + // If the result is single tuple, use struct as return value container directly. v := struct { - Ret struct { - A *big.Int - B *big.Int - } - }{Ret: struct { A *big.Int B *big.Int - }{new(big.Int), new(big.Int)}} + }{new(big.Int), new(big.Int)} err = abi.Unpack(&v, "tuple", buff.Bytes()) if err != nil { t.Error(err) } else { - if v.Ret.A.Cmp(big.NewInt(1)) != 0 { - t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.Ret.A) + if v.A.Cmp(big.NewInt(1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A) } - if v.Ret.B.Cmp(big.NewInt(-1)) != 0 { - t.Errorf("unexpected value unpacked: want %x, got %x", v.Ret.B, -1) + if v.B.Cmp(big.NewInt(-1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", v.B, -1) } } From 587f6b34388dc002c2f5866739428e0f742ef354 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 078/280] accounts/abi/bind: fix typo in comments (#19791) --- accounts/abi/bind/auth.go | 2 +- accounts/abi/bind/bind.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 5949fed395..6051aebe58 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -53,7 +53,7 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { return NewKeyedTransactor(key.PrivateKey), nil } -// NewKeystoreTransactor is a utility method to easily create a transaction signer from +// NewKeyStoreTransactor is a utility method to easily create a transaction signer from // an decrypted key from a keystore func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { signer := types.HomesteadSigner{} diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index d2c20489d3..1301af300a 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -251,7 +251,7 @@ var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) LangGo: bindTopicTypeGo, } -// bindTypeGo converts a Solidity topic type to a Go one. It is almost the same +// bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same // funcionality as for simple types, but dynamic types get converted to hashes. func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { bound := bindTypeGo(kind, structs) From f571689bab7c87e11ca246118333a03df631a9dc Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 079/280] signer/core: fix reference issue in key derivation (#19827) * signer/core: fix reference issue in key derivation * Review feedback --- accounts/usbwallet/wallet.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 289b086d09..659d164cca 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -479,7 +479,8 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun if _, ok := w.paths[address]; !ok { w.accounts = append(w.accounts, account) - w.paths[address] = path + w.paths[address] = make(accounts.DerivationPath, len(path)) + copy(w.paths[address], path) } return account, nil } From 6d17a42edb6098bd276c1d49ebb0315733cc527f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 080/280] all: replace t.Log(); t.FailNow() with t.Fatal() (#19849) --- accounts/abi/abi_test.go | 23 +++++++------------ .../tests/engine_v2_tests/forensics_test.go | 13 +++++++---- core/blockchain_test.go | 3 +-- core/txpool/lending_pool_test.go | 12 ++++------ core/types/transaction_test.go | 14 ++++------- 5 files changed, 26 insertions(+), 39 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 52d73992eb..efdfc03645 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -21,7 +21,6 @@ import ( "encoding/hex" "errors" "fmt" - "log" "math/big" "reflect" "strings" @@ -105,8 +104,7 @@ func TestReader(t *testing.T) { func TestTestNumbers(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if _, err := abi.Pack("balance"); err != nil { @@ -143,8 +141,7 @@ func TestTestNumbers(t *testing.T) { func TestTestString(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if _, err := abi.Pack("string", "hello world"); err != nil { @@ -155,8 +152,7 @@ func TestTestString(t *testing.T) { func TestTestBool(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if _, err := abi.Pack("bool", true); err != nil { @@ -167,8 +163,7 @@ func TestTestBool(t *testing.T) { func TestTestSlice(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } slice := make([]uint64, 2) @@ -224,8 +219,7 @@ func TestMethodSignature(t *testing.T) { func TestMultiPack(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } sig := crypto.Keccak256([]byte("bar(uint32,uint16)"))[:4] @@ -235,8 +229,7 @@ func TestMultiPack(t *testing.T) { packed, err := abi.Pack("bar", uint32(10), uint16(11)) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if !bytes.Equal(packed, sig) { @@ -249,11 +242,11 @@ func ExampleJSON() { abi, err := JSON(strings.NewReader(definition)) if err != nil { - log.Fatalln(err) + panic(err) } out, err := abi.Pack("isBar", common.HexToAddress("01")) if err != nil { - log.Fatalln(err) + panic(err) } fmt.Printf("%x\n", out) diff --git a/consensus/tests/engine_v2_tests/forensics_test.go b/consensus/tests/engine_v2_tests/forensics_test.go index dd9ad913db..a5a77d93eb 100644 --- a/consensus/tests/engine_v2_tests/forensics_test.go +++ b/consensus/tests/engine_v2_tests/forensics_test.go @@ -3,6 +3,7 @@ package engine_v2_tests import ( "crypto/ecdsa" "encoding/json" + "errors" "math/big" "testing" "time" @@ -16,6 +17,8 @@ import ( "github.com/stretchr/testify/assert" ) +var errTimeoutAfter5Seconds = errors.New("timeout after 5 seconds") + func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) { t.Skip("Skipping this test for now as we disable forensics") @@ -200,7 +203,7 @@ func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) { assert.Equal(t, 5, len(content.LargerRoundInfo.SignerAddresses)) return case <-time.After(5 * time.Second): - t.FailNow() + t.Fatal(errTimeoutAfter5Seconds) } } } @@ -262,7 +265,7 @@ func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) { assert.Equal(t, 2, len(content.LargerRoundInfo.SignerAddresses)) return case <-time.After(5 * time.Second): - t.FailNow() + t.Fatal(errTimeoutAfter5Seconds) } } } @@ -327,7 +330,7 @@ func TestForensicsAcrossEpoch(t *testing.T) { assert.Equal(t, 2, len(content.LargerRoundInfo.SignerAddresses)) return case <-time.After(5 * time.Second): - t.FailNow() + t.Fatal(errTimeoutAfter5Seconds) } } } @@ -395,7 +398,7 @@ func TestVoteEquivocationSameRound(t *testing.T) { assert.Equal(t, types.Round(5), content.LargerRoundVote.ProposedBlockInfo.Round) return case <-time.After(5 * time.Second): - t.FailNow() + t.Fatal(errTimeoutAfter5Seconds) } } } @@ -452,7 +455,7 @@ func TestVoteEquivocationDifferentRound(t *testing.T) { assert.Equal(t, acc1Addr, content.Signer) return case <-time.After(5 * time.Second): - t.FailNow() + t.Fatal(errTimeoutAfter5Seconds) } } } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index eb26fca2b8..0ea24c180b 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -157,8 +157,7 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) { _, err := blockchain.InsertChain(chain) if err != nil { - fmt.Println(err) - t.FailNow() + t.Fatal(err) } done <- true } diff --git a/core/txpool/lending_pool_test.go b/core/txpool/lending_pool_test.go index ceb6970b7a..fff43d190c 100644 --- a/core/txpool/lending_pool_test.go +++ b/core/txpool/lending_pool_test.go @@ -177,8 +177,7 @@ func TestSendLending(t *testing.T) { } nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey)) if err != nil { - t.Error("fail to get nonce") - t.FailNow() + t.Fatal("fail to get nonce") } for { @@ -249,8 +248,7 @@ func TestCancelLending(t *testing.T) { } nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey)) if err != nil { - t.Error("fail to get nonce") - t.FailNow() + t.Fatal("fail to get nonce") } // 10% @@ -272,16 +270,14 @@ func TestRecallLending(t *testing.T) { } nonce, err := getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey)) if err != nil { - t.Error("fail to get nonce") - t.FailNow() + t.Fatal("fail to get nonce") } interestRate := 10 * common.BaseLendingInterest.Uint64() testSendLending(key, nonce, USDAddress, common.Address{}, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Investing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "") time.Sleep(2 * time.Second) nonce, err = getLendingNonce(crypto.PubkeyToAddress(privateKey.PublicKey)) if err != nil { - t.Error("fail to get nonce") - t.FailNow() + t.Fatal("fail to get nonce") } testSendLending(key, nonce, USDAddress, common.XDCNativeAddressBinary, new(big.Int).Mul(_1E8, big.NewInt(1000)), interestRate, lendingstate.Borrowing, lendingstate.LendingStatusNew, true, 0, 0, common.Hash{}, "") time.Sleep(2 * time.Second) diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index e43e55f79b..e0d46bd8d6 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -230,14 +230,12 @@ func TestRecipientEmpty(t *testing.T) { _, addr := defaultTestKey() tx, err := decodeTx(common.Hex2Bytes("f8498080808080011ca09b16de9d5bdee2cf56c28d16275a4da68cd30273e2525f3959f5d62557489921a0372ebd8fb3345f7db7b5a86d42e24d36e983e259b0664ceb8c227ec9af572f3d")) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } from, err := Sender(HomesteadSigner{}, tx) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if addr != from { t.Error("derived address doesn't match") @@ -249,18 +247,16 @@ func TestRecipientNormal(t *testing.T) { tx, err := decodeTx(common.Hex2Bytes("f85d80808094000000000000000000000000000000000000000080011ca0527c0d8f5c63f7b9f41324a7c8a563ee1190bcbf0dac8ab446291bdbf32f5c79a0552c4ef0a09a04395074dab9ed34d3fbfb843c2f2546cc30fe89ec143ca94ca6")) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } from, err := Sender(HomesteadSigner{}, tx) if err != nil { - t.Error(err) - t.FailNow() + t.Fatal(err) } if addr != from { - t.Error("derived address doesn't match") + t.Fatal("derived address doesn't match") } } From 9340a81ce1297dfa22caf7d3fe16f0874d22d3f0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 081/280] accounts/abi/bind: support closing a simulated backend (#19902) --- accounts/abi/bind/backends/simulated_test.go | 1 + accounts/abi/bind/bind_test.go | 20 ++++++++++++++++++++ accounts/abi/bind/util_test.go | 1 + 3 files changed, 22 insertions(+) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 8075552dc1..16728b0996 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -41,6 +41,7 @@ func TestSimulatedBackend(t *testing.T) { genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} sim := NewSimulatedBackend(genAlloc, gasLimit) + defer sim.Close() // should return an error if the tx is not found txHash := common.HexToHash("2") diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index a4f7dc5af5..244fa5c287 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -283,7 +283,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy an interaction tester contract and call a transaction on it _, _, interactor, err := DeployInteractor(auth, sim, "Deploy string") @@ -336,7 +338,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a tuple tester contract and execute a structured call on it _, _, getter, err := DeployGetter(auth, sim) @@ -380,7 +384,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a tuple tester contract and execute a structured call on it _, _, tupler, err := DeployTupler(auth, sim) @@ -436,7 +442,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a slice tester contract and execute a n array call on it _, _, slicer, err := DeploySlicer(auth, sim) @@ -482,7 +490,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a default method invoker contract and execute its default method _, _, defaulter, err := DeployDefaulter(auth, sim) @@ -526,6 +536,7 @@ var bindTests = []struct { ` // Create a simulator and wrap a non-deployed contract sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000), params.TestXDPoSMockChainConfig) + defer sim.Close() nonexistent, err := NewNonExistent(common.Address{}, sim) if err != nil { @@ -573,7 +584,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a funky gas pattern contract _, _, limiter, err := DeployFunkyGasPattern(auth, sim) @@ -622,7 +635,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a sender tester contract and execute a structured call on it _, _, callfrom, err := DeployCallFrom(auth, sim) @@ -697,6 +712,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy a underscorer tester contract and execute a structured call on it _, _, underscorer, err := DeployUnderscorer(auth, sim) @@ -788,7 +804,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() // Deploy an eventer contract _, _, eventer, err := DeployEventer(auth, sim) @@ -976,7 +994,9 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() //deploy the test contract _, _, testContract, err := DeployDeeplyNestedArray(auth, sim) diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index b836165708..7475374c4f 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -63,6 +63,7 @@ func TestWaitDeployed(t *testing.T) { 10000000, &config, ) + defer backend.Close() // Create the transaction head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough From 5009a3df042f7bdee6427debe1737a2b4c670ec4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 082/280] accounts/abi: fix incorrect signature (#19881) The abi package already supports function overload by adding a suffix to the overloaded function name, but it uses the function name with suffix to calculate signature(both for the event and method). This PR fixes it by adding a new field named RawName, which can be used to calcuate all signatures but use Name to distinguish different overloaded function. --- accounts/abi/abi.go | 10 ++++---- accounts/abi/abi_test.go | 47 +++++++++++++++++++++++++---------- accounts/abi/bind/base.go | 6 ++--- accounts/abi/bind/bind.go | 4 +-- accounts/abi/bind/template.go | 18 +++++++------- accounts/abi/event.go | 38 +++++++++++++++++++++------- accounts/abi/event_test.go | 4 +-- accounts/abi/method.go | 23 +++++++++++++---- accounts/abi/pack_test.go | 14 +++++------ 9 files changed, 109 insertions(+), 55 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index cea58ae301..ee85b24fe8 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -72,7 +72,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { return nil, err } // Pack up the method ID too if not a constructor and return - return append(method.Id(), arguments...), nil + return append(method.ID(), arguments...), nil } // Unpack output in v according to the abi specification @@ -123,11 +123,9 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { Inputs []Argument Outputs []Argument } - if err := json.Unmarshal(data, &fields); err != nil { return err } - abi.Methods = make(map[string]Method) abi.Events = make(map[string]Event) for _, field := range fields { @@ -146,6 +144,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } abi.Methods[name] = Method{ Name: name, + RawName: field.Name, Const: field.Constant, Inputs: field.Inputs, Outputs: field.Outputs, @@ -159,6 +158,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } abi.Events[name] = Event{ Name: name, + RawName: field.Name, Anonymous: field.Anonymous, Inputs: field.Inputs, } @@ -175,7 +175,7 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata)) } for _, method := range abi.Methods { - if bytes.Equal(method.Id(), sigdata[:4]) { + if bytes.Equal(method.ID(), sigdata[:4]) { return &method, nil } } @@ -186,7 +186,7 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { // ABI and returns nil if none found. func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { for _, event := range abi.Events { - if bytes.Equal(event.Id().Bytes(), topic.Bytes()) { + if bytes.Equal(event.ID().Bytes(), topic.Bytes()) { return &event, nil } } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index efdfc03645..7f953c9e91 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -64,10 +64,10 @@ func TestReader(t *testing.T) { exp := ABI{ Methods: map[string]Method{ "balance": { - "balance", true, nil, nil, + "balance", "balance", true, nil, nil, }, "send": { - "send", false, []Argument{ + "send", "send", false, []Argument{ {"amount", Uint256, false}, }, nil, }, @@ -165,12 +165,10 @@ func TestTestSlice(t *testing.T) { if err != nil { t.Fatal(err) } - slice := make([]uint64, 2) if _, err := abi.Pack("uint64[2]", slice); err != nil { t.Error(err) } - if _, err := abi.Pack("uint64[]", slice); err != nil { t.Error(err) } @@ -178,19 +176,19 @@ func TestTestSlice(t *testing.T) { func TestMethodSignature(t *testing.T) { String, _ := NewType("string", nil) - m := Method{"foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} + m := Method{"foo", "foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} exp := "foo(string,string)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) } idexp := crypto.Keccak256([]byte(exp))[:4] - if !bytes.Equal(m.Id(), idexp) { - t.Errorf("expected ids to match %x != %x", m.Id(), idexp) + if !bytes.Equal(m.ID(), idexp) { + t.Errorf("expected ids to match %x != %x", m.ID(), idexp) } uintt, _ := NewType("uint256", nil) - m = Method{"foo", false, []Argument{{"bar", uintt, false}}, nil} + m = Method{"foo", "foo", false, []Argument{{"bar", uintt, false}}, nil} exp = "foo(uint256)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) @@ -209,13 +207,36 @@ func TestMethodSignature(t *testing.T) { {Name: "y", Type: "int256"}, }}, }) - m = Method{"foo", false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} + m = Method{"foo", "foo", false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} exp = "foo((int256,int256[],(int256,int256)[],(int256,int256)[2]),string)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) } } +func TestOverloadedMethodSignature(t *testing.T) { + json := `[{"constant":true,"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"i","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"}],"name":"bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"},{"indexed":false,"name":"j","type":"uint256"}],"name":"bar","type":"event"}]` + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + check := func(name string, expect string, method bool) { + if method { + if abi.Methods[name].Sig() != expect { + t.Fatalf("The signature of overloaded method mismatch, want %s, have %s", expect, abi.Methods[name].Sig()) + } + } else { + if abi.Events[name].Sig() != expect { + t.Fatalf("The signature of overloaded event mismatch, want %s, have %s", expect, abi.Events[name].Sig()) + } + } + } + check("foo", "foo(uint256,uint256)", true) + check("foo0", "foo(uint256)", true) + check("bar", "bar(uint256)", false) + check("bar0", "bar(uint256,uint256)", false) +} + func TestMultiPack(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata2)) if err != nil { @@ -907,13 +928,13 @@ func TestABI_MethodById(t *testing.T) { } for name, m := range abi.Methods { a := fmt.Sprintf("%v", m) - m2, err := abi.MethodById(m.Id()) + m2, err := abi.MethodById(m.ID()) if err != nil { t.Fatalf("Failed to look up ABI method: %v", err) } b := fmt.Sprintf("%v", m2) if a != b { - t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, hexutil.Encode(m.Id())) + t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, hexutil.Encode(m.ID())) } } // Also test empty @@ -1012,8 +1033,8 @@ func TestABI_EventById(t *testing.T) { t.Errorf("We should find a event for topic %s, test #%d", topicID.Hex(), testnum) } - if event.Id() != topicID { - t.Errorf("Event id %s does not match topic %s, test #%d", event.Id().Hex(), topicID.Hex(), testnum) + if event.ID() != topicID { + t.Errorf("Event id %s does not match topic %s, test #%d", event.ID().Hex(), topicID.Hex(), testnum) } unknowntopicID := crypto.Keccak256Hash([]byte("unknownEvent")) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 79c4fd5581..21fafefcf8 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -364,7 +364,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int opts = new(FilterOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].Id()}}, query...) + query = append([][]interface{}{{c.abi.Events[name].ID()}}, query...) topics, err := makeTopics(query...) if err != nil { @@ -410,7 +410,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter opts = new(WatchOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].Id()}}, query...) + query = append([][]interface{}{{c.abi.Events[name].ID()}}, query...) topics, err := makeTopics(query...) if err != nil { @@ -439,7 +439,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) if len(log.Topics) == 0 { return errNoEventSignature } - if log.Topics[0] != c.abi.Events[event].Id() { + if log.Topics[0] != c.abi.Events[event].ID() { return errors.New("event signature mismatch") } if len(log.Data) > 0 { diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 1301af300a..62bbf4e3ac 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -390,7 +390,7 @@ func formatMethod(method abi.Method, structs map[string]*tmplStruct) string { if method.Const { constant = "constant " } - return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) + return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) } // formatEvent transforms raw event representation into a user friendly one. @@ -403,5 +403,5 @@ func formatEvent(event abi.Event, structs map[string]*tmplStruct) string { inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name) } } - return fmt.Sprintf("event %v(%v)", event.Name, strings.Join(inputs, ", ")) + return fmt.Sprintf("event %v(%v)", event.RawName, strings.Join(inputs, ", ")) } diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index f941d595ad..78db7d7fd3 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -292,7 +292,7 @@ var ( {{end}} {{range .Calls}} - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { @@ -311,14 +311,14 @@ var ( return {{if .Structured}}*ret,{{else}}{{range $i, $_ := .Normalized.Outputs}}*ret{{$i}},{{end}}{{end}} err } - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { @@ -327,21 +327,21 @@ var ( {{end}} {{range .Transacts}} - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) } - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.Id}}. + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatmethod .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { @@ -420,7 +420,7 @@ var ( Raw types.Log // Blockchain specific contextual infos } - // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.Id}}. + // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatevent .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { @@ -437,7 +437,7 @@ var ( return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil } - // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.Id}}. + // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. // // Solidity: {{formatevent .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { @@ -479,7 +479,7 @@ var ( }), nil } - // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.Id}}. + // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. // // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { diff --git a/accounts/abi/event.go b/accounts/abi/event.go index b64e62aafc..3292caf8c3 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -28,7 +28,18 @@ import ( // holds type information (inputs) about the yielded output. Anonymous events // don't get the signature canonical representation as the first LOG topic. type Event struct { - Name string + // Name is the event name used for internal representation. It's derived from + // the raw name and a suffix will be added in the case of a event overload. + // + // e.g. + // There are two events have same name: + // * foo(int,int) + // * foo(uint,uint) + // The event name of the first one wll be resolved as foo while the second one + // will be resolved as foo0. + Name string + // RawName is the raw event name parsed from ABI. + RawName string Anonymous bool Inputs Arguments } @@ -41,17 +52,26 @@ func (e Event) String() string { inputs[i] = fmt.Sprintf("%v indexed %v", input.Type, input.Name) } } - return fmt.Sprintf("event %v(%v)", e.Name, strings.Join(inputs, ", ")) + return fmt.Sprintf("event %v(%v)", e.RawName, strings.Join(inputs, ", ")) } -// Id returns the canonical representation of the event's signature used by the -// abi definition to identify event names and types. -func (e Event) Id() common.Hash { +// Sig returns the event string signature according to the ABI spec. +// +// Example +// +// event foo(uint32 a, int b) = "foo(uint32,int256)" +// +// Please note that "int" is substitute for its canonical representation "int256" +func (e Event) Sig() string { types := make([]string, len(e.Inputs)) - i := 0 - for _, input := range e.Inputs { + for i, input := range e.Inputs { types[i] = input.Type.String() - i++ } - return common.BytesToHash(crypto.Keccak256([]byte(fmt.Sprintf("%v(%v)", e.Name, strings.Join(types, ","))))) + return fmt.Sprintf("%v(%v)", e.RawName, strings.Join(types, ",")) +} + +// ID returns the canonical representation of the event's signature used by the +// abi definition to identify event names and types. +func (e Event) ID() common.Hash { + return common.BytesToHash(crypto.Keccak256([]byte(e.Sig()))) } diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index ee77108f80..23ee920480 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -104,8 +104,8 @@ func TestEventId(t *testing.T) { } for name, event := range abi.Events { - if event.Id() != test.expectations[name] { - t.Errorf("expected id to be %x, got %x", test.expectations[name], event.Id()) + if event.ID() != test.expectations[name] { + t.Errorf("expected id to be %x, got %x", test.expectations[name], event.ID()) } } } diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 6037ddf220..7acbd4847e 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -32,7 +32,18 @@ import ( // be flagged `false`. // Input specifies the required input parameters for this gives method. type Method struct { - Name string + // Name is the method name used for internal representation. It's derived from + // the raw name and a suffix will be added in the case of a function overload. + // + // e.g. + // There are two functions have same name: + // * foo(int,int) + // * foo(uint,uint) + // The method name of the first one will be resolved as foo while the second one + // will be resolved as foo0. + Name string + // RawName is the raw method name parsed from ABI. + RawName string Const bool Inputs Arguments Outputs Arguments @@ -42,7 +53,7 @@ type Method struct { // // Example // -// function foo(uint32 a, int b) = "foo(uint32,int256)" +// function foo(uint32 a, int b) = "foo(uint32,int256)" // // Please note that "int" is substitute for its canonical representation "int256" func (method Method) Sig() string { @@ -50,7 +61,7 @@ func (method Method) Sig() string { for i, input := range method.Inputs { types[i] = input.Type.String() } - return fmt.Sprintf("%v(%v)", method.Name, strings.Join(types, ",")) + return fmt.Sprintf("%v(%v)", method.RawName, strings.Join(types, ",")) } func (method Method) String() string { @@ -69,9 +80,11 @@ func (method Method) String() string { if method.Const { constant = "constant " } - return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.Name, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) + return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) } -func (method Method) Id() []byte { +// ID returns the canonical representation of the method's signature used by the +// abi definition to identify method names and types. +func (method Method) ID() []byte { return crypto.Keccak256([]byte(method.Sig()))[:4] } diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index 8adff04a83..4e93e6153c 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -633,7 +633,7 @@ func TestMethodPack(t *testing.T) { t.Fatal(err) } - sig := abi.Methods["slice"].Id() + sig := abi.Methods["slice"].ID() sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -647,7 +647,7 @@ func TestMethodPack(t *testing.T) { } var addrA, addrB = common.Address{1}, common.Address{2} - sig = abi.Methods["sliceAddress"].Id() + sig = abi.Methods["sliceAddress"].ID() sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) @@ -662,7 +662,7 @@ func TestMethodPack(t *testing.T) { } var addrC, addrD = common.Address{3}, common.Address{4} - sig = abi.Methods["sliceMultiAddress"].Id() + sig = abi.Methods["sliceMultiAddress"].ID() sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -680,7 +680,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["slice256"].Id() + sig = abi.Methods["slice256"].ID() sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -694,7 +694,7 @@ func TestMethodPack(t *testing.T) { } a := [2][2]*big.Int{{big.NewInt(1), big.NewInt(1)}, {big.NewInt(2), big.NewInt(0)}} - sig = abi.Methods["nestedArray"].Id() + sig = abi.Methods["nestedArray"].ID() sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -711,7 +711,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["nestedArray2"].Id() + sig = abi.Methods["nestedArray2"].ID() sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x80}, 32)...) @@ -727,7 +727,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["nestedSlice"].Id() + sig = abi.Methods["nestedSlice"].ID() sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x02}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) From 6a7b539c0e273366d1016921b103bcd5184e1920 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 083/280] accounts, internal/ethapi: use common Accounts method (#18428) * accounts/mananger, internal/ethapi/api: Add new function AllAccounts on account manager to remove the duplication code on getting all wallets accounts * Rename to Accounts * Rename to AllAccounts --- accounts/manager.go | 15 +++++++++++++++ internal/ethapi/api.go | 16 ++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/accounts/manager.go b/accounts/manager.go index 200260cabc..f4f40bff88 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -21,6 +21,7 @@ import ( "sort" "sync" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/event" ) @@ -162,6 +163,20 @@ func (am *Manager) Wallet(url string) (Wallet, error) { return nil, ErrUnknownWallet } +// Accounts returns all account addresses of all wallets within the account manager +func (am *Manager) Accounts() []common.Address { + am.lock.RLock() + defer am.lock.RUnlock() + + addresses := make([]common.Address, 0) // return [] instead of nil if empty + for _, wallet := range am.wallets { + for _, account := range wallet.Accounts() { + addresses = append(addresses, account.Address) + } + } + return addresses +} + // Find attempts to locate the wallet corresponding to a specific account. Since // accounts can be dynamically added to and removed from wallets, this method has // a linear runtime in the number of wallets. diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 867c9e2d87..99221c9745 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -284,13 +284,7 @@ func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { // Accounts returns the collection of accounts this node manages func (s *PublicAccountAPI) Accounts() []common.Address { - addresses := make([]common.Address, 0) // return [] instead of nil if empty - for _, wallet := range s.am.Wallets() { - for _, account := range wallet.Accounts() { - addresses = append(addresses, account.Address) - } - } - return addresses + return s.am.Accounts() } // PrivateAccountAPI provides an API to access accounts managed by this node. @@ -313,13 +307,7 @@ func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { // ListAccounts will return a list of addresses for accounts this node manages. func (s *PrivateAccountAPI) ListAccounts() []common.Address { - addresses := make([]common.Address, 0) // return [] instead of nil if empty - for _, wallet := range s.am.Wallets() { - for _, account := range wallet.Accounts() { - addresses = append(addresses, account.Address) - } - } - return addresses + return s.am.Accounts() } // rawWallet is a JSON representation of an accounts.Wallet interface, with its From e90df44b43cf2bc5bef652bcbdedda4f3bcec52a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 084/280] accounts: replace passPHRASE with passWORD in any user interactions (#19932) --- accounts/errors.go | 2 +- accounts/keystore/keystore.go | 2 +- accounts/keystore/plain_test.go | 2 +- accounts/keystore/testdata/keystore/README | 2 +- cmd/XDC/accountcmd_test.go | 6 +++--- cmd/puppeth/wizard_faucet.go | 2 +- cmd/puppeth/wizard_node.go | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/accounts/errors.go b/accounts/errors.go index 40b21ed179..2fed35f9d0 100644 --- a/accounts/errors.go +++ b/accounts/errors.go @@ -35,7 +35,7 @@ var ErrNotSupported = errors.New("not supported") // ErrInvalidPassphrase is returned when a decryption operation receives a bad // passphrase. -var ErrInvalidPassphrase = errors.New("invalid passphrase") +var ErrInvalidPassphrase = errors.New("invalid password") // ErrWalletAlreadyOpen is returned if a wallet is attempted to be opened the // second time. diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 0f146a44d4..0ed77522e8 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -42,7 +42,7 @@ import ( var ( ErrLocked = accounts.NewAuthNeededError("password or unlock") ErrNoMatch = errors.New("no key for given address or file") - ErrDecrypt = errors.New("could not decrypt key with given passphrase") + ErrDecrypt = errors.New("could not decrypt key with given password") ) // KeyStoreType is the reflect type of a keystore backend. diff --git a/accounts/keystore/plain_test.go b/accounts/keystore/plain_test.go index a42c75c4ad..b7c0f5b3a5 100644 --- a/accounts/keystore/plain_test.go +++ b/accounts/keystore/plain_test.go @@ -95,7 +95,7 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) { t.Fatal(err) } if _, err = ks.GetKey(k1.Address, account.URL.Path, "bar"); err != ErrDecrypt { - t.Fatalf("wrong error for invalid passphrase\ngot %q\nwant %q", err, ErrDecrypt) + t.Fatalf("wrong error for invalid password\ngot %q\nwant %q", err, ErrDecrypt) } } diff --git a/accounts/keystore/testdata/keystore/README b/accounts/keystore/testdata/keystore/README index c489123c26..0d4ec3f090 100644 --- a/accounts/keystore/testdata/keystore/README +++ b/accounts/keystore/testdata/keystore/README @@ -1,5 +1,5 @@ This directory contains accounts for testing. -The passphrase that unlocks them is "foobar". +The password that unlocks them is "foobar". The "good" key files which are supposed to be loadable are: diff --git a/cmd/XDC/accountcmd_test.go b/cmd/XDC/accountcmd_test.go index dad6b45b69..9bd57a350f 100644 --- a/cmd/XDC/accountcmd_test.go +++ b/cmd/XDC/accountcmd_test.go @@ -175,7 +175,7 @@ func TestWalletImportBadPassword(t *testing.T) { XDC.Expect(` !! Unsupported terminal, password will be echoed. Passphrase: {{.InputLine "wrong"}} -Fatal: could not decrypt key with given passphrase +Fatal: could not decrypt key with given password `) } @@ -219,7 +219,7 @@ Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3 Passphrase: {{.InputLine "wrong2"}} Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3 Passphrase: {{.InputLine "wrong3"}} -Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given passphrase) +Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given password) `) } @@ -281,7 +281,7 @@ func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) { "--password", "testdata/wrong-passwords.txt", "--unlock", "0,2") defer XDC.ExpectExit() XDC.Expect(` -Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase) +Fatal: Failed to unlock account 0 (could not decrypt key with given password) `) } diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go index 5c145d5447..e449067e49 100644 --- a/cmd/puppeth/wizard_faucet.go +++ b/cmd/puppeth/wizard_faucet.go @@ -147,7 +147,7 @@ func (w *wizard) deployFaucet() { infos.node.keyPass = w.readPassword() if _, err := keystore.DecryptKey([]byte(infos.node.keyJSON), infos.node.keyPass); err != nil { - log.Error("Failed to decrypt key with given passphrase") + log.Error("Failed to decrypt key with given password") infos.node.keyJSON = "" infos.node.keyPass = "" } diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go index 13c9efb9f6..a1d4d12722 100644 --- a/cmd/puppeth/wizard_node.go +++ b/cmd/puppeth/wizard_node.go @@ -142,7 +142,7 @@ func (w *wizard) deployNode(boot bool) { infos.keyPass = w.readPassword() if _, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil { - log.Error("Failed to decrypt key with given passphrase") + log.Error("Failed to decrypt key with given password") return } } From 32615fda97012d810fbc81ac7c364db3e92d1a16 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 085/280] accounts/abi: add internalType information and fix issues (#20179) * accounts/abi: fix various issues The fixed issues include: (1) If there is no return in a call function, unpack should return nil error (2) For some functions which have struct array as parameter, it will also be detected and generate the struct definition (3) For event, if it has non-indexed parameter, the parameter name will also be assigned if empty. Also the internal struct will be detected and generate struct defition if not exist. (4) Fix annotation generation in event function * accounts/abi: add new abi field internalType * accounts: address comments and add tests * accounts/abi: replace strings.ReplaceAll with strings.Replace --- accounts/abi/abi.go | 8 +---- accounts/abi/abi_test.go | 14 ++++---- accounts/abi/argument.go | 26 ++++++++++---- accounts/abi/bind/bind.go | 59 ++++++++++++++++++++++++-------- accounts/abi/bind/template.go | 4 +-- accounts/abi/bind/topics.go | 13 ++++--- accounts/abi/bind/topics_test.go | 2 +- accounts/abi/pack_test.go | 2 +- accounts/abi/type.go | 25 +++++++++++--- accounts/abi/type_test.go | 4 +-- accounts/abi/unpack_test.go | 34 ++++++++++++++++-- 11 files changed, 139 insertions(+), 52 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index ee85b24fe8..3201ef0bc2 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -77,9 +77,6 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { // Unpack output in v according to the abi specification func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { - if len(data) == 0 { - return errors.New("abi: unmarshalling empty output") - } // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event if method, ok := abi.Methods[name]; ok { @@ -96,9 +93,6 @@ func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { // UnpackIntoMap unpacks a log into the provided map[string]interface{} func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) { - if len(data) == 0 { - return fmt.Errorf("abi: unmarshalling empty output") - } // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event if method, ok := abi.Methods[name]; ok { @@ -207,7 +201,7 @@ func UnpackRevert(data []byte) (string, error) { if !bytes.Equal(data[:4], revertSelector) { return "", errors.New("invalid data for unpacking") } - typ, _ := NewType("string", nil) + typ, _ := NewType("string", "", nil) unpacked, err := (Arguments{{Type: typ}}).Unpack2(data[4:]) if err != nil { return "", err diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 7f953c9e91..070f012889 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -60,7 +60,7 @@ const jsondata2 = ` ]` func TestReader(t *testing.T) { - Uint256, _ := NewType("uint256", nil) + Uint256, _ := NewType("uint256", "", nil) exp := ABI{ Methods: map[string]Method{ "balance": { @@ -175,7 +175,7 @@ func TestTestSlice(t *testing.T) { } func TestMethodSignature(t *testing.T) { - String, _ := NewType("string", nil) + String, _ := NewType("string", "", nil) m := Method{"foo", "foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} exp := "foo(string,string)" if m.Sig() != exp { @@ -187,7 +187,7 @@ func TestMethodSignature(t *testing.T) { t.Errorf("expected ids to match %x != %x", m.ID(), idexp) } - uintt, _ := NewType("uint256", nil) + uintt, _ := NewType("uint256", "", nil) m = Method{"foo", "foo", false, []Argument{{"bar", uintt, false}}, nil} exp = "foo(uint256)" if m.Sig() != exp { @@ -195,7 +195,7 @@ func TestMethodSignature(t *testing.T) { } // Method with tuple arguments - s, _ := NewType("tuple", []ArgumentMarshaling{ + s, _ := NewType("tuple", "", []ArgumentMarshaling{ {Name: "a", Type: "int256"}, {Name: "b", Type: "int256[]"}, {Name: "c", Type: "tuple[]", Components: []ArgumentMarshaling{ @@ -606,9 +606,9 @@ func TestBareEvents(t *testing.T) { { "type" : "event", "name" : "tuple", "inputs" : [{ "indexed":false, "name":"t", "type":"tuple", "components":[{"name":"a", "type":"uint256"}] }, { "indexed":true, "name":"arg1", "type":"address" }] } ]` - arg0, _ := NewType("uint256", nil) - arg1, _ := NewType("address", nil) - tuple, _ := NewType("tuple", []ArgumentMarshaling{{Name: "a", Type: "uint256"}}) + arg0, _ := NewType("uint256", "", nil) + arg1, _ := NewType("address", "", nil) + tuple, _ := NewType("tuple", "", []ArgumentMarshaling{{Name: "a", Type: "uint256"}}) expectedEvents := map[string]struct { Anonymous bool diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 8cfa8db1a9..760254201e 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -35,10 +35,11 @@ type Argument struct { type Arguments []Argument type ArgumentMarshaling struct { - Name string - Type string - Components []ArgumentMarshaling - Indexed bool + Name string + Type string + InternalType string + Components []ArgumentMarshaling + Indexed bool } // UnmarshalJSON implements json.Unmarshaler interface @@ -49,7 +50,7 @@ func (argument *Argument) UnmarshalJSON(data []byte) error { return fmt.Errorf("argument json err: %v", err) } - argument.Type, err = NewType(arg.Type, arg.Components) + argument.Type, err = NewType(arg.Type, arg.InternalType, arg.Components) if err != nil { return err } @@ -89,6 +90,13 @@ func (arguments Arguments) isTuple() bool { // Unpack performs the operation hexdata -> Go format func (arguments Arguments) Unpack(v interface{}, data []byte) error { + if len(data) == 0 { + if len(arguments) != 0 { + return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") + } else { + return nil // Nothing to unmarshal, return + } + } // make sure the passed value is arguments pointer if reflect.Ptr != reflect.ValueOf(v).Kind() { return fmt.Errorf("abi: Unpack(non-pointer %T)", v) @@ -116,11 +124,17 @@ func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { // UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { + if len(data) == 0 { + if len(arguments) != 0 { + return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") + } else { + return nil // Nothing to unmarshal, return + } + } marshalledValues, err := arguments.UnpackValues(data) if err != nil { return err } - return arguments.unpackIntoMap(v, marshalledValues) } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 62bbf4e3ac..d0ffb40aa9 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -83,7 +83,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if input.Name == "" { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } - if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist { + if hasStruct(input.Type) { bindStructType[lang](input.Type, structs) } } @@ -93,7 +93,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] if output.Name != "" { normalized.Outputs[j].Name = capitalise(output.Name) } - if _, exist := structs[output.Type.String()]; output.Type.T == abi.TupleTy && !exist { + if hasStruct(output.Type) { bindStructType[lang](output.Type, structs) } } @@ -116,14 +116,11 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { - // Indexed fields are input, non-indexed ones are outputs - if input.Indexed { - if input.Name == "" { - normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) - } - if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist { - bindStructType[lang](input.Type, structs) - } + if input.Name == "" { + normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) + } + if hasStruct(input.Type) { + bindStructType[lang](input.Type, structs) } } // Append the event to the accumulator list @@ -235,7 +232,7 @@ func bindBasicTypeGo(kind abi.Type) string { func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: - return structs[kind.String()].Name + return structs[kind.TupleRawName+kind.String()].Name case abi.ArrayTy: return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs) case abi.SliceTy: @@ -255,6 +252,13 @@ var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) // funcionality as for simple types, but dynamic types get converted to hashes. func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { bound := bindTypeGo(kind, structs) + + // todo(rjl493456442) according solidity documentation, indexed event + // parameters that are not value types i.e. arrays and structs are not + // stored directly but instead a keccak256-hash of an encoding is stored. + // + // We only convert stringS and bytes to hash, still need to deal with + // array(both fixed-size and dynamic-size) and struct. if bound == "string" || bound == "[]byte" { bound = "common.Hash" } @@ -273,7 +277,14 @@ var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: - if s, exist := structs[kind.String()]; exist { + // We compose raw struct name and canonical parameter expression + // together here. The reason is before solidity v0.5.11, kind.TupleRawName + // is empty, so we use canonical parameter expression to distinguish + // different struct definition. From the consideration of backward + // compatibility, we concat these two together so that if kind.TupleRawName + // is not empty, it can have unique id. + id := kind.TupleRawName + kind.String() + if s, exist := structs[id]; exist { return s.Name } var fields []*tmplField @@ -281,8 +292,11 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { field := bindStructTypeGo(*elem, structs) fields = append(fields, &tmplField{Type: field, Name: capitalise(kind.TupleRawNames[i]), SolKind: *elem}) } - name := fmt.Sprintf("Struct%d", len(structs)) - structs[kind.String()] = &tmplStruct{ + name := kind.TupleRawName + if name == "" { + name = fmt.Sprintf("Struct%d", len(structs)) + } + structs[id] = &tmplStruct{ Name: name, Fields: fields, } @@ -346,6 +360,21 @@ func structured(args abi.Arguments) bool { return true } +// hasStruct returns an indicator whether the given type is struct, struct slice +// or struct array. +func hasStruct(t abi.Type) bool { + switch t.T { + case abi.SliceTy: + return hasStruct(*t.Elem) + case abi.ArrayTy: + return hasStruct(*t.Elem) + case abi.TupleTy: + return true + default: + return false + } +} + // resolveArgName converts a raw argument representation into a user friendly format. func resolveArgName(arg abi.Argument, structs map[string]*tmplStruct) string { var ( @@ -361,7 +390,7 @@ loop: case abi.ArrayTy: prefix += fmt.Sprintf("[%d]", typ.Size) default: - embedded = typ.String() + embedded = typ.TupleRawName + typ.String() break loop } typ = typ.Elem diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 78db7d7fd3..3a0c7bf5a9 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -65,7 +65,7 @@ type tmplField struct { // tmplStruct is a wrapper around an abi.tuple contains a auto-generated // struct name. type tmplStruct struct { - Name string // Auto-generated struct name(We can't obtain the raw struct name through abi) + Name string // Auto-generated struct name(before solidity v0.5.11) or raw name. Fields []*tmplField // Struct fields definition depends on the binding language. } @@ -481,7 +481,7 @@ var ( // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{.Original.String}} + // Solidity: {{formatevent .Original $structs}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { event := new({{$contract.Type}}{{.Normalized.Name}}) if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index 17265c9e14..0b35a2d4b7 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -80,15 +80,19 @@ func makeTopics(query ...[]interface{}) ([][]common.Hash, error) { copy(topic[:], hash[:]) default: + // todo(rjl493456442) according solidity documentation, indexed event + // parameters that are not value types i.e. arrays and structs are not + // stored directly but instead a keccak256-hash of an encoding is stored. + // + // We only convert stringS and bytes to hash, still need to deal with + // array(both fixed-size and dynamic-size) and struct. + // Attempt to generate the topic from funky types 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[:val.Len()]), val) - default: return nil, fmt.Errorf("unsupported indexed type: %T", rule) } @@ -162,6 +166,7 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er default: // Ran out of plain primitive types, try custom types + switch field.Type() { case reflectHash: // Also covers all dynamic types field.Set(reflect.ValueOf(topics[0])) @@ -178,11 +183,9 @@ 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][: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 index 2bc1329482..cb2502554f 100644 --- a/accounts/abi/bind/topics_test.go +++ b/accounts/abi/bind/topics_test.go @@ -59,7 +59,7 @@ func TestParseTopics(t *testing.T) { type bytesStruct struct { StaticBytes [5]byte } - bytesType, _ := abi.NewType("bytes5", nil) + bytesType, _ := abi.NewType("bytes5", "", nil) type args struct { createObj func() interface{} resultObj func() interface{} diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index 4e93e6153c..92b8a7c187 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -612,7 +612,7 @@ func TestPack(t *testing.T) { "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].A[1] }, } { - typ, err := NewType(test.typ, test.components) + typ, err := NewType(test.typ, "", test.components) if err != nil { t.Fatalf("%v failed. Unexpected parse error: %v", i, err) } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 0b15dcc401..6fe0b6e059 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -53,6 +53,7 @@ type Type struct { stringKind string // holds the unparsed string for deriving signatures // Tuple relative fields + TupleRawName string // Raw struct name defined in source code, may be empty. TupleElems []*Type // Type information of all tuple fields TupleRawNames []string // Raw field name of all tuple fields } @@ -63,7 +64,7 @@ var ( ) // NewType creates a new reflection type of abi type given in t. -func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { +func NewType(t string, internalType string, components []ArgumentMarshaling) (typ Type, err error) { // check that array brackets are equal if they exist if strings.Count(t, "[") != strings.Count(t, "]") { return Type{}, errors.New("invalid arg type in abi") @@ -73,9 +74,14 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { // if there are brackets, get ready to go into slice/array mode and // recursively create the type if strings.Count(t, "[") != 0 { - i := strings.LastIndex(t, "[") + // Note internalType can be empty here. + subInternal := internalType + if i := strings.LastIndex(internalType, "["); i != -1 { + subInternal = subInternal[:i] + } // recursively embed the type - embeddedType, err := NewType(t[:i], components) + i := strings.LastIndex(t, "[") + embeddedType, err := NewType(t[:i], subInternal, components) if err != nil { return Type{}, err } @@ -172,7 +178,7 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { ) expression += "(" for idx, c := range components { - cType, err := NewType(c.Type, c.Components) + cType, err := NewType(c.Type, c.InternalType, c.Components) if err != nil { return Type{}, err } @@ -198,6 +204,17 @@ func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) { typ.TupleRawNames = names typ.T = TupleTy typ.stringKind = expression + + const structPrefix = "struct " + // After solidity 0.5.10, a new field of abi "internalType" + // is introduced. From that we can obtain the struct name + // user defined in the source code. + if internalType != "" && strings.HasPrefix(internalType, structPrefix) { + // Foo.Bar type definition is not allowed in golang, + // convert the format to FooBar + typ.TupleRawName = strings.Replace(internalType[len(structPrefix):], ".", "", -1) + } + case "function": typ.Kind = reflect.Array typ.T = FunctionTy diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index 2f663d51d7..8ff3d46b5a 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -106,7 +106,7 @@ func TestTypeRegexp(t *testing.T) { } for _, tt := range tests { - typ, err := NewType(tt.blob, tt.components) + typ, err := NewType(tt.blob, "", tt.components) if err != nil { t.Errorf("type %q: failed to parse type string: %v", tt.blob, err) } @@ -281,7 +281,7 @@ func TestTypeCheck(t *testing.T) { B *big.Int }{{big.NewInt(0), big.NewInt(0)}, {big.NewInt(0), big.NewInt(0)}}, ""}, } { - typ, err := NewType(test.typ, test.components) + typ, err := NewType(test.typ, "", test.components) if err != nil && len(test.err) == 0 { t.Fatal("unexpected parse error:", err) } else if err != nil && len(test.err) != 0 { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 391927dc8b..8be43b44d9 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -51,6 +51,7 @@ func (test unpackTest) checkError(err error) error { } var unpackTests = []unpackTest{ + // Bools { def: `[{ "type": "bool" }]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", @@ -73,6 +74,7 @@ var unpackTests = []unpackTest{ want: false, err: "abi: improperly encoded boolean value", }, + // Integers { def: `[{"type": "uint32"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", @@ -122,11 +124,13 @@ var unpackTests = []unpackTest{ enc: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", want: big.NewInt(-1), }, + // Address { def: `[{"type": "address"}]`, enc: "0000000000000000000000000100000000000000000000000000000000000000", want: common.Address{1}, }, + // Bytes { def: `[{"type": "bytes32"}]`, enc: "0100000000000000000000000000000000000000000000000000000000000000", @@ -154,23 +158,39 @@ var unpackTests = []unpackTest{ enc: "0100000000000000000000000000000000000000000000000000000000000000", want: [32]byte{1, 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}, }, + // Functions { def: `[{"type": "function"}]`, enc: "0100000000000000000000000000000000000000000000000000000000000000", want: [24]byte{1}, }, - // slices + // Slice and Array { def: `[{"type": "uint8[]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: []uint8{1, 2}, }, + { + def: `[{"type": "uint8[]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", + want: []uint8{}, + }, + { + def: `[{"type": "uint256[]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", + want: []*big.Int{}, + }, { def: `[{"type": "uint8[2]"}]`, enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: [2]uint8{1, 2}, }, // multi dimensional, if these pass, all types that don't require length prefix should pass + { + def: `[{"type": "uint8[][]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", + want: [][]uint8{}, + }, { def: `[{"type": "uint8[][]"}]`, enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", @@ -186,11 +206,21 @@ var unpackTests = []unpackTest{ enc: "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", want: [2][2]uint8{{1, 2}, {1, 2}}, }, + { + def: `[{"type": "uint8[][2]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + want: [2][]uint8{{}, {}}, + }, { def: `[{"type": "uint8[][2]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", want: [2][]uint8{{1}, {1}}, }, + { + def: `[{"type": "uint8[2][]"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", + want: [][2]uint8{}, + }, { def: `[{"type": "uint8[2][]"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", @@ -420,7 +450,7 @@ func TestUnpack(t *testing.T) { } encb, err := hex.DecodeString(test.enc) if err != nil { - t.Fatalf("invalid hex: %s" + test.enc) + t.Fatalf("invalid hex %s: %v", test.enc, err) } outptr := reflect.New(reflect.TypeOf(test.want)) err = abi.Unpack(outptr.Interface(), "method", encb) From 3a320d2c6f634b5c8387452fd7a8dcd35bd1ce55 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH 086/280] accounts/abi/bind, cmd/abigen: implement alias for abigen (#20244) --- accounts/abi/bind/bind.go | 41 ++++++++++++++++++--- accounts/abi/bind/bind_test.go | 66 +++++++++++++++++++++++++++++++++- cmd/abigen/main.go | 31 ++++++++++++---- 3 files changed, 127 insertions(+), 11 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index d0ffb40aa9..6a28ad0f77 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -44,7 +44,7 @@ const ( // to be used as is in client code, but rather as an intermediate struct which // enforces compile time type safety and naming convention opposed to having to // manually maintain hard coded strings that break on runtime. -func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string) (string, error) { +func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) { // Process each individual contract requested binding contracts := make(map[string]*tmplContract) @@ -71,12 +71,29 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] transacts = make(map[string]*tmplMethod) events = make(map[string]*tmplEvent) structs = make(map[string]*tmplStruct) + + // identifiers are used to detect duplicated identifier of function + // and event. For all calls, transacts and events, abigen will generate + // corresponding bindings. However we have to ensure there is no + // identifier coliision in the bindings of these categories. + callIdentifiers = make(map[string]bool) + transactIdentifiers = make(map[string]bool) + eventIdentifiers = make(map[string]bool) ) for _, original := range evmABI.Methods { // Normalize the method for capital cases and non-anonymous inputs/outputs normalized := original - normalized.Name = methodNormalizer[lang](original.Name) - + normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + // Ensure there is no duplicated identifier + var identifiers = callIdentifiers + if !original.Const { + identifiers = transactIdentifiers + } + if identifiers[normalizedName] { + return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName) + } + identifiers[normalizedName] = true + normalized.Name = normalizedName normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { @@ -111,7 +128,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] } // Normalize the event for capital cases and non-anonymous outputs normalized := original - normalized.Name = methodNormalizer[lang](original.Name) + + // Ensure there is no duplicated identifier + normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + if eventIdentifiers[normalizedName] { + return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName) + } + eventIdentifiers[normalizedName] = true + normalized.Name = normalizedName normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) @@ -316,6 +340,15 @@ var namedType = map[Lang]func(string, abi.Type) string{ LangGo: func(string, abi.Type) string { panic("this shouldn't be needed") }, } +// alias returns an alias of the given string based on the aliasing rules +// or returns itself if no rule is matched. +func alias(aliases map[string]string, n string) string { + if alias, exist := aliases[n]; exist { + return alias + } + return n +} + // methodNormalizer is a name transformer that modifies Solidity method names to // conform to target language naming concentions. var methodNormalizer = map[Lang]func(string) string{ diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 244fa5c287..d6b35156ea 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -38,6 +38,7 @@ var bindTests = []struct { tester string fsigs []map[string]string libs map[string]string + aliases map[string]string types []string }{ // Test that the binding is available in combined and separate forms too @@ -61,6 +62,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Test that all the official sample contracts bind correctly { @@ -77,6 +79,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, { `Crowdsale`, @@ -92,6 +95,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, { `DAO`, @@ -107,6 +111,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Test that named and anonymous inputs are handled correctly { @@ -143,6 +148,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Test that named and anonymous outputs are handled correctly { @@ -182,6 +188,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that named, anonymous and indexed events are handled correctly { @@ -250,6 +257,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Test that contract interactions (deploy, transact and call) generate working code { @@ -312,6 +320,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that plain values can be properly returned and deserialized { @@ -358,6 +367,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that tuples can be properly returned and deserialized { @@ -404,6 +414,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that arrays/slices can be properly returned and deserialized. // Only addresses are tested, remainder just compiled to keep the test small. @@ -462,6 +473,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that anonymous default methods can be correctly invoked { @@ -513,6 +525,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that non-existent contracts are reported as such (though only simulator test) { @@ -552,6 +565,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that gas estimation works for contracts with weird gas mechanics too. { @@ -608,6 +622,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Test that constant functions can be called from an (optional) specified address { @@ -663,6 +678,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that methods and returns with underscores inside work correctly. { @@ -743,6 +759,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, // Tests that logs can be successfully filtered and decoded. { @@ -965,6 +982,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, { `DeeplyNestedArray`, @@ -1046,6 +1064,7 @@ var bindTests = []struct { nil, nil, nil, + nil, }, { `CallbackParam`, @@ -1088,6 +1107,51 @@ var bindTests = []struct { }, nil, nil, + nil, + }, + { + "IdentifierCollision", + ` + pragma solidity >=0.4.19 <0.6.0; + + contract IdentifierCollision { + uint public _myVar; + + function MyVar() public view returns (uint) { + return _myVar; + } + } + `, + []string{"60806040523480156100115760006000fd5b50610017565b60c3806100256000396000f3fe608060405234801560105760006000fd5b506004361060365760003560e01c806301ad4d8714603c5780634ef1f0ad146058576036565b60006000fd5b60426074565b6040518082815260200191505060405180910390f35b605e607d565b6040518082815260200191505060405180910390f35b60006000505481565b60006000600050549050608b565b9056fea265627a7a7231582067c8d84688b01c4754ba40a2a871cede94ea1f28b5981593ab2a45b46ac43af664736f6c634300050c0032"}, + []string{`[{"constant":true,"inputs":[],"name":"MyVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_myVar","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]`}, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Initialize test accounts + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + // Deploy registrar contract + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + transactOpts := bind.NewKeyedTransactor(key) + _, _, _, err := DeployIdentifierCollision(transactOpts, sim) + if err != nil { + t.Fatalf("failed to deploy contract: %v", err) + } + `, + nil, + nil, + map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar + nil, }, } @@ -1120,7 +1184,7 @@ func TestGolangBindings(t *testing.T) { types = []string{tt.name} } // Generate the binding and create a Go source file in the workspace - bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs) + bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs, tt.aliases) if err != nil { t.Fatalf("test %d: failed to generate binding: %v", i, err) } diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 43cfdab6ab..a20d75e202 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "os" + "regexp" "strings" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" @@ -74,6 +75,10 @@ var ( Usage: "Destination language for the bindings (go)", Value: "go", } + aliasFlag = &cli.StringFlag{ + Name: "alias", + Usage: "Comma separated aliases for function and event renaming, e.g. foo=bar", + } ) func init() { @@ -88,6 +93,7 @@ func init() { pkgFlag, outFlag, langFlag, + aliasFlag, } app.Action = abigen } @@ -110,11 +116,12 @@ func abigen(c *cli.Context) error { } // If the entire solidity code was specified, build and bind based on that var ( - abis []string - bins []string - types []string - sigs []map[string]string - libs = make(map[string]string) + abis []string + bins []string + types []string + sigs []map[string]string + libs = make(map[string]string) + aliases = make(map[string]string) ) if c.String(abiFlag.Name) != "" { // Load up the ABI, optional bytecode and type name from the parameters @@ -186,8 +193,20 @@ func abigen(c *cli.Context) error { libs[libPattern] = nameParts[len(nameParts)-1] } } + // Extract all aliases from the flags + if c.IsSet(aliasFlag.Name) { + // We support multi-versions for aliasing + // e.g. + // foo=bar,foo2=bar2 + // foo:bar,foo2:bar2 + re := regexp.MustCompile(`(?:(\w+)[:=](\w+))`) + submatches := re.FindAllStringSubmatch(c.String(aliasFlag.Name), -1) + for _, match := range submatches { + aliases[match[1]] = match[2] + } + } // Generate the contract binding - code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs) + code, err := bind.Bind(types, abis, bins, sigs, c.String(pkgFlag.Name), lang, libs, aliases) if err != nil { utils.Fatalf("Failed to generate ABI binding: %v", err) } From 575a5cb2e297753b82d8de44c12c6ea52567870c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 087/280] accounts/abi/bind/backends: remove unused assignment (#20359) --- accounts/abi/bind/backends/simulated_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 16728b0996..5ff57db4c6 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -75,14 +75,13 @@ func TestSimulatedBackend(t *testing.T) { } sim.Commit() - tx, isPending, err = sim.TransactionByHash(context.Background(), txHash) + _, isPending, err = sim.TransactionByHash(context.Background(), txHash) if err != nil { t.Fatalf("error getting transaction with hash: %v", txHash.String()) } if isPending { t.Fatal("transaction should not have pending status") } - } func TestSimulatedBackend_EstimateGas(t *testing.T) { From eb628a4f0268c3d8f5e8c1a2b88ec43a1fe3d9ac Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 088/280] accounts/abi: fix staticcheck warnings (#20358) * accounts/abi: fix staticcheck warnings * accounts/abi: restore unused field for test --- accounts/abi/abi_test.go | 3 +-- accounts/abi/event_test.go | 36 +----------------------------------- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 070f012889..fab84ec9fa 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -27,7 +27,6 @@ import ( "testing" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -934,7 +933,7 @@ func TestABI_MethodById(t *testing.T) { } b := fmt.Sprintf("%v", m2) if a != b { - t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, hexutil.Encode(m.ID())) + t.Errorf("Method %v (id %x) not 'findable' by id in ABI", name, m.ID()) } } // Also test empty diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 23ee920480..c044c5d0ea 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -173,7 +173,7 @@ func TestEventTupleUnpack(t *testing.T) { type EventTransferWithTag struct { // this is valid because `value` is not exportable, // so value is only unmarshalled into `Value1`. - value *big.Int + value *big.Int //lint:ignore U1000 unused field is part of test Value1 *big.Int `abi:"value"` } @@ -354,40 +354,6 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass return a.Unpack(dest, "e", data) } -/* -Taken from -https://github.com/XinFinOrg/XDPoSChain/pull/15568 -*/ - -type testResult struct { - Values [2]*big.Int - Value1 *big.Int - Value2 *big.Int -} - -type testCase struct { - definition string - want testResult -} - -func (tc testCase) encoded(intType, arrayType Type) []byte { - var b bytes.Buffer - if tc.want.Value1 != nil { - val, _ := intType.pack(reflect.ValueOf(tc.want.Value1)) - b.Write(val) - } - - if !reflect.DeepEqual(tc.want.Values, [2]*big.Int{nil, nil}) { - val, _ := arrayType.pack(reflect.ValueOf(tc.want.Values)) - b.Write(val) - } - if tc.want.Value2 != nil { - val, _ := intType.pack(reflect.ValueOf(tc.want.Value2)) - b.Write(val) - } - return b.Bytes() -} - // TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder. func TestEventUnpackIndexed(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` From f2fb9f86616b997171c49e6f07d88cbc9a1acfaa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 089/280] accounts/abi/bind: avoid reclaring structs (#20381) --- accounts/abi/bind/bind.go | 15 +++--- accounts/abi/bind/bind_test.go | 83 ++++++++++++++++++++++++++++++++++ accounts/abi/bind/template.go | 22 ++++----- 3 files changed, 103 insertions(+), 17 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 6a28ad0f77..f7b5023f9d 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -45,12 +45,16 @@ const ( // enforces compile time type safety and naming convention opposed to having to // manually maintain hard coded strings that break on runtime. func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) { - // Process each individual contract requested binding - contracts := make(map[string]*tmplContract) + var ( + // contracts is the map of each individual contract requested binding + contracts = make(map[string]*tmplContract) - // Map used to flag each encountered library as such - isLib := make(map[string]struct{}) + // structs is the map of all reclared structs shared by passed contracts. + structs = make(map[string]*tmplStruct) + // isLib is the map used to flag each encountered library as such + isLib = make(map[string]struct{}) + ) for i := 0; i < len(types); i++ { // Parse the actual ABI to generate the binding for evmABI, err := abi.JSON(strings.NewReader(abis[i])) @@ -70,7 +74,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] calls = make(map[string]*tmplMethod) transacts = make(map[string]*tmplMethod) events = make(map[string]*tmplEvent) - structs = make(map[string]*tmplStruct) // identifiers are used to detect duplicated identifier of function // and event. For all calls, transacts and events, abigen will generate @@ -160,7 +163,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] Transacts: transacts, Events: events, Libraries: make(map[string]string), - Structs: structs, } // Function 4-byte signatures are stored in the same sequence // as types, if available. @@ -192,6 +194,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] Package: pkg, Contracts: contracts, Libraries: libs, + Structs: structs, } buffer := new(bytes.Buffer) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index d6b35156ea..22cd418daf 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1153,6 +1153,89 @@ var bindTests = []struct { map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar nil, }, + { + "MultiContracts", + ` + pragma solidity ^0.5.11; + pragma experimental ABIEncoderV2; + + library ExternalLib { + struct SharedStruct{ + uint256 f1; + bytes32 f2; + } + } + + contract ContractOne { + function foo(ExternalLib.SharedStruct memory s) pure public { + // Do stuff + } + } + + contract ContractTwo { + function bar(ExternalLib.SharedStruct memory s) pure public { + // Do stuff + } + } + `, + []string{ + `60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c80639d8a8ba81461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a72315820749274eb7f6c01010d5322af4e1668b0a154409eb7968bd6cae5524c7ed669bb6c6578706572696d656e74616cf564736f6c634300050c0040`, + `60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c8063db8ba08c1461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a723158209bc28ee7ea97c131a13330d77ec73b4493b5c59c648352da81dd288b021192596c6578706572696d656e74616cf564736f6c634300050c0040`, + `606c6026600b82828239805160001a6073141515601857fe5b30600052607381538281f350fe73000000000000000000000000000000000000000030146080604052600436106023575b60006000fdfea365627a7a72315820518f0110144f5b3de95697d05e456a064656890d08e6f9cff47f3be710cc46a36c6578706572696d656e74616cf564736f6c634300050c0040`, + }, + []string{ + `[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`, + `[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"bar","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`, + `[]`, + }, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + // Deploy registrar contract + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + transactOpts := bind.NewKeyedTransactor(key) + _, _, c1, err := DeployContractOne(transactOpts, sim) + if err != nil { + t.Fatal("Failed to deploy contract") + } + sim.Commit() + err = c1.Foo(nil, ExternalLibSharedStruct{ + F1: big.NewInt(100), + F2: [32]byte{0x01, 0x02, 0x03}, + }) + if err != nil { + t.Fatal("Failed to invoke function") + } + _, _, c2, err := DeployContractTwo(transactOpts, sim) + if err != nil { + t.Fatal("Failed to deploy contract") + } + sim.Commit() + err = c2.Bar(nil, ExternalLibSharedStruct{ + F1: big.NewInt(100), + F2: [32]byte{0x01, 0x02, 0x03}, + }) + if err != nil { + t.Fatal("Failed to invoke function") + } + `, + nil, + nil, + nil, + []string{"ContractOne", "ContractTwo", "ExternalLib"}, + }, } // Tests that packages generated by the binder can be successfully compiled and diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 3a0c7bf5a9..1c1a7255cd 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -23,6 +23,7 @@ type tmplData struct { Package string // Name of the package to place the generated file in Contracts map[string]*tmplContract // List of contracts to generate into this file Libraries map[string]string // Map the bytecode's link pattern to the library name + Structs map[string]*tmplStruct // Contract struct type definitions } // tmplContract contains the data needed to generate an individual contract binding. @@ -36,8 +37,7 @@ type tmplContract struct { Transacts map[string]*tmplMethod // Contract calls that write state data Events map[string]*tmplEvent // Contract events accessors Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs - Structs map[string]*tmplStruct // Contract struct type definitions - Library bool + Library bool // Indicator whether the contract is a library } // tmplMethod is a wrapper around an abi.Method that contains a few preprocessed @@ -106,8 +106,16 @@ var ( _ = event.NewSubscription ) +{{$structs := .Structs}} +{{range $structs}} + // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. + type {{.Name}} struct { + {{range $field := .Fields}} + {{$field.Name}} {{$field.Type}}{{end}} + } +{{end}} + {{range $contract := .Contracts}} - {{$structs := $contract.Structs}} // {{.Type}}ABI is the input ABI used to generate the binding from. const {{.Type}}ABI = "{{.InputABI}}" @@ -283,14 +291,6 @@ var ( return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) } - {{range .Structs}} - // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. - type {{.Name}} struct { - {{range $field := .Fields}} - {{$field.Name}} {{$field.Type}}{{end}} - } - {{end}} - {{range .Calls}} // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // From 833c8513615b78cedded4cc914f4492ca85a3ca8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 090/280] accounts/keystore: fix staticcheck warnings (#20373) * accounts/keystore: fix staticcheck warnings * review feedback --- accounts/keystore/passphrase.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index bf4446c7f7..ae0d2c1dd2 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -122,6 +122,7 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er "Please file a ticket at:\n\n" + "https://github.com/ethereum/go-ethereum/issues." + "The error was : %s" + //lint:ignore ST1005 This is a message for the user return fmt.Errorf(msg, tmpName, err) } } @@ -235,7 +236,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { if cryptoJson.Cipher != "aes-128-ctr" { - return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher) + return nil, fmt.Errorf("cipher not supported: %v", cryptoJson.Cipher) } mac, err := hex.DecodeString(cryptoJson.MAC) if err != nil { @@ -271,7 +272,7 @@ func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { if keyProtected.Version != version { - return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version) + return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version) } keyId = uuid.Parse(keyProtected.Id) plainText, err := DecryptDataV3(keyProtected.Crypto, auth) From db708e76971fbb981ec2ec4b4e2cad94fd13c199 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 091/280] accounts/scwallet: fix staticcheck warnings (#20370) --- accounts/scwallet/securechannel.go | 24 ++++++++++++------------ accounts/scwallet/wallet.go | 15 +++++++++------ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index c108689166..b27a9a3b92 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -71,7 +71,7 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes cardPublic, ok := gen.Unmarshal(keyData) if !ok { - return nil, fmt.Errorf("Could not unmarshal public key from card") + return nil, fmt.Errorf("could not unmarshal public key from card") } secret, err := gen.GenerateSharedSecret(private, cardPublic) @@ -109,7 +109,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error { cardChallenge := response.Data[32:64] if !bytes.Equal(expectedCryptogram, cardCryptogram) { - return fmt.Errorf("Invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram) + return fmt.Errorf("invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram) } md.Reset() @@ -132,7 +132,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error { // Unpair disestablishes an existing pairing. func (s *SecureChannelSession) Unpair() error { if s.PairingKey == nil { - return fmt.Errorf("Cannot unpair: not paired") + return fmt.Errorf("cannot unpair: not paired") } _, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{}) @@ -148,7 +148,7 @@ func (s *SecureChannelSession) Unpair() error { // Open initializes the secure channel. func (s *SecureChannelSession) Open() error { if s.iv != nil { - return fmt.Errorf("Session already opened") + return fmt.Errorf("session already opened") } response, err := s.open() @@ -185,11 +185,11 @@ func (s *SecureChannelSession) mutuallyAuthenticate() error { return err } if response.Sw1 != 0x90 || response.Sw2 != 0x00 { - return fmt.Errorf("Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2) + return fmt.Errorf("got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2) } if len(response.Data) != scSecretLength { - return fmt.Errorf("Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength) + return fmt.Errorf("response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength) } return nil @@ -222,7 +222,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error // transmitEncrypted sends an encrypted message, and decrypts and returns the response. func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) { if s.iv == nil { - return nil, fmt.Errorf("Channel not open") + return nil, fmt.Errorf("channel not open") } data, err := s.encryptAPDU(data) @@ -261,14 +261,14 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b return nil, err } if !bytes.Equal(s.iv, rmac) { - return nil, fmt.Errorf("Invalid MAC in response") + return nil, fmt.Errorf("invalid MAC in response") } rapdu := &responseAPDU{} rapdu.deserialize(plainData) if rapdu.Sw1 != sw1Ok { - return nil, fmt.Errorf("Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) + return nil, fmt.Errorf("unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) } return rapdu, nil @@ -277,7 +277,7 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b // encryptAPDU is an internal method that serializes and encrypts an APDU. func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) { if len(data) > maxPayloadSize { - return nil, fmt.Errorf("Payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize) + return nil, fmt.Errorf("payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize) } data = pad(data, 0x80) @@ -323,10 +323,10 @@ func unpad(data []byte, terminator byte) ([]byte, error) { case terminator: return data[:len(data)-i], nil default: - return nil, fmt.Errorf("Expected end of padding, got %d", data[len(data)-i]) + return nil, fmt.Errorf("expected end of padding, got %d", data[len(data)-i]) } } - return nil, fmt.Errorf("Expected end of padding, got 0") + return nil, fmt.Errorf("expected end of padding, got 0") } // updateIV is an internal method that updates the initialization vector after diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 5948e9b30b..5be89c564d 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -167,7 +167,7 @@ func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) { } if response.Sw1 != sw1Ok { - return nil, fmt.Errorf("Unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) + return nil, fmt.Errorf("unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) } return response, nil @@ -252,7 +252,7 @@ func (w *Wallet) release() error { // with the wallet. func (w *Wallet) pair(puk []byte) error { if w.session.paired() { - return fmt.Errorf("Wallet already paired") + return fmt.Errorf("wallet already paired") } pairing, err := w.session.pair(puk) if err != nil { @@ -773,12 +773,12 @@ func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationP // Look for the path in the URL if account.URL.Scheme != w.Hub.scheme { - return nil, fmt.Errorf("Scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) + return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) } parts := strings.SplitN(account.URL.Path, "/", 2) if len(parts) != 2 { - return nil, fmt.Errorf("Invalid URL format: %s", account.URL) + return nil, fmt.Errorf("invalid URL format: %s", account.URL) } if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) { @@ -813,7 +813,7 @@ func (s *Session) pair(secret []byte) (smartcardPairing, error) { // unpair deletes an existing pairing. func (s *Session) unpair() error { if !s.verified { - return fmt.Errorf("Unpair requires that the PIN be verified") + return fmt.Errorf("unpair requires that the PIN be verified") } return s.Channel.Unpair() } @@ -850,7 +850,7 @@ func (s *Session) paired() bool { // authenticate uses an existing pairing to establish a secure channel. func (s *Session) authenticate(pairing smartcardPairing) error { if !bytes.Equal(s.Wallet.PublicKey, pairing.PublicKey) { - return fmt.Errorf("Cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey) + return fmt.Errorf("cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey) } s.Channel.PairingKey = pairing.PairingKey s.Channel.PairingIndex = pairing.PairingIndex @@ -879,6 +879,7 @@ func (s *Session) walletStatus() (*walletStatus, error) { } // derivationPath fetches the wallet's current derivation path from the card. +//lint:ignore U1000 needs to be added to the console interface func (s *Session) derivationPath() (accounts.DerivationPath, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) if err != nil { @@ -993,12 +994,14 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) } // keyExport contains information on an exported keypair. +//lint:ignore U1000 needs to be added to the console interface type keyExport struct { PublicKey []byte `asn1:"tag:0"` PrivateKey []byte `asn1:"tag:1,optional"` } // publicKey returns the public key for the current derivation path. +//lint:ignore U1000 needs to be added to the console interface func (s *Session) publicKey() ([]byte, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) if err != nil { From 193ee6d606a751c38550c203c558b8fbda43ef41 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 092/280] accounts/usbwallet: fix staticcheck warnings (#20372) --- accounts/usbwallet/ledger.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 87983c4954..818ed4cbef 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -162,8 +162,9 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return common.Address{}, nil, accounts.ErrWalletClosed } // Ensure the wallet is capable of signing the given transaction - if chainID != nil && w.version[0] <= 1 && w.version[1] <= 0 && w.version[2] <= 2 { - return common.Address{}, nil, fmt.Errorf("ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2]) + if chainID != nil && w.version[0] <= 1 && w.version[2] <= 2 { + //lint:ignore ST1005 brand name displayed on the console + return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2]) } // All infos gathered and metadata checks out, request signing return w.ledgerSign(path, tx, chainID) @@ -353,7 +354,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction signer = new(types.HomesteadSigner) } else { signer = types.NewEIP155Signer(chainID) - signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2+35) + signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2 + 35) } signed, err := tx.WithSignature(signer, signature) if err != nil { From e9f9c19c52fb3d38c98f25db04457bfd88278e56 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 093/280] accounts/abi/bind: fix destructive packing of *big.Int (#20412) --- accounts/abi/pack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index 0041349894..58af1446bf 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -73,7 +73,7 @@ func packNum(value reflect.Value) []byte { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return math.U256Bytes(big.NewInt(value.Int())) case reflect.Ptr: - return math.U256Bytes(value.Interface().(*big.Int)) + return math.U256Bytes(new(big.Int).Set(value.Interface().(*big.Int))) default: panic("abi: fatal error") } From f7b66c10b3d0648136cb7f8e4459b8ac62f38647 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 094/280] [#20266] Fix bugs decoding integers and fixed bytes in indexed event fields (#20269) * fix parseTopics() and add tests * remove printf * add ParseTopicsIntoMap() tests * fix FixedBytesTy * fix int and fixed bytes * golint topics_test.go --- accounts/abi/bind/topics.go | 16 ++++- accounts/abi/bind/topics_test.go | 112 ++++++++++++++++++++++++++----- accounts/abi/unpack.go | 22 +++--- 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index 0b35a2d4b7..d999e9a0ee 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -178,6 +178,13 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er case reflectBigInt: num := new(big.Int).SetBytes(topics[0][:]) + if arg.Type.T == abi.IntTy { + if num.Cmp(abi.MaxInt256) > 0 { + num.Add(abi.MaxUint256, big.NewInt(0).Neg(num)) + num.Add(num, big.NewInt(1)) + num.Neg(num) + } + } field.Set(reflect.ValueOf(num)) default: @@ -212,8 +219,7 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics case abi.BoolTy: out[arg.Name] = topics[0][common.HashLength-1] == 1 case abi.IntTy, abi.UintTy: - num := new(big.Int).SetBytes(topics[0][:]) - out[arg.Name] = num + out[arg.Name] = abi.ReadInteger(arg.Type.T, arg.Type.Kind, topics[0].Bytes()) case abi.AddressTy: var addr common.Address copy(addr[:], topics[0][common.HashLength-common.AddressLength:]) @@ -221,7 +227,11 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics case abi.HashTy: out[arg.Name] = topics[0] case abi.FixedBytesTy: - out[arg.Name] = topics[0][:] + array, err := abi.ReadFixedBytes(arg.Type, topics[0].Bytes()) + if err != nil { + return err + } + out[arg.Name] = array case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy: // Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash // whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash diff --git a/accounts/abi/bind/topics_test.go b/accounts/abi/bind/topics_test.go index cb2502554f..09c68f0967 100644 --- a/accounts/abi/bind/topics_test.go +++ b/accounts/abi/bind/topics_test.go @@ -17,6 +17,7 @@ package bind import ( + "math/big" "reflect" "testing" @@ -55,27 +56,44 @@ func TestMakeTopics(t *testing.T) { } } -func TestParseTopics(t *testing.T) { - type bytesStruct struct { - StaticBytes [5]byte - } +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 { 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 - }{ + int8Type, _ := abi.NewType("int8", "", nil) + int256Type, _ := abi.NewType("int256", "", nil) + + tests := []topicTest{ { 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}} }, + resultMap: func() map[string]interface{} { + return map[string]interface{}{"staticBytes": [5]byte{1, 2, 3, 4, 5}} + }, fields: abi.Arguments{abi.Argument{ Name: "staticBytes", Type: bytesType, @@ -87,7 +105,54 @@ func TestParseTopics(t *testing.T) { }, wantErr: false, }, + { + 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, + }, } + + return tests +} + +func TestParseTopics(t *testing.T) { + tests := setupTopicsTests() + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { createObj := tt.args.createObj() @@ -101,3 +166,20 @@ func TestParseTopics(t *testing.T) { }) } } + +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) + } + }) + } +} diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 5a60a03ff4..917bac642c 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -27,16 +27,18 @@ import ( ) var ( - maxUint256 = big.NewInt(0).Add( + // MaxUint256 is the maximum value that can be represented by a uint256 + MaxUint256 = big.NewInt(0).Add( big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil), big.NewInt(-1)) - maxInt256 = big.NewInt(0).Add( + // MaxInt256 is the maximum value that can be represented by a int256 + MaxInt256 = big.NewInt(0).Add( big.NewInt(0).Exp(big.NewInt(2), big.NewInt(255), nil), big.NewInt(-1)) ) -// reads the integer based on its kind -func readInteger(typ byte, kind reflect.Kind, b []byte) interface{} { +// ReadInteger reads the integer based on its kind and returns the appropriate value +func ReadInteger(typ byte, kind reflect.Kind, b []byte) interface{} { switch kind { case reflect.Uint8: return b[len(b)-1] @@ -63,8 +65,8 @@ func readInteger(typ byte, kind reflect.Kind, b []byte) interface{} { return ret } - if ret.Cmp(maxInt256) > 0 { - ret.Add(maxUint256, big.NewInt(0).Neg(ret)) + if ret.Cmp(MaxInt256) > 0 { + ret.Add(MaxUint256, big.NewInt(0).Neg(ret)) ret.Add(ret, big.NewInt(1)) ret.Neg(ret) } @@ -103,8 +105,8 @@ func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) { return } -// through reflection, creates a fixed array to be read from -func readFixedBytes(t Type, word []byte) (interface{}, error) { +// ReadFixedBytes uses reflection to create a fixed array to be read from +func ReadFixedBytes(t Type, word []byte) (interface{}, error) { if t.T != FixedBytesTy { return nil, errors.New("abi: invalid type in call to make fixed byte array") } @@ -231,7 +233,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { case StringTy: // variable arrays are written at the end of the return bytes return string(output[begin : begin+length]), nil case IntTy, UintTy: - return readInteger(t.T, t.Kind, returnOutput), nil + return ReadInteger(t.T, t.Kind, returnOutput), nil case BoolTy: return readBool(returnOutput) case AddressTy: @@ -241,7 +243,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { case BytesTy: return output[begin : begin+length], nil case FixedBytesTy: - return readFixedBytes(t, returnOutput) + return ReadFixedBytes(t, returnOutput) case FunctionTy: return readFunctionType(t, returnOutput) default: From 0350880af61218d764ccbabba4a785d7b590ee64 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 095/280] accounts/abi/backends/simulated: add more API methods (#5) (#20208) * Add more functionality to the sim (#5) * backends: implement more of ethclient in sim * backends: add BlockByNumber to simulated backend * backends: make simulated progress function agree with syncprogress interface for client * backends: add more tests * backends: add more comments * backends: fix sim for index in tx and add tests * backends: add lock back to estimategas * backends: goimports * backends: go ci lint * Add more functionality to the sim (#5) * backends: implement more of ethclient in sim * backends: add BlockByNumber to simulated backend * backends: make simulated progress function agree with syncprogress interface for client * backends: add more tests * backends: add more comments * backends: fix sim for index in tx and add tests * backends: add lock back to estimategas * backends: goimports * backends: go ci lint * assert errs --- accounts/abi/bind/backends/simulated.go | 134 +++- accounts/abi/bind/backends/simulated_test.go | 736 +++++++++++++++++++ 2 files changed, 868 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index e955a18324..ee753a2bc7 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -56,11 +56,16 @@ import ( var _ bind.ContractBackend = (*SimulatedBackend)(nil) var ( - errBlockNumberUnsupported = errors.New("SimulatedBackend cannot access blocks other than the latest block") + errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block") + errBlockDoesNotExist = errors.New("block does not exist in blockchain") + errTransactionDoesNotExist = errors.New("transaction does not exist") ) // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in // the background. Its main purpose is to allow easily testing contract bindings. +// Simulated backend implements the following interfaces: +// ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor, +// DeployBackend, GasEstimator, GasPricer, LogFilterer, PendingContractCaller, TransactionReader, and TransactionSender type SimulatedBackend struct { database ethdb.Database // In memory database to store our testing data blockchain *core.BlockChain // Ethereum blockchain to handle the consensus @@ -262,6 +267,9 @@ func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common // TransactionReceipt returns the receipt of a transaction. func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + b.mu.Lock() + defer b.mu.Unlock() + receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config) return receipt, nil } @@ -285,6 +293,58 @@ func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common. return nil, false, ethereum.ErrNotFound } +// BlockByHash retrieves a block based on the block hash +func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if hash == b.pendingBlock.Hash() { + return b.pendingBlock, nil + } + + block := b.blockchain.GetBlockByHash(hash) + if block != nil { + return block, nil + } + + return nil, errBlockDoesNotExist +} + +// BlockByNumber retrieves a block from the database by number, caching it +// (associated with its hash) if found. +func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 { + return b.blockchain.CurrentBlock(), nil + } + + block := b.blockchain.GetBlockByNumber(uint64(number.Int64())) + if block == nil { + return nil, errBlockDoesNotExist + } + + return block, nil +} + +// HeaderByHash returns a block header from the current canonical chain. +func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if hash == b.pendingBlock.Hash() { + return b.pendingBlock.Header(), nil + } + + header := b.blockchain.GetHeaderByHash(hash) + if header == nil { + return nil, errBlockDoesNotExist + } + + return header, nil +} + // HeaderByNumber returns a block header from the current canonical chain. If number is // nil, the latest known header is returned. func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) { @@ -298,6 +358,50 @@ func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) ( return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil } +// TransactionCount returns the number of transactions in a given block +func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockHash == b.pendingBlock.Hash() { + return uint(b.pendingBlock.Transactions().Len()), nil + } + + block := b.blockchain.GetBlockByHash(blockHash) + if block == nil { + return uint(0), errBlockDoesNotExist + } + + return uint(block.Transactions().Len()), nil +} + +// TransactionInBlock returns the transaction for a specific block at a specific index +func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockHash == b.pendingBlock.Hash() { + transactions := b.pendingBlock.Transactions() + if uint(len(transactions)) < index+1 { + return nil, errTransactionDoesNotExist + } + + return transactions[index], nil + } + + block := b.blockchain.GetBlockByHash(blockHash) + if block == nil { + return nil, errBlockDoesNotExist + } + + transactions := block.Transactions() + if uint(len(transactions)) < index+1 { + return nil, errTransactionDoesNotExist + } + + return transactions[index], nil +} + // PendingCodeAt returns the code associated with an account in the pending state. func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { b.mu.Lock() @@ -607,12 +711,38 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethere }), nil } +// SubscribeNewHead returns an event subscription for a new header +func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { + // subscribe to a new head + sink := make(chan *types.Header) + sub := b.events.SubscribeNewHeads(sink) + + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case head := <-sink: + select { + case ch <- head: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + // AdjustTime adds a time shift to the simulated clock. func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { b.mu.Lock() defer b.mu.Unlock() blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { - // blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { for _, tx := range b.pendingBlock.Transactions() { block.AddTx(tx) } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 5ff57db4c6..632fc7290e 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -17,11 +17,13 @@ package backends import ( + "bytes" "context" "errors" "math/big" "strings" "testing" + "time" ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" @@ -84,6 +86,276 @@ func TestSimulatedBackend(t *testing.T) { } } +var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + +// the following is based on this contract: +// contract T { +// event received(address sender, uint amount, bytes memo); +// event receivedAddr(address sender); +// +// function receive(bytes calldata memo) external payable returns (string memory res) { +// emit received(msg.sender, msg.value, memo); +// emit receivedAddr(msg.sender); +// return "hello world"; +// } +// } +const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` +const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` +const deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` + +// expected return value contains "hello world" +var expectedReturn = []byte{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, 32, 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, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +func TestNewSimulatedBackend(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + expectedBal := big.NewInt(10000000000) + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: expectedBal}, + }, 10000000, + ) + defer sim.Close() + + if sim.config != params.AllEthashProtocolChanges { + t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config) + } + + if sim.blockchain.Config() != params.AllEthashProtocolChanges { + t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) + } + + statedb, _ := sim.blockchain.State() + bal := statedb.GetBalance(testAddr) + if bal.Cmp(expectedBal) != 0 { + t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) + } +} + +func TestSimulatedBackend_AdjustTime(t *testing.T) { + sim := NewSimulatedBackend( + core.GenesisAlloc{}, 10000000, + ) + defer sim.Close() + + prevTime := sim.pendingBlock.Time().Uint64() + err := sim.AdjustTime(time.Second) + if err != nil { + t.Error(err) + } + newTime := sim.pendingBlock.Time().Uint64() + + if newTime-prevTime != uint64(time.Second.Seconds()) { + t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime) + } +} + +func TestSimulatedBackend_BalanceAt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + expectedBal := big.NewInt(10000000000) + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: expectedBal}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + bal, err := sim.BalanceAt(bgCtx, testAddr, nil) + if err != nil { + t.Error(err) + } + + if bal.Cmp(expectedBal) != 0 { + t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) + } +} + +func TestSimulatedBackend_BlockByHash(t *testing.T) { + sim := NewSimulatedBackend( + core.GenesisAlloc{}, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + block, err := sim.BlockByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + blockByHash, err := sim.BlockByHash(bgCtx, block.Hash()) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + + if block.Hash() != blockByHash.Hash() { + t.Errorf("did not get expected block") + } +} + +func TestSimulatedBackend_BlockByNumber(t *testing.T) { + sim := NewSimulatedBackend( + core.GenesisAlloc{}, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + block, err := sim.BlockByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + if block.NumberU64() != 0 { + t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) + } + + // create one block + sim.Commit() + + block, err = sim.BlockByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + if block.NumberU64() != 1 { + t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64()) + } + + blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) + if err != nil { + t.Errorf("could not get block by number: %v", err) + } + if blockByNumber.Hash() != block.Hash() { + t.Errorf("did not get the same block with height of 1 as before") + } +} + +func TestSimulatedBackend_NonceAt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0)) + if err != nil { + t.Errorf("could not get nonce for test addr: %v", err) + } + + if nonce != uint64(0) { + t.Errorf("received incorrect nonce. expected 0, got %v", nonce) + } + + // create a signed transaction to send + tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + sim.Commit() + + newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) + if err != nil { + t.Errorf("could not get nonce for test addr: %v", err) + } + + if newNonce != nonce+uint64(1) { + t.Errorf("received incorrect nonce. expected 1, got %v", nonce) + } +} + +func TestSimulatedBackend_SendTransaction(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + sim.Commit() + + block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) + if err != nil { + t.Errorf("could not get block at height 1: %v", err) + } + + if signedTx.Hash() != block.Transactions()[0].Hash() { + t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash()) + } +} + +func TestSimulatedBackend_TransactionByHash(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + + // ensure tx is committed pending + receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) + if err != nil { + t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) + } + if !pending { + t.Errorf("expected transaction to be in pending state") + } + if receivedTx.Hash() != signedTx.Hash() { + t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) + } + + sim.Commit() + + // ensure tx is not and committed pending + receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash()) + if err != nil { + t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err) + } + if pending { + t.Errorf("expected transaction to not be in pending state") + } + if receivedTx.Hash() != signedTx.Hash() { + t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash()) + } +} + func TestSimulatedBackend_EstimateGas(t *testing.T) { /* pragma solidity ^0.6.4; @@ -204,3 +476,467 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { } } } + +func TestSimulatedBackend_HeaderByHash(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + header, err := sim.HeaderByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash()) + if err != nil { + t.Errorf("could not get recent block: %v", err) + } + + if header.Hash() != headerByHash.Hash() { + t.Errorf("did not get expected block") + } +} + +func TestSimulatedBackend_HeaderByNumber(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get header for tip of chain: %v", err) + } + if latestBlockHeader == nil { + t.Errorf("received a nil block header") + } + if latestBlockHeader.Number.Uint64() != uint64(0) { + t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) + } + + sim.Commit() + + latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get header for blockheight of 1: %v", err) + } + + blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1)) + if err != nil { + t.Errorf("could not get header for blockheight of 1: %v", err) + } + + if blockHeader.Hash() != latestBlockHeader.Hash() { + t.Errorf("block header and latest block header are not the same") + } + if blockHeader.Number.Int64() != int64(1) { + t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64()) + } + + block, err := sim.BlockByNumber(bgCtx, big.NewInt(1)) + if err != nil { + t.Errorf("could not get block for blockheight of 1: %v", err) + } + + if block.Hash() != blockHeader.Hash() { + t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash()) + } +} + +func TestSimulatedBackend_TransactionCount(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + currentBlock, err := sim.BlockByNumber(bgCtx, nil) + if err != nil || currentBlock == nil { + t.Error("could not get current block") + } + + count, err := sim.TransactionCount(bgCtx, currentBlock.Hash()) + if err != nil { + t.Error("could not get current block's transaction count") + } + + if count != 0 { + t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count) + } + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + + sim.Commit() + + lastBlock, err := sim.BlockByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get header for tip of chain: %v", err) + } + + count, err = sim.TransactionCount(bgCtx, lastBlock.Hash()) + if err != nil { + t.Error("could not get current block's transaction count") + } + + if count != 1 { + t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count) + } +} + +func TestSimulatedBackend_TransactionInBlock(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0)) + if err == nil && err != errTransactionDoesNotExist { + t.Errorf("expected a transaction does not exist error to be received but received %v", err) + } + if transaction != nil { + t.Errorf("expected transaction to be nil but received %v", transaction) + } + + // expect pending nonce to be 0 since account has not been used + pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) + if err != nil { + t.Errorf("did not get the pending nonce: %v", err) + } + + if pendingNonce != uint64(0) { + t.Errorf("expected pending nonce of 0 got %v", pendingNonce) + } + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + + sim.Commit() + + lastBlock, err := sim.BlockByNumber(bgCtx, nil) + if err != nil { + t.Errorf("could not get header for tip of chain: %v", err) + } + + transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1)) + if err == nil && err != errTransactionDoesNotExist { + t.Errorf("expected a transaction does not exist error to be received but received %v", err) + } + if transaction != nil { + t.Errorf("expected transaction to be nil but received %v", transaction) + } + + transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0)) + if err != nil { + t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err) + } + + if signedTx.Hash().String() != transaction.Hash().String() { + t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String()) + } +} + +func TestSimulatedBackend_PendingNonceAt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + // expect pending nonce to be 0 since account has not been used + pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) + if err != nil { + t.Errorf("did not get the pending nonce: %v", err) + } + + if pendingNonce != uint64(0) { + t.Errorf("expected pending nonce of 0 got %v", pendingNonce) + } + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + + // expect pending nonce to be 1 since account has submitted one transaction + pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) + if err != nil { + t.Errorf("did not get the pending nonce: %v", err) + } + + if pendingNonce != uint64(1) { + t.Errorf("expected pending nonce of 1 got %v", pendingNonce) + } + + // make a new transaction with a nonce of 1 + tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not send tx: %v", err) + } + + // expect pending nonce to be 2 since account now has two transactions + pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) + if err != nil { + t.Errorf("did not get the pending nonce: %v", err) + } + + if pendingNonce != uint64(2) { + t.Errorf("expected pending nonce of 2 got %v", pendingNonce) + } +} + +func TestSimulatedBackend_TransactionReceipt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + // create a signed transaction to send + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + // send tx to simulated backend + err = sim.SendTransaction(bgCtx, signedTx) + if err != nil { + t.Errorf("could not add tx to pending block: %v", err) + } + sim.Commit() + + receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash()) + if err != nil { + t.Errorf("could not get transaction receipt: %v", err) + } + + if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() { + t.Errorf("received receipt is not correct: %v", receipt) + } +} + +func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { + sim := NewSimulatedBackend( + core.GenesisAlloc{}, + 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + gasPrice, err := sim.SuggestGasPrice(bgCtx) + if err != nil { + t.Errorf("could not get gas price: %v", err) + } + if gasPrice.Uint64() != uint64(1) { + t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64()) + } +} + +func TestSimulatedBackend_PendingCodeAt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, + 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + code, err := sim.CodeAt(bgCtx, testAddr, nil) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) != 0 { + t.Errorf("got code for account that does not have contract code") + } + + parsed, err := abi.JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + auth := bind.NewKeyedTransactor(testKey) + contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) + if err != nil { + t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) + } + + code, err = sim.PendingCodeAt(bgCtx, contractAddr) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) == 0 { + t.Errorf("did not get code for account that has contract code") + } + // ensure code received equals code deployed + if !bytes.Equal(code, common.FromHex(deployedCode)) { + t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) + } +} + +func TestSimulatedBackend_CodeAt(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, + 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + code, err := sim.CodeAt(bgCtx, testAddr, nil) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) != 0 { + t.Errorf("got code for account that does not have contract code") + } + + parsed, err := abi.JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + auth := bind.NewKeyedTransactor(testKey) + contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) + if err != nil { + t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) + } + + sim.Commit() + code, err = sim.CodeAt(bgCtx, contractAddr, nil) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) == 0 { + t.Errorf("did not get code for account that has contract code") + } + // ensure code received equals code deployed + if !bytes.Equal(code, common.FromHex(deployedCode)) { + t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) + } +} + +// When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: +// +// receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} +func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, + 10000000, + ) + defer sim.Close() + bgCtx := context.Background() + + parsed, err := abi.JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + contractAuth := bind.NewKeyedTransactor(testKey) + addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) + if err != nil { + t.Errorf("could not deploy contract: %v", err) + } + + input, err := parsed.Pack("receive", []byte("X")) + if err != nil { + t.Errorf("could pack receive function on contract: %v", err) + } + + // make sure you can call the contract in pending state + res, err := sim.PendingCallContract(bgCtx, ethereum.CallMsg{ + From: testAddr, + To: &addr, + Data: input, + }) + if err != nil { + t.Errorf("could not call receive method on contract: %v", err) + } + if len(res) == 0 { + t.Errorf("result of contract call was empty: %v", res) + } + + // while comparing against the byte array is more exact, also compare against the human readable string for readability + if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { + t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) + } + + sim.Commit() + + // make sure you can call the contract + res, err = sim.CallContract(bgCtx, ethereum.CallMsg{ + From: testAddr, + To: &addr, + Data: input, + }, nil) + if err != nil { + t.Errorf("could not call receive method on contract: %v", err) + } + if len(res) == 0 { + t.Errorf("result of contract call was empty: %v", res) + } + + if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { + t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) + } +} From 8d4c290cce3f2458e13013584655853f88766577 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 096/280] accounts/abi: fix method constant flag for solidity 6.0 (#20482) --- accounts/abi/abi.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 3201ef0bc2..2f3817243b 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -110,12 +110,13 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) // UnmarshalJSON implements json.Unmarshaler interface func (abi *ABI) UnmarshalJSON(data []byte) error { var fields []struct { - Type string - Name string - Constant bool - Anonymous bool - Inputs []Argument - Outputs []Argument + Type string + Name string + Constant bool + StateMutability string + Anonymous bool + Inputs []Argument + Outputs []Argument } if err := json.Unmarshal(data, &fields); err != nil { return err @@ -136,10 +137,11 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { name = fmt.Sprintf("%s%d", field.Name, idx) _, ok = abi.Methods[name] } + isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view" abi.Methods[name] = Method{ Name: name, RawName: field.Name, - Const: field.Constant, + Const: isConst, Inputs: field.Inputs, Outputs: field.Outputs, } From 164d929307f10998ce1d50b352fd7f841374db53 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 097/280] accounts/abi/bind/backends: add support for historical state (#20644) --- accounts/abi/bind/backends/simulated.go | 40 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index ee753a2bc7..fe5ae20a74 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -203,15 +203,28 @@ func (b *SimulatedBackend) rollback() { b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) } +// stateByBlockNumber retrieves a state by a given blocknumber. +func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) { + if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 { + return b.blockchain.State() + } + block, err := b.BlockByNumber(ctx, blockNumber) + if err != nil { + return nil, err + } + return b.blockchain.StateAt(block.Hash()) +} + // CodeAt returns the code associated with a certain account in the blockchain. func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + return statedb.GetCode(contract), nil } @@ -220,10 +233,11 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + return statedb.GetBalance(contract), nil } @@ -232,10 +246,11 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return 0, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return 0, err } - statedb, _ := b.blockchain.State() + return statedb.GetNonce(contract), nil } @@ -244,10 +259,11 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { - return nil, errBlockNumberUnsupported + statedb, err := b.stateByBlockNumber(ctx, blockNumber) + if err != nil { + return nil, err } - statedb, _ := b.blockchain.State() + val := statedb.GetState(contract, key) return val[:], nil } From 219b5ef8837436c8b338e09bbc21a09b1487eff2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 098/280] accounts: add walletsNoLock to avoid double read lock (#20655) --- accounts/manager.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/accounts/manager.go b/accounts/manager.go index f4f40bff88..e2ad6ddc8c 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -141,6 +141,11 @@ func (am *Manager) Wallets() []Wallet { am.lock.RLock() defer am.lock.RUnlock() + return am.walletsNoLock() +} + +// walletsNoLock returns all registered wallets. Callers must hold am.lock. +func (am *Manager) walletsNoLock() []Wallet { cpy := make([]Wallet, len(am.wallets)) copy(cpy, am.wallets) return cpy @@ -155,7 +160,7 @@ func (am *Manager) Wallet(url string) (Wallet, error) { if err != nil { return nil, err } - for _, wallet := range am.Wallets() { + for _, wallet := range am.walletsNoLock() { if wallet.URL() == parsed { return wallet, nil } From 6259ce565c68acb2da1fc07af3a6d0dd1934ba34 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 099/280] accounts/abi faster unpacking of int256 (#20850) --- accounts/abi/unpack.go | 22 +++++++++------------- accounts/abi/unpack_test.go | 2 +- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 917bac642c..99125cf3a1 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -28,13 +28,9 @@ import ( var ( // MaxUint256 is the maximum value that can be represented by a uint256 - MaxUint256 = big.NewInt(0).Add( - big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil), - big.NewInt(-1)) + MaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 256), common.Big1) // MaxInt256 is the maximum value that can be represented by a int256 - MaxInt256 = big.NewInt(0).Add( - big.NewInt(0).Exp(big.NewInt(2), big.NewInt(255), nil), - big.NewInt(-1)) + MaxInt256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 255), common.Big1) ) // ReadInteger reads the integer based on its kind and returns the appropriate value @@ -57,17 +53,17 @@ func ReadInteger(typ byte, kind reflect.Kind, b []byte) interface{} { case reflect.Int64: return int64(binary.BigEndian.Uint64(b[len(b)-8:])) default: - // the only case lefts for integer is int256/uint256. - // big.SetBytes can't tell if a number is negative, positive on itself. - // On EVM, if the returned number > max int256, it is negative. + // the only case left for integer is int256/uint256. ret := new(big.Int).SetBytes(b) if typ == UintTy { return ret } - - if ret.Cmp(MaxInt256) > 0 { - ret.Add(MaxUint256, big.NewInt(0).Neg(ret)) - ret.Add(ret, big.NewInt(1)) + // big.SetBytes can't tell if a number is negative or positive in itself. + // On EVM, if the returned number > max int256, it is negative. + // A number is > max int256 if the bit at position 255 is set. + if ret.Bit(255) == 1 { + ret.Add(MaxUint256, new(big.Int).Neg(ret)) + ret.Add(ret, common.Big1) ret.Neg(ret) } return ret diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 8be43b44d9..d788224d3c 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -1009,7 +1009,7 @@ func TestUnpackTuple(t *testing.T) { t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A) } if v.B.Cmp(big.NewInt(-1)) != 0 { - t.Errorf("unexpected value unpacked: want %x, got %x", v.B, -1) + t.Errorf("unexpected value unpacked: want %x, got %x", -1, v.B) } } From 601d1c80ea8fa2eb39348b59f1487d691645acce Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 100/280] accounts/scwallet: fix unnecessary use of fmt.Sprint --- accounts/scwallet/wallet.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 5be89c564d..af557a7018 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -312,15 +312,15 @@ func (w *Wallet) Status() (string, error) { } switch { case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0: - return fmt.Sprintf("Bricked, waiting for full wipe"), nil + return "Bricked, waiting for full wipe", nil case !w.session.verified && status.PinRetryCount == 0: return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil case !w.session.verified: return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil case !status.Initialized: - return fmt.Sprintf("Empty, waiting for initialization"), nil + return "Empty, waiting for initialization", nil default: - return fmt.Sprintf("Online"), nil + return "Online", nil } } @@ -879,6 +879,7 @@ func (s *Session) walletStatus() (*walletStatus, error) { } // derivationPath fetches the wallet's current derivation path from the card. +// //lint:ignore U1000 needs to be added to the console interface func (s *Session) derivationPath() (accounts.DerivationPath, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) @@ -994,6 +995,7 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) } // keyExport contains information on an exported keypair. +// //lint:ignore U1000 needs to be added to the console interface type keyExport struct { PublicKey []byte `asn1:"tag:0"` @@ -1001,6 +1003,7 @@ type keyExport struct { } // publicKey returns the public key for the current derivation path. +// //lint:ignore U1000 needs to be added to the console interface func (s *Session) publicKey() ([]byte, error) { response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) From f8b85afec5034efc73b5a0d3602d9f220d9779c1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 101/280] accounts/abi/bind: Refactored topics (#20851) * accounts/abi/bind: refactored topics * accounts/abi/bind: use store function to remove code duplication * accounts/abi/bind: removed unused type defs * accounts/abi/bind: error on tuples in topics * Cosmetic changes to restart travis build Co-authored-by: Guillaume Ballet --- accounts/abi/argument.go | 2 +- accounts/abi/bind/topics.go | 157 +++++++------------------------ accounts/abi/bind/topics_test.go | 16 ++++ accounts/abi/unpack.go | 8 +- 4 files changed, 55 insertions(+), 128 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 760254201e..39b257c55c 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -304,7 +304,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { retval := make([]interface{}, 0, arguments.LengthNonIndexed()) virtualArgs := 0 for index, arg := range arguments.NonIndexed() { - marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) + marshalledValue, err := ToGoType((index+virtualArgs)*32, arg.Type, data) if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index d999e9a0ee..2543bd9bcf 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -103,151 +103,62 @@ func makeTopics(query ...[]interface{}) ([][]common.Hash, error) { return topics, nil } -// Big batch of reflect types for topic reconstruction. -var ( - reflectHash = reflect.TypeOf(common.Hash{}) - reflectAddress = reflect.TypeOf(common.Address{}) - reflectBigInt = reflect.TypeOf(new(big.Int)) -) - // parseTopics converts the indexed topic fields into actual log field values. -// -// Note, dynamic types cannot be reconstructed since they get mapped to Keccak256 -// hashes as the topic value! func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) error { - // Sanity check that the fields and topics match up - if len(fields) != len(topics) { - return errors.New("topic/field count mismatch") - } - // Iterate over all the fields and reconstruct them from topics - for _, arg := range fields { - if !arg.Indexed { - return errors.New("non-indexed field in topic reconstruction") - } - field := reflect.ValueOf(out).Elem().FieldByName(capitalise(arg.Name)) - - // Try to parse the topic back into the fields based on primitive types - switch field.Kind() { - case reflect.Bool: - if topics[0][common.HashLength-1] == 1 { - field.Set(reflect.ValueOf(true)) - } - case reflect.Int8: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(int8(num.Int64()))) - - case reflect.Int16: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(int16(num.Int64()))) - - case reflect.Int32: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(int32(num.Int64()))) - - case reflect.Int64: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(num.Int64())) - - case reflect.Uint8: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(uint8(num.Uint64()))) - - case reflect.Uint16: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(uint16(num.Uint64()))) - - case reflect.Uint32: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(uint32(num.Uint64()))) - - case reflect.Uint64: - num := new(big.Int).SetBytes(topics[0][:]) - field.Set(reflect.ValueOf(num.Uint64())) - - default: - // Ran out of plain primitive types, try custom types - - switch field.Type() { - case reflectHash: // Also covers all dynamic types - field.Set(reflect.ValueOf(topics[0])) - - case reflectAddress: - var addr common.Address - copy(addr[:], topics[0][common.HashLength-common.AddressLength:]) - field.Set(reflect.ValueOf(addr)) - - case reflectBigInt: - num := new(big.Int).SetBytes(topics[0][:]) - if arg.Type.T == abi.IntTy { - if num.Cmp(abi.MaxInt256) > 0 { - num.Add(abi.MaxUint256, big.NewInt(0).Neg(num)) - num.Add(num, big.NewInt(1)) - num.Neg(num) - } - } - field.Set(reflect.ValueOf(num)) - - 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][:arg.Type.Size])) - default: - return fmt.Errorf("unsupported indexed type: %v", arg.Type) - } - } - } - topics = topics[1:] - } - return nil + return parseTopicWithSetter(fields, topics, + func(arg abi.Argument, reconstr interface{}) { + field := reflect.ValueOf(out).Elem().FieldByName(capitalise(arg.Name)) + field.Set(reflect.ValueOf(reconstr)) + }) } // parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error { + return parseTopicWithSetter(fields, topics, + func(arg abi.Argument, reconstr interface{}) { + out[arg.Name] = reconstr + }) +} + +// parseTopicWithSetter converts the indexed topic field-value pairs and stores them using the +// provided set function. +// +// Note, dynamic types cannot be reconstructed since they get mapped to Keccak256 +// hashes as the topic value! +func parseTopicWithSetter(fields abi.Arguments, topics []common.Hash, setter func(abi.Argument, interface{})) error { // Sanity check that the fields and topics match up if len(fields) != len(topics) { return errors.New("topic/field count mismatch") } // Iterate over all the fields and reconstruct them from topics - for _, arg := range fields { + for i, arg := range fields { if !arg.Indexed { return errors.New("non-indexed field in topic reconstruction") } - + var reconstr interface{} switch arg.Type.T { - case abi.BoolTy: - out[arg.Name] = topics[0][common.HashLength-1] == 1 - case abi.IntTy, abi.UintTy: - out[arg.Name] = abi.ReadInteger(arg.Type.T, arg.Type.Kind, topics[0].Bytes()) - case abi.AddressTy: - var addr common.Address - copy(addr[:], topics[0][common.HashLength-common.AddressLength:]) - out[arg.Name] = addr - case abi.HashTy: - out[arg.Name] = topics[0] - case abi.FixedBytesTy: - array, err := abi.ReadFixedBytes(arg.Type, topics[0].Bytes()) - if err != nil { - return err - } - out[arg.Name] = array + case abi.TupleTy: + return errors.New("tuple type in topic reconstruction") case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy: // Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash // whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash - out[arg.Name] = topics[0] + reconstr = topics[i] case abi.FunctionTy: - if garbage := binary.BigEndian.Uint64(topics[0][0:8]); garbage != 0 { - return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[0].Bytes()) + if garbage := binary.BigEndian.Uint64(topics[i][0:8]); garbage != 0 { + return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[i].Bytes()) } var tmp [24]byte - copy(tmp[:], topics[0][8:32]) - out[arg.Name] = tmp - default: // Not handling tuples - return fmt.Errorf("unsupported indexed type: %v", arg.Type) + copy(tmp[:], topics[i][8:32]) + reconstr = tmp + default: + var err error + reconstr, err = abi.ToGoType(0, arg.Type, topics[i].Bytes()) + if err != nil { + return err + } } - - topics = topics[1:] + // Use the setter function to store the value + setter(arg, reconstr) } return nil diff --git a/accounts/abi/bind/topics_test.go b/accounts/abi/bind/topics_test.go index 09c68f0967..bf3c714542 100644 --- a/accounts/abi/bind/topics_test.go +++ b/accounts/abi/bind/topics_test.go @@ -84,6 +84,7 @@ func setupTopicsTests() []topicTest { bytesType, _ := abi.NewType("bytes5", "", nil) int8Type, _ := abi.NewType("int8", "", nil) int256Type, _ := abi.NewType("int256", "", nil) + tupleType, _ := abi.NewType("tuple(int256,int8)", "", nil) tests := []topicTest{ { @@ -145,6 +146,21 @@ func setupTopicsTests() []topicTest { }, wantErr: false, }, + { + 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, + }, } return tests diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 99125cf3a1..6b5ca98854 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -141,7 +141,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) elemSize := getTypeSize(*t.Elem) for i, j := start, 0; j < size; i, j = i+elemSize, j+1 { - inter, err := toGoType(i, *t.Elem, output) + inter, err := ToGoType(i, *t.Elem, output) if err != nil { return nil, err } @@ -158,7 +158,7 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { retval := reflect.New(t.Type).Elem() virtualArgs := 0 for index, elem := range t.TupleElems { - marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output) + marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output) if elem.T == ArrayTy && !isDynamicType(*elem) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. @@ -184,9 +184,9 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { return retval.Interface(), nil } -// toGoType parses the output bytes and recursively assigns the value of these bytes +// ToGoType parses the output bytes and recursively assigns the value of these bytes // into a go type with accordance with the ABI spec. -func toGoType(index int, t Type, output []byte) (interface{}, error) { +func ToGoType(index int, t Type, output []byte) (interface{}, error) { if index+32 > len(output) { return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32) } From 296c052c02557e789ea8e9bad40e522dc24577fb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 102/280] accounts/abi/bind: fixed erroneous filtering of negative ints (#20865) * accounts/abi/bind: fixed erroneous packing of negative ints * accounts/abi/bind: added test cases for negative ints in topics * accounts/abi/bind: fixed genIntType for go 1.12 * accounts/abi: minor nitpick --- accounts/abi/bind/topics.go | 25 +++++++---- accounts/abi/bind/topics_test.go | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 8 deletions(-) diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go index 2543bd9bcf..0bee4f39a1 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/bind/topics.go @@ -49,17 +49,13 @@ func makeTopics(query ...[]interface{}) ([][]common.Hash, error) { topic[common.HashLength-1] = 1 } case int8: - blob := big.NewInt(int64(rule)).Bytes() - copy(topic[common.HashLength-len(blob):], blob) + copy(topic[:], genIntType(int64(rule), 1)) case int16: - blob := big.NewInt(int64(rule)).Bytes() - copy(topic[common.HashLength-len(blob):], blob) + copy(topic[:], genIntType(int64(rule), 2)) case int32: - blob := big.NewInt(int64(rule)).Bytes() - copy(topic[common.HashLength-len(blob):], blob) + copy(topic[:], genIntType(int64(rule), 4)) case int64: - blob := big.NewInt(rule).Bytes() - copy(topic[common.HashLength-len(blob):], blob) + copy(topic[:], genIntType(rule, 8)) case uint8: blob := new(big.Int).SetUint64(uint64(rule)).Bytes() copy(topic[common.HashLength-len(blob):], blob) @@ -103,6 +99,19 @@ func makeTopics(query ...[]interface{}) ([][]common.Hash, error) { return topics, nil } +func genIntType(rule int64, size uint) []byte { + var topic [common.HashLength]byte + if rule < 0 { + // if a rule is negative, we need to put it into two's complement. + // extended to common.Hashlength bytes. + topic = [common.HashLength]byte{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} + } + for i := uint(0); i < size; i++ { + topic[common.HashLength-i-1] = byte(rule >> (i * 8)) + } + return topic[:] +} + // parseTopics converts the indexed topic fields into actual log field values. func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) error { return parseTopicWithSetter(fields, topics, diff --git a/accounts/abi/bind/topics_test.go b/accounts/abi/bind/topics_test.go index bf3c714542..c74b90cacd 100644 --- a/accounts/abi/bind/topics_test.go +++ b/accounts/abi/bind/topics_test.go @@ -23,6 +23,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/crypto" ) func TestMakeTopics(t *testing.T) { @@ -41,6 +42,80 @@ func TestMakeTopics(t *testing.T) { [][]common.Hash{{common.Hash{1, 2, 3, 4, 5}}}, false, }, + { + "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, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From fd53a433aa45f167d90cf19e2ce61e4231839192 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 103/280] accounts/abi: implement new fallback functions (#20764) * accounts/abi: implement new fackball functions In Solidity v0.6.0, the original fallback is separated into two different sub types: fallback and receive. This PR addes the support for parsing new format abi and the relevant abigen functionalities. * accounts/abi: fix unit tests * accounts/abi: minor fixes * accounts/abi, mobile: support jave binding * accounts/abi: address marius's comment * accounts/abi: Work around the uin64 conversion issue Co-authored-by: Guillaume Ballet --- accounts/abi/abi.go | 115 ++++++++++++++++++++++++++++----- accounts/abi/abi_test.go | 50 +++++++------- accounts/abi/bind/base.go | 12 ++++ accounts/abi/bind/bind.go | 36 +++++++++-- accounts/abi/bind/bind_test.go | 94 +++++++++++++++++++++++++++ accounts/abi/bind/template.go | 48 ++++++++++++++ accounts/abi/method.go | 56 +++++++++++++--- accounts/abi/method_test.go | 29 +++++++-- accounts/abi/unpack_test.go | 36 +++++------ 9 files changed, 396 insertions(+), 80 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 2f3817243b..c65d22d8ed 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -34,6 +34,12 @@ type ABI struct { Constructor Method Methods map[string]Method Events map[string]Event + + // Additional "special" functions introduced in solidity v0.6.0. + // It's separated from the original default fallback. Each contract + // can only define one fallback and receive function. + Fallback Method // Note it's also used to represent legacy fallback before v0.6.0 + Receive Method } // JSON returns a parsed ABI interface and error if it failed. @@ -44,7 +50,6 @@ func JSON(reader io.Reader) (ABI, error) { if err := dec.Decode(&abi); err != nil { return ABI{}, err } - return abi, nil } @@ -110,13 +115,22 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) // UnmarshalJSON implements json.Unmarshaler interface func (abi *ABI) UnmarshalJSON(data []byte) error { var fields []struct { - Type string - Name string - Constant bool + Type string + Name string + Inputs []Argument + Outputs []Argument + + // Status indicator which can be: "pure", "view", + // "nonpayable" or "payable". StateMutability string - Anonymous bool - Inputs []Argument - Outputs []Argument + + // Deprecated Status indicators, but removed in v0.6.0. + Constant bool // True if function is either pure or view + Payable bool // True if function is payable + + // Event relevant indicator represents the event is + // declared as anonymous. + Anonymous bool } if err := json.Unmarshal(data, &fields); err != nil { return err @@ -128,22 +142,82 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { case "constructor": abi.Constructor = Method{ Inputs: field.Inputs, + + // Note for constructor the `StateMutability` can only + // be payable or nonpayable according to the output of + // compiler. So constant is always false. + StateMutability: field.StateMutability, + + // Legacy fields, keep them for backward compatibility + Constant: field.Constant, + Payable: field.Payable, } - // empty defaults to function according to the abi spec - case "function", "": + case "function": name := field.Name _, ok := abi.Methods[name] for idx := 0; ok; idx++ { name = fmt.Sprintf("%s%d", field.Name, idx) _, ok = abi.Methods[name] } - isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view" abi.Methods[name] = Method{ - Name: name, - RawName: field.Name, - Const: isConst, - Inputs: field.Inputs, - Outputs: field.Outputs, + Name: name, + RawName: field.Name, + StateMutability: field.StateMutability, + Inputs: field.Inputs, + Outputs: field.Outputs, + + // Legacy fields, keep them for backward compatibility + Constant: field.Constant, + Payable: field.Payable, + } + case "fallback": + // New introduced function type in v0.6.0, check more detail + // here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function + if abi.HasFallback() { + return errors.New("only single fallback is allowed") + } + abi.Fallback = Method{ + Name: "", + RawName: "", + + // The `StateMutability` can only be payable or nonpayable, + // so the constant is always false. + StateMutability: field.StateMutability, + IsFallback: true, + + // Fallback doesn't have any input or output + Inputs: nil, + Outputs: nil, + + // Legacy fields, keep them for backward compatibility + Constant: field.Constant, + Payable: field.Payable, + } + case "receive": + // New introduced function type in v0.6.0, check more detail + // here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function + if abi.HasReceive() { + return errors.New("only single receive is allowed") + } + if field.StateMutability != "payable" { + return errors.New("the statemutability of receive can only be payable") + } + abi.Receive = Method{ + Name: "", + RawName: "", + + // The `StateMutability` can only be payable, so constant + // is always true while payable is always false. + StateMutability: field.StateMutability, + IsReceive: true, + + // Receive doesn't have any input or output + Inputs: nil, + Outputs: nil, + + // Legacy fields, keep them for backward compatibility + Constant: field.Constant, + Payable: field.Payable, } case "event": name := field.Name @@ -160,7 +234,6 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } } } - return nil } @@ -189,6 +262,16 @@ func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { return nil, fmt.Errorf("no event with id: %#x", topic.Hex()) } +// HasFallback returns an indicator whether a fallback function is included. +func (abi *ABI) HasFallback() bool { + return abi.Fallback.IsFallback +} + +// HasReceive returns an indicator whether a receive function is included. +func (abi *ABI) HasReceive() bool { + return abi.Receive.IsReceive +} + // revertSelector is a special function selector for revert reason unpacking. var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index fab84ec9fa..5294943407 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -33,29 +33,29 @@ import ( const jsondata = ` [ - { "type" : "function", "name" : "balance", "constant" : true }, - { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] } + { "type" : "function", "name" : "balance", "stateMutability" : "view" }, + { "type" : "function", "name" : "send", "inputs" : [ { "name" : "amount", "type" : "uint256" } ] } ]` const jsondata2 = ` [ - { "type" : "function", "name" : "balance", "constant" : true }, - { "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, - { "type" : "function", "name" : "test", "constant" : false, "inputs" : [ { "name" : "number", "type" : "uint32" } ] }, - { "type" : "function", "name" : "string", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "string" } ] }, - { "type" : "function", "name" : "bool", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "bool" } ] }, - { "type" : "function", "name" : "address", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address" } ] }, - { "type" : "function", "name" : "uint64[2]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] }, - { "type" : "function", "name" : "uint64[]", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] }, - { "type" : "function", "name" : "foo", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, - { "type" : "function", "name" : "bar", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, - { "type" : "function", "name" : "slice", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, - { "type" : "function", "name" : "slice256", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }, - { "type" : "function", "name" : "sliceAddress", "constant" : false, "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] }, - { "type" : "function", "name" : "sliceMultiAddress", "constant" : false, "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }, - { "type" : "function", "name" : "nestedArray", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint256[2][2]" }, { "name" : "b", "type" : "address[]" } ] }, - { "type" : "function", "name" : "nestedArray2", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint8[][2]" } ] }, - { "type" : "function", "name" : "nestedSlice", "constant" : false, "inputs" : [ { "name" : "a", "type" : "uint8[][]" } ] } + { "type" : "function", "name" : "balance", "stateMutability" : "view" }, + { "type" : "function", "name" : "send", "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, + { "type" : "function", "name" : "test", "inputs" : [ { "name" : "number", "type" : "uint32" } ] }, + { "type" : "function", "name" : "string", "inputs" : [ { "name" : "inputs", "type" : "string" } ] }, + { "type" : "function", "name" : "bool", "inputs" : [ { "name" : "inputs", "type" : "bool" } ] }, + { "type" : "function", "name" : "address", "inputs" : [ { "name" : "inputs", "type" : "address" } ] }, + { "type" : "function", "name" : "uint64[2]", "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] }, + { "type" : "function", "name" : "uint64[]", "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] }, + { "type" : "function", "name" : "foo", "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, + { "type" : "function", "name" : "bar", "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, + { "type" : "function", "name" : "slice", "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, + { "type" : "function", "name" : "slice256", "inputs" : [ { "name" : "inputs", "type" : "uint256[2]" } ] }, + { "type" : "function", "name" : "sliceAddress", "inputs" : [ { "name" : "inputs", "type" : "address[]" } ] }, + { "type" : "function", "name" : "sliceMultiAddress", "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }, + { "type" : "function", "name" : "nestedArray", "inputs" : [ { "name" : "a", "type" : "uint256[2][2]" }, { "name" : "b", "type" : "address[]" } ] }, + { "type" : "function", "name" : "nestedArray2", "inputs" : [ { "name" : "a", "type" : "uint8[][2]" } ] }, + { "type" : "function", "name" : "nestedSlice", "inputs" : [ { "name" : "a", "type" : "uint8[][]" } ] } ]` func TestReader(t *testing.T) { @@ -63,10 +63,10 @@ func TestReader(t *testing.T) { exp := ABI{ Methods: map[string]Method{ "balance": { - "balance", "balance", true, nil, nil, + "balance", "balance", "view", false, false, false, false, nil, nil, }, "send": { - "send", "send", false, []Argument{ + "send", "send", "", false, false, false, false, []Argument{ {"amount", Uint256, false}, }, nil, }, @@ -175,7 +175,7 @@ func TestTestSlice(t *testing.T) { func TestMethodSignature(t *testing.T) { String, _ := NewType("string", "", nil) - m := Method{"foo", "foo", false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} + m := Method{"foo", "foo", "", false, false, false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} exp := "foo(string,string)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) @@ -187,7 +187,7 @@ func TestMethodSignature(t *testing.T) { } uintt, _ := NewType("uint256", "", nil) - m = Method{"foo", "foo", false, []Argument{{"bar", uintt, false}}, nil} + m = Method{"foo", "foo", "", false, false, false, false, []Argument{{"bar", uintt, false}}, nil} exp = "foo(uint256)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) @@ -206,7 +206,7 @@ func TestMethodSignature(t *testing.T) { {Name: "y", Type: "int256"}, }}, }) - m = Method{"foo", "foo", false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} + m = Method{"foo", "foo", "", false, false, false, false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} exp = "foo((int256,int256[],(int256,int256)[],(int256,int256)[2]),string)" if m.Sig() != exp { t.Error("signature mismatch", exp, "!=", m.Sig()) @@ -585,7 +585,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) { } func TestDefaultFunctionParsing(t *testing.T) { - const definition = `[{ "name" : "balance" }]` + const definition = `[{ "name" : "balance", "type" : "function" }]` abi, err := JSON(strings.NewReader(definition)) if err != nil { diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 21fafefcf8..ee57edb871 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -179,12 +179,24 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in if err != nil { return nil, err } + // todo(rjl493456442) check the method is payable or not, + // reject invalid transaction at the first place return c.transact(opts, &c.address, input) } +// RawTransact initiates a transaction with the given raw calldata as the input. +// It's usually used to initiates transaction for invoking **Fallback** function. +func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) { + // todo(rjl493456442) check the method is payable or not, + // reject invalid transaction at the first place + return c.transact(opts, &c.address, calldata) +} + // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) { + // todo(rjl493456442) check the payable fallback or receive is defined + // or not, reject invalid transaction at the first place return c.transact(opts, &c.address, nil) } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index f7b5023f9d..bbf0af9c72 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -74,6 +74,8 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] calls = make(map[string]*tmplMethod) transacts = make(map[string]*tmplMethod) events = make(map[string]*tmplEvent) + fallback *tmplMethod + receive *tmplMethod // identifiers are used to detect duplicated identifier of function // and event. For all calls, transacts and events, abigen will generate @@ -89,7 +91,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) // Ensure there is no duplicated identifier var identifiers = callIdentifiers - if !original.Const { + if !original.IsConstant() { identifiers = transactIdentifiers } if identifiers[normalizedName] { @@ -118,7 +120,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] } } // Append the methods to the call or transact lists - if original.Const { + if original.IsConstant() { calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} } else { transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)} @@ -153,14 +155,23 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Append the event to the accumulator list events[original.Name] = &tmplEvent{Original: original, Normalized: normalized} } + // Add two special fallback functions if they exist + if evmABI.HasFallback() { + fallback = &tmplMethod{Original: evmABI.Fallback} + } + if evmABI.HasReceive() { + receive = &tmplMethod{Original: evmABI.Receive} + } contracts[types[i]] = &tmplContract{ Type: capitalise(types[i]), - InputABI: strings.ReplaceAll(strippedABI, "\"", "\\\""), + InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1), InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"), Constructor: evmABI.Constructor, Calls: calls, Transacts: transacts, + Fallback: fallback, + Receive: receive, Events: events, Libraries: make(map[string]string), } @@ -451,11 +462,22 @@ func formatMethod(method abi.Method, structs map[string]*tmplStruct) string { outputs[i] += fmt.Sprintf(" %v", output.Name) } } - constant := "" - if method.Const { - constant = "constant " + // Extract meaningful state mutability of solidity method. + // If it's default value, never print it. + state := method.StateMutability + if state == "nonpayable" { + state = "" } - return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) + if state != "" { + state = state + " " + } + identity := fmt.Sprintf("function %v", method.RawName) + if method.IsFallback { + identity = "fallback" + } else if method.IsReceive { + identity = "receive" + } + return fmt.Sprintf("%s(%v) %sreturns(%v)", identity, strings.Join(inputs, ", "), state, strings.Join(outputs, ", ")) } // formatEvent transforms raw event representation into a user friendly one. diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 22cd418daf..d8edd86e2e 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1236,6 +1236,100 @@ var bindTests = []struct { nil, []string{"ContractOne", "ContractTwo", "ExternalLib"}, }, + // Test fallback separation introduced in v0.6.0 + { + `NewFallbacks`, + ` + pragma solidity >=0.6.0 <0.7.0; + + contract NewFallbacks { + event Fallback(bytes data); + fallback() external { + bytes memory data; + assembly { + calldatacopy(data, 0, calldatasize()) + } + emit Fallback(data); + } + + event Received(address addr, uint value); + receive() external payable { + emit Received(msg.sender, msg.value); + } + } + `, + []string{"60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040526004361061000d575b36610081575b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b005b34801561008e5760006000fd5b505b606036600082377f9043988963722edecc2099c75b0af0ff76af14ffca42ed6bce059a20a2a9f986816040518080602001828103825283818151815260200191508051906020019080838360005b838110156100fa5780820151818401525b6020810190506100de565b50505050905090810190601f1680156101275780820380516001836020036101000a031916815260200191505b509250505060405180910390a1505b00fea26469706673582212205643ca37f40c2b352dc541f42e9e6720de065de756324b7fcc9fb1d67eda4a7d64736f6c63430006040033"}, + []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Fallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Received","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]`}, + ` + "bytes" + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + opts := bind.NewKeyedTransactor(key) + _, _, c, err := DeployNewFallbacks(opts, sim) + if err != nil { + t.Fatalf("Failed to deploy contract: %v", err) + } + sim.Commit() + + // Test receive function + opts.Value = big.NewInt(100) + c.Receive(opts) + sim.Commit() + + var gotEvent bool + iter, _ := c.FilterReceived(nil) + defer iter.Close() + for iter.Next() { + if iter.Event.Addr != addr { + t.Fatal("Msg.sender mismatch") + } + if iter.Event.Value.Uint64() != 100 { + t.Fatal("Msg.value mismatch") + } + gotEvent = true + break + } + if !gotEvent { + t.Fatal("Expect to receive event emitted by receive") + } + + // Test fallback function + opts.Value = nil + calldata := []byte{0x01, 0x02, 0x03} + c.Fallback(opts, calldata) + sim.Commit() + + iter2, _ := c.FilterFallback(nil) + defer iter2.Close() + for iter2.Next() { + if !bytes.Equal(iter2.Event.Data, calldata) { + t.Fatal("calldata mismatch") + } + gotEvent = true + break + } + if !gotEvent { + t.Fatal("Expect to receive event emitted by fallback") + } + `, + nil, + nil, + nil, + nil, + }, } // Tests that packages generated by the binder can be successfully compiled and diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 1c1a7255cd..00d38a6a1e 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -35,6 +35,8 @@ type tmplContract struct { Constructor abi.Method // Contract constructor for deploy parametrization Calls map[string]*tmplMethod // Contract calls that only read state data Transacts map[string]*tmplMethod // Contract calls that write state data + Fallback *tmplMethod // Additional special fallback function + Receive *tmplMethod // Additional special receive function Events map[string]*tmplEvent // Contract events accessors Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs Library bool // Indicator whether the contract is a library @@ -349,6 +351,52 @@ var ( } {{end}} + {{if .Fallback}} + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{formatmethod .Fallback.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{formatmethod .Fallback.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{formatmethod .Fallback.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + {{end}} + + {{if .Receive}} + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{formatmethod .Receive.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{formatmethod .Receive.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{formatmethod .Receive.Original $structs}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + {{end}} + {{range .Events}} // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract. type {{$contract.Type}}{{.Normalized.Name}}Iterator struct { diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 7acbd4847e..3fe3a3954d 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -41,10 +41,23 @@ type Method struct { // * foo(uint,uint) // The method name of the first one will be resolved as foo while the second one // will be resolved as foo0. - Name string - // RawName is the raw method name parsed from ABI. - RawName string - Const bool + Name string + RawName string // RawName is the raw method name parsed from ABI + + // StateMutability indicates the mutability state of method, + // the default value is nonpayable. It can be empty if the abi + // is generated by legacy compiler. + StateMutability string + + // Legacy indicators generated by compiler before v0.6.0 + Constant bool + Payable bool + + // The following two flags indicates whether the method is a + // special fallback introduced in solidity v0.6.0 + IsFallback bool + IsReceive bool + Inputs Arguments Outputs Arguments } @@ -57,6 +70,11 @@ type Method struct { // // Please note that "int" is substitute for its canonical representation "int256" func (method Method) Sig() string { + // Short circuit if the method is special. Fallback + // and Receive don't have signature at all. + if method.IsFallback || method.IsReceive { + return "" + } types := make([]string, len(method.Inputs)) for i, input := range method.Inputs { types[i] = input.Type.String() @@ -76,11 +94,22 @@ func (method Method) String() string { outputs[i] += fmt.Sprintf(" %v", output.Name) } } - constant := "" - if method.Const { - constant = "constant " + // Extract meaningful state mutability of solidity method. + // If it's default value, never print it. + state := method.StateMutability + if state == "nonpayable" { + state = "" } - return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", ")) + if state != "" { + state = state + " " + } + identity := fmt.Sprintf("function %v", method.RawName) + if method.IsFallback { + identity = "fallback" + } else if method.IsReceive { + identity = "receive" + } + return fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputs, ", "), state, strings.Join(outputs, ", ")) } // ID returns the canonical representation of the method's signature used by the @@ -88,3 +117,14 @@ func (method Method) String() string { func (method Method) ID() []byte { return crypto.Keccak256([]byte(method.Sig()))[:4] } + +// IsConstant returns the indicator whether the method is read-only. +func (method Method) IsConstant() bool { + return method.StateMutability == "view" || method.StateMutability == "pure" || method.Constant +} + +// IsPayable returns the indicator whether the method can process +// plain ether transfers. +func (method Method) IsPayable() bool { + return method.StateMutability == "payable" || method.Payable +} diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go index 92c360f0d2..66e53d8a29 100644 --- a/accounts/abi/method_test.go +++ b/accounts/abi/method_test.go @@ -23,13 +23,15 @@ import ( const methoddata = ` [ - {"type": "function", "name": "balance", "constant": true }, - {"type": "function", "name": "send", "constant": false, "inputs": [{ "name": "amount", "type": "uint256" }]}, - {"type": "function", "name": "transfer", "constant": false, "inputs": [{"name": "from", "type": "address"}, {"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}], "outputs": [{"name": "success", "type": "bool"}]}, + {"type": "function", "name": "balance", "stateMutability": "view"}, + {"type": "function", "name": "send", "inputs": [{ "name": "amount", "type": "uint256" }]}, + {"type": "function", "name": "transfer", "inputs": [{"name": "from", "type": "address"}, {"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}], "outputs": [{"name": "success", "type": "bool"}]}, {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple"}],"name":"tuple","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[]"}],"name":"tupleSlice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[5]"}],"name":"tupleArray","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, - {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[5][]"}],"name":"complexTuple","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"} + {"constant":false,"inputs":[{"components":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"a","type":"tuple[5][]"}],"name":"complexTuple","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}, + {"stateMutability":"nonpayable","type":"fallback"}, + {"stateMutability":"payable","type":"receive"} ]` func TestMethodString(t *testing.T) { @@ -39,7 +41,7 @@ func TestMethodString(t *testing.T) { }{ { method: "balance", - expectation: "function balance() constant returns()", + expectation: "function balance() view returns()", }, { method: "send", @@ -65,6 +67,14 @@ func TestMethodString(t *testing.T) { method: "complexTuple", expectation: "function complexTuple((uint256,uint256)[5][] a) returns()", }, + { + method: "fallback", + expectation: "fallback() returns()", + }, + { + method: "receive", + expectation: "receive() payable returns()", + }, } abi, err := JSON(strings.NewReader(methoddata)) @@ -73,7 +83,14 @@ func TestMethodString(t *testing.T) { } for _, test := range table { - got := abi.Methods[test.method].String() + var got string + if test.method == "fallback" { + got = abi.Fallback.String() + } else if test.method == "receive" { + got = abi.Receive.String() + } else { + got = abi.Methods[test.method].String() + } if got != test.expectation { t.Errorf("expected string to be %s, got %s", test.expectation, got) } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index d788224d3c..c0525390f8 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -443,7 +443,7 @@ var unpackTests = []unpackTest{ func TestUnpack(t *testing.T) { for i, test := range unpackTests { t.Run(strconv.Itoa(i), func(t *testing.T) { - def := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def) + def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) abi, err := JSON(strings.NewReader(def)) if err != nil { t.Fatalf("invalid ABI definition %s: %v", def, err) @@ -522,7 +522,7 @@ type methodMultiOutput struct { func methodMultiReturn(require *require.Assertions) (ABI, []byte, methodMultiOutput) { const definition = `[ - { "name" : "multi", "constant" : false, "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]` + { "name" : "multi", "type": "function", "outputs": [ { "name": "Int", "type": "uint256" }, { "name": "String", "type": "string" } ] }]` var expected = methodMultiOutput{big.NewInt(1), "hello"} abi, err := JSON(strings.NewReader(definition)) @@ -611,7 +611,7 @@ func TestMethodMultiReturn(t *testing.T) { } func TestMultiReturnWithArray(t *testing.T) { - const definition = `[{"name" : "multi", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]` + const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { t.Fatal(err) @@ -634,7 +634,7 @@ func TestMultiReturnWithArray(t *testing.T) { } func TestMultiReturnWithStringArray(t *testing.T) { - const definition = `[{"name" : "multi", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]` + const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { t.Fatal(err) @@ -664,7 +664,7 @@ func TestMultiReturnWithStringArray(t *testing.T) { } func TestMultiReturnWithStringSlice(t *testing.T) { - const definition = `[{"name" : "multi", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]` + const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { t.Fatal(err) @@ -700,7 +700,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { // values of nested static arrays count towards the size as well, and any element following // after such nested array argument should be read with the correct offset, // so that it does not read content from the previous array argument. - const definition = `[{"name" : "multi", "outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]` + const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3][2][4]"}, {"type": "uint64"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { t.Fatal(err) @@ -737,15 +737,15 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { func TestUnmarshal(t *testing.T) { const definition = `[ - { "name" : "int", "constant" : false, "outputs": [ { "type": "uint256" } ] }, - { "name" : "bool", "constant" : false, "outputs": [ { "type": "bool" } ] }, - { "name" : "bytes", "constant" : false, "outputs": [ { "type": "bytes" } ] }, - { "name" : "fixed", "constant" : false, "outputs": [ { "type": "bytes32" } ] }, - { "name" : "multi", "constant" : false, "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] }, - { "name" : "intArraySingle", "constant" : false, "outputs": [ { "type": "uint256[3]" } ] }, - { "name" : "addressSliceSingle", "constant" : false, "outputs": [ { "type": "address[]" } ] }, - { "name" : "addressSliceDouble", "constant" : false, "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] }, - { "name" : "mixedBytes", "constant" : true, "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]` + { "name" : "int", "type": "function", "outputs": [ { "type": "uint256" } ] }, + { "name" : "bool", "type": "function", "outputs": [ { "type": "bool" } ] }, + { "name" : "bytes", "type": "function", "outputs": [ { "type": "bytes" } ] }, + { "name" : "fixed", "type": "function", "outputs": [ { "type": "bytes32" } ] }, + { "name" : "multi", "type": "function", "outputs": [ { "type": "bytes" }, { "type": "bytes" } ] }, + { "name" : "intArraySingle", "type": "function", "outputs": [ { "type": "uint256[3]" } ] }, + { "name" : "addressSliceSingle", "type": "function", "outputs": [ { "type": "address[]" } ] }, + { "name" : "addressSliceDouble", "type": "function", "outputs": [ { "name": "a", "type": "address[]" }, { "name": "b", "type": "address[]" } ] }, + { "name" : "mixedBytes", "type": "function", "stateMutability" : "view", "outputs": [ { "name": "a", "type": "bytes" }, { "name": "b", "type": "bytes32" } ] }]` abi, err := JSON(strings.NewReader(definition)) if err != nil { @@ -985,7 +985,7 @@ func TestUnmarshal(t *testing.T) { } func TestUnpackTuple(t *testing.T) { - const simpleTuple = `[{"name":"tuple","constant":false,"outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]` + const simpleTuple = `[{"name":"tuple","type":"function","outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]` abi, err := JSON(strings.NewReader(simpleTuple)) if err != nil { t.Fatal(err) @@ -1014,7 +1014,7 @@ func TestUnpackTuple(t *testing.T) { } // Test nested tuple - const nestedTuple = `[{"name":"tuple","constant":false,"outputs":[ + const nestedTuple = `[{"name":"tuple","type":"function","outputs":[ {"type":"tuple","name":"s","components":[{"type":"uint256","name":"a"},{"type":"uint256[]","name":"b"},{"type":"tuple[]","name":"c","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}]}, {"type":"tuple","name":"t","components":[{"name":"x", "type":"uint256"},{"name":"y","type":"uint256"}]}, {"type":"uint256","name":"a"} @@ -1136,7 +1136,7 @@ func TestOOMMaliciousInput(t *testing.T) { }, } for i, test := range oomTests { - def := fmt.Sprintf(`[{ "name" : "method", "outputs": %s}]`, test.def) + def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) abi, err := JSON(strings.NewReader(def)) if err != nil { t.Fatalf("invalid ABI definition %s: %v", def, err) From 56f9c1781786d72d5b9a6ff4309caa2851873228 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 104/280] accounts/abi: Prevent recalculation of internal fields (#20895) * accounts/abi: prevent recalculation of ID, Sig and String * accounts/abi: fixed unpacking of no values * accounts/abi: multiple fixes to arguments * accounts/abi: refactored methodName and eventName This commit moves the complicated logic of how we assign method names and event names if they already exist into their own functions for better readability. * accounts/abi: prevent recalculation of internal In this commit, I changed the way we calculate the string representations, sig representations and the id's of methods. Before that these fields would be recalculated everytime someone called .Sig() .String() or .ID() on a method or an event. Additionally this commit fixes issue #20856 as we assign names to inputs with no name (input with name "" becomes "arg0") * accounts/abi: added unnamed event params test * accounts/abi: fixed rebasing errors in method sig * accounts/abi: fixed rebasing errors in method sig * accounts/abi: addressed comments * accounts/abi: added FunctionType enumeration * accounts/abi/bind: added test for unnamed arguments * accounts/abi: improved readability in NewMethod, nitpicks * accounts/abi: method/eventName -> overloadedMethodName --- accounts/abi/abi.go | 124 ++++++++++++--------------------- accounts/abi/abi_test.go | 77 ++++++++++++-------- accounts/abi/argument.go | 55 +++++++-------- accounts/abi/bind/base.go | 6 +- accounts/abi/bind/bind.go | 4 +- accounts/abi/bind/bind_test.go | 9 ++- accounts/abi/event.go | 81 +++++++++++++-------- accounts/abi/event_test.go | 4 +- accounts/abi/method.go | 119 ++++++++++++++++++++----------- accounts/abi/method_test.go | 2 +- accounts/abi/pack_test.go | 14 ++-- accounts/abi/reflect.go | 17 ++--- 12 files changed, 276 insertions(+), 236 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index c65d22d8ed..4906858378 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -77,7 +77,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { return nil, err } // Pack up the method ID too if not a constructor and return - return append(method.ID(), arguments...), nil + return append(method.ID, arguments...), nil } // Unpack output in v according to the abi specification @@ -140,59 +140,17 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { for _, field := range fields { switch field.Type { case "constructor": - abi.Constructor = Method{ - Inputs: field.Inputs, - - // Note for constructor the `StateMutability` can only - // be payable or nonpayable according to the output of - // compiler. So constant is always false. - StateMutability: field.StateMutability, - - // Legacy fields, keep them for backward compatibility - Constant: field.Constant, - Payable: field.Payable, - } + abi.Constructor = NewMethod("", "", Constructor, field.StateMutability, field.Constant, field.Payable, field.Inputs, nil) case "function": - name := field.Name - _, ok := abi.Methods[name] - for idx := 0; ok; idx++ { - name = fmt.Sprintf("%s%d", field.Name, idx) - _, ok = abi.Methods[name] - } - abi.Methods[name] = Method{ - Name: name, - RawName: field.Name, - StateMutability: field.StateMutability, - Inputs: field.Inputs, - Outputs: field.Outputs, - - // Legacy fields, keep them for backward compatibility - Constant: field.Constant, - Payable: field.Payable, - } + name := abi.overloadedMethodName(field.Name) + abi.Methods[name] = NewMethod(name, field.Name, Function, field.StateMutability, field.Constant, field.Payable, field.Inputs, field.Outputs) case "fallback": // New introduced function type in v0.6.0, check more detail // here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function if abi.HasFallback() { return errors.New("only single fallback is allowed") } - abi.Fallback = Method{ - Name: "", - RawName: "", - - // The `StateMutability` can only be payable or nonpayable, - // so the constant is always false. - StateMutability: field.StateMutability, - IsFallback: true, - - // Fallback doesn't have any input or output - Inputs: nil, - Outputs: nil, - - // Legacy fields, keep them for backward compatibility - Constant: field.Constant, - Payable: field.Payable, - } + abi.Fallback = NewMethod("", "", Fallback, field.StateMutability, field.Constant, field.Payable, nil, nil) case "receive": // New introduced function type in v0.6.0, check more detail // here https://solidity.readthedocs.io/en/v0.6.0/contracts.html#fallback-function @@ -202,41 +160,47 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { if field.StateMutability != "payable" { return errors.New("the statemutability of receive can only be payable") } - abi.Receive = Method{ - Name: "", - RawName: "", - - // The `StateMutability` can only be payable, so constant - // is always true while payable is always false. - StateMutability: field.StateMutability, - IsReceive: true, - - // Receive doesn't have any input or output - Inputs: nil, - Outputs: nil, - - // Legacy fields, keep them for backward compatibility - Constant: field.Constant, - Payable: field.Payable, - } + abi.Receive = NewMethod("", "", Receive, field.StateMutability, field.Constant, field.Payable, nil, nil) case "event": - name := field.Name - _, ok := abi.Events[name] - for idx := 0; ok; idx++ { - name = fmt.Sprintf("%s%d", field.Name, idx) - _, ok = abi.Events[name] - } - abi.Events[name] = Event{ - Name: name, - RawName: field.Name, - Anonymous: field.Anonymous, - Inputs: field.Inputs, - } + name := abi.overloadedEventName(field.Name) + abi.Events[name] = NewEvent(name, field.Name, field.Anonymous, field.Inputs) + default: + return fmt.Errorf("abi: could not recognize type %v of field %v", field.Type, field.Name) } } return nil } +// overloadedMethodName returns the next available name for a given function. +// Needed since solidity allows for function overload. +// +// e.g. if the abi contains Methods send, send1 +// overloadedMethodName would return send2 for input send. +func (abi *ABI) overloadedMethodName(rawName string) string { + name := rawName + _, ok := abi.Methods[name] + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", rawName, idx) + _, ok = abi.Methods[name] + } + return name +} + +// overloadedEventName returns the next available name for a given event. +// Needed since solidity allows for event overload. +// +// e.g. if the abi contains events received, received1 +// overloadedEventName would return received2 for input received. +func (abi *ABI) overloadedEventName(rawName string) string { + name := rawName + _, ok := abi.Events[name] + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", rawName, idx) + _, ok = abi.Events[name] + } + return name +} + // MethodById looks up a method by the 4-byte id // returns nil if none found func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { @@ -244,7 +208,7 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata)) } for _, method := range abi.Methods { - if bytes.Equal(method.ID(), sigdata[:4]) { + if bytes.Equal(method.ID, sigdata[:4]) { return &method, nil } } @@ -255,7 +219,7 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { // ABI and returns nil if none found. func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { for _, event := range abi.Events { - if bytes.Equal(event.ID().Bytes(), topic.Bytes()) { + if bytes.Equal(event.ID.Bytes(), topic.Bytes()) { return &event, nil } } @@ -264,12 +228,12 @@ func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { // HasFallback returns an indicator whether a fallback function is included. func (abi *ABI) HasFallback() bool { - return abi.Fallback.IsFallback + return abi.Fallback.Type == Fallback } // HasReceive returns an indicator whether a receive function is included. func (abi *ABI) HasReceive() bool { - return abi.Receive.IsReceive + return abi.Receive.Type == Receive } // revertSelector is a special function selector for revert reason unpacking. diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 5294943407..8f616e07cf 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -60,20 +60,14 @@ const jsondata2 = ` func TestReader(t *testing.T) { Uint256, _ := NewType("uint256", "", nil) - exp := ABI{ + abi := ABI{ Methods: map[string]Method{ - "balance": { - "balance", "balance", "view", false, false, false, false, nil, nil, - }, - "send": { - "send", "send", "", false, false, false, false, []Argument{ - {"amount", Uint256, false}, - }, nil, - }, + "balance": NewMethod("balance", "balance", Function, "view", false, false, nil, nil), + "send": NewMethod("send", "send", Function, "", false, false, []Argument{{"amount", Uint256, false}}, nil), }, } - abi, err := JSON(strings.NewReader(jsondata)) + exp, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Error(err) } @@ -175,22 +169,22 @@ func TestTestSlice(t *testing.T) { func TestMethodSignature(t *testing.T) { String, _ := NewType("string", "", nil) - m := Method{"foo", "foo", "", false, false, false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil} + m := NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil) exp := "foo(string,string)" - if m.Sig() != exp { - t.Error("signature mismatch", exp, "!=", m.Sig()) + if m.Sig != exp { + t.Error("signature mismatch", exp, "!=", m.Sig) } idexp := crypto.Keccak256([]byte(exp))[:4] - if !bytes.Equal(m.ID(), idexp) { - t.Errorf("expected ids to match %x != %x", m.ID(), idexp) + if !bytes.Equal(m.ID, idexp) { + t.Errorf("expected ids to match %x != %x", m.ID, idexp) } uintt, _ := NewType("uint256", "", nil) - m = Method{"foo", "foo", "", false, false, false, false, []Argument{{"bar", uintt, false}}, nil} + m = NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", uintt, false}}, nil) exp = "foo(uint256)" - if m.Sig() != exp { - t.Error("signature mismatch", exp, "!=", m.Sig()) + if m.Sig != exp { + t.Error("signature mismatch", exp, "!=", m.Sig) } // Method with tuple arguments @@ -206,10 +200,10 @@ func TestMethodSignature(t *testing.T) { {Name: "y", Type: "int256"}, }}, }) - m = Method{"foo", "foo", "", false, false, false, false, []Argument{{"s", s, false}, {"bar", String, false}}, nil} + m = NewMethod("foo", "foo", Function, "", false, false, []Argument{{"s", s, false}, {"bar", String, false}}, nil) exp = "foo((int256,int256[],(int256,int256)[],(int256,int256)[2]),string)" - if m.Sig() != exp { - t.Error("signature mismatch", exp, "!=", m.Sig()) + if m.Sig != exp { + t.Error("signature mismatch", exp, "!=", m.Sig) } } @@ -221,12 +215,12 @@ func TestOverloadedMethodSignature(t *testing.T) { } check := func(name string, expect string, method bool) { if method { - if abi.Methods[name].Sig() != expect { - t.Fatalf("The signature of overloaded method mismatch, want %s, have %s", expect, abi.Methods[name].Sig()) + if abi.Methods[name].Sig != expect { + t.Fatalf("The signature of overloaded method mismatch, want %s, have %s", expect, abi.Methods[name].Sig) } } else { - if abi.Events[name].Sig() != expect { - t.Fatalf("The signature of overloaded event mismatch, want %s, have %s", expect, abi.Events[name].Sig()) + if abi.Events[name].Sig != expect { + t.Fatalf("The signature of overloaded event mismatch, want %s, have %s", expect, abi.Events[name].Sig) } } } @@ -927,13 +921,13 @@ func TestABI_MethodById(t *testing.T) { } for name, m := range abi.Methods { a := fmt.Sprintf("%v", m) - m2, err := abi.MethodById(m.ID()) + m2, err := abi.MethodById(m.ID) if err != nil { t.Fatalf("Failed to look up ABI method: %v", err) } b := fmt.Sprintf("%v", m2) if a != b { - t.Errorf("Method %v (id %x) not 'findable' by id in ABI", name, m.ID()) + t.Errorf("Method %v (id %x) not 'findable' by id in ABI", name, m.ID) } } // Also test empty @@ -1032,8 +1026,8 @@ func TestABI_EventById(t *testing.T) { t.Errorf("We should find a event for topic %s, test #%d", topicID.Hex(), testnum) } - if event.ID() != topicID { - t.Errorf("Event id %s does not match topic %s, test #%d", event.ID().Hex(), topicID.Hex(), testnum) + if event.ID != topicID { + t.Errorf("Event id %s does not match topic %s, test #%d", event.ID.Hex(), topicID.Hex(), testnum) } unknowntopicID := crypto.Keccak256Hash([]byte("unknownEvent")) @@ -1088,3 +1082,28 @@ func TestDoubleDuplicateMethodNames(t *testing.T) { t.Fatalf("Should not have found extra method") } } + +// TestUnnamedEventParam checks that an event with unnamed parameters is +// correctly handled +// The test runs the abi of the following contract. +// contract TestEvent { +// event send(uint256, uint256); +// } +func TestUnnamedEventParam(t *testing.T) { + abiJSON := `[{ "anonymous": false, "inputs": [{ "indexed": false,"internalType": "uint256", "name": "","type": "uint256"},{"indexed": false,"internalType": "uint256","name": "","type": "uint256"}],"name": "send","type": "event"}]` + contractAbi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + + event, ok := contractAbi.Events["send"] + if !ok { + t.Fatalf("Could not find event") + } + if event.Inputs[0].Name != "arg0" { + t.Fatalf("Could not find input") + } + if event.Inputs[1].Name != "arg1" { + t.Fatalf("Could not find input") + } +} diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 39b257c55c..a5ee9839e7 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -93,9 +93,8 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { if len(data) == 0 { if len(arguments) != 0 { return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") - } else { - return nil // Nothing to unmarshal, return } + return nil // Nothing to unmarshal, return } // make sure the passed value is arguments pointer if reflect.Ptr != reflect.ValueOf(v).Kind() { @@ -105,6 +104,9 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { if err != nil { return err } + if len(marshalledValues) == 0 { + return fmt.Errorf("abi: Unpack(no-values unmarshalled %T)", v) + } if arguments.isTuple() { return arguments.unpackTuple(v, marshalledValues) } @@ -124,18 +126,24 @@ func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { // UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { + // Make sure map is not nil + if v == nil { + return fmt.Errorf("abi: cannot unpack into a nil map") + } if len(data) == 0 { if len(arguments) != 0 { return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") - } else { - return nil // Nothing to unmarshal, return } + return nil // Nothing to unmarshal, return } marshalledValues, err := arguments.UnpackValues(data) if err != nil { return err } - return arguments.unpackIntoMap(v, marshalledValues) + for i, arg := range arguments.NonIndexed() { + v[arg.Name] = marshalledValues[i] + } + return nil } // unpack sets the unmarshalled value to go format. @@ -207,19 +215,6 @@ func unpack(t *Type, dst interface{}, src interface{}) error { return nil } -// unpackIntoMap unpacks marshalledValues into the provided map[string]interface{} -func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error { - // Make sure map is not nil - if v == nil { - return fmt.Errorf("abi: cannot unpack into a nil map") - } - - for i, arg := range arguments.NonIndexed() { - v[arg.Name] = marshalledValues[i] - } - return nil -} - // unpackAtomic unpacks ( hexdata -> go ) a single value func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { if arguments.LengthNonIndexed() == 0 { @@ -245,30 +240,28 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interfac // unpackTuple unpacks ( hexdata -> go ) a batch of values. func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { var ( - value = reflect.ValueOf(v).Elem() - typ = value.Type() - kind = value.Kind() + value = reflect.ValueOf(v).Elem() + typ = value.Type() + kind = value.Kind() + nonIndexedArgs = arguments.NonIndexed() ) - if err := requireUnpackKind(value, typ, kind, arguments); err != nil { + if err := requireUnpackKind(value, len(nonIndexedArgs), arguments); err != nil { return err } // If the interface is a struct, get of abi->struct_field mapping var abi2struct map[string]string if kind == reflect.Struct { - var ( - argNames []string - err error - ) - for _, arg := range arguments.NonIndexed() { - argNames = append(argNames, arg.Name) + argNames := make([]string, len(nonIndexedArgs)) + for i, arg := range nonIndexedArgs { + argNames[i] = arg.Name } - abi2struct, err = mapArgNamesToStructFields(argNames, value) - if err != nil { + var err error + if abi2struct, err = mapArgNamesToStructFields(argNames, value); err != nil { return err } } - for i, arg := range arguments.NonIndexed() { + for i, arg := range nonIndexedArgs { switch kind { case reflect.Struct: field := value.FieldByName(abi2struct[arg.Name]) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index ee57edb871..48b136ffbe 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -376,7 +376,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int opts = new(FilterOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].ID()}}, query...) + query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) topics, err := makeTopics(query...) if err != nil { @@ -422,7 +422,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter opts = new(WatchOpts) } // Append the event selector to the query parameters and construct the topic set - query = append([][]interface{}{{c.abi.Events[name].ID()}}, query...) + query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) topics, err := makeTopics(query...) if err != nil { @@ -451,7 +451,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) if len(log.Topics) == 0 { return errNoEventSignature } - if log.Topics[0] != c.abi.Events[event].ID() { + if log.Topics[0] != c.abi.Events[event].ID { return errors.New("event signature mismatch") } if len(log.Data) > 0 { diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index bbf0af9c72..a90f0492ca 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -472,9 +472,9 @@ func formatMethod(method abi.Method, structs map[string]*tmplStruct) string { state = state + " " } identity := fmt.Sprintf("function %v", method.RawName) - if method.IsFallback { + if method.Type == abi.Fallback { identity = "fallback" - } else if method.IsReceive { + } else if method.Type == abi.Receive { identity = "receive" } return fmt.Sprintf("%s(%v) %sreturns(%v)", identity, strings.Join(inputs, ", "), state, strings.Join(outputs, ", ")) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index d8edd86e2e..003cdf09e8 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -199,7 +199,8 @@ var bindTests = []struct { {"type":"event","name":"indexed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256","indexed":true}]}, {"type":"event","name":"mixed","inputs":[{"name":"addr","type":"address","indexed":true},{"name":"num","type":"int256"}]}, {"type":"event","name":"anonymous","anonymous":true,"inputs":[]}, - {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]} + {"type":"event","name":"dynamic","inputs":[{"name":"idxStr","type":"string","indexed":true},{"name":"idxDat","type":"bytes","indexed":true},{"name":"str","type":"string"},{"name":"dat","type":"bytes"}]}, + {"type":"event","name":"unnamed","inputs":[{"name":"","type":"uint256","indexed": true},{"name":"","type":"uint256","indexed":true}]} ] `}, ` @@ -249,6 +250,12 @@ var bindTests = []struct { fmt.Println(event.Addr) // Make sure the reconstructed indexed fields are present fmt.Println(res, str, dat, hash, err) + + oit, err := e.FilterUnnamed(nil, []*big.Int{}, []*big.Int{}) + + arg0 := oit.Event.Arg0 // Make sure unnamed arguments are handled correctly + arg1 := oit.Event.Arg1 // Make sure unnamed arguments are handled correctly + fmt.Println(arg0, arg1) } // Run a tiny reflection test to ensure disallowed methods don't appear if _, ok := reflect.TypeOf(&EventChecker{}).MethodByName("FilterAnonymous"); ok { diff --git a/accounts/abi/event.go b/accounts/abi/event.go index 3292caf8c3..db01a0f6bf 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -42,36 +42,59 @@ type Event struct { RawName string Anonymous bool Inputs Arguments + str string + // Sig contains the string signature according to the ABI spec. + // e.g. event foo(uint32 a, int b) = "foo(uint32,int256)" + // Please note that "int" is substitute for its canonical representation "int256" + Sig string + // ID returns the canonical representation of the event's signature used by the + // abi definition to identify event names and types. + ID common.Hash +} + +// NewEvent creates a new Event. +// It sanitizes the input arguments to remove unnamed arguments. +// It also precomputes the id, signature and string representation +// of the event. +func NewEvent(name, rawName string, anonymous bool, inputs Arguments) Event { + // sanitize inputs to remove inputs without names + // and precompute string and sig representation. + names := make([]string, len(inputs)) + types := make([]string, len(inputs)) + for i, input := range inputs { + if input.Name == "" { + inputs[i] = Argument{ + Name: fmt.Sprintf("arg%d", i), + Indexed: input.Indexed, + Type: input.Type, + } + } else { + inputs[i] = input + } + // string representation + names[i] = fmt.Sprintf("%v %v", input.Type, inputs[i].Name) + if input.Indexed { + names[i] = fmt.Sprintf("%v indexed %v", input.Type, inputs[i].Name) + } + // sig representation + types[i] = input.Type.String() + } + + str := fmt.Sprintf("event %v(%v)", rawName, strings.Join(names, ", ")) + sig := fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ",")) + id := common.BytesToHash(crypto.Keccak256([]byte(sig))) + + return Event{ + Name: name, + RawName: rawName, + Anonymous: anonymous, + Inputs: inputs, + str: str, + Sig: sig, + ID: id, + } } func (e Event) String() string { - inputs := make([]string, len(e.Inputs)) - for i, input := range e.Inputs { - inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name) - if input.Indexed { - inputs[i] = fmt.Sprintf("%v indexed %v", input.Type, input.Name) - } - } - return fmt.Sprintf("event %v(%v)", e.RawName, strings.Join(inputs, ", ")) -} - -// Sig returns the event string signature according to the ABI spec. -// -// Example -// -// event foo(uint32 a, int b) = "foo(uint32,int256)" -// -// Please note that "int" is substitute for its canonical representation "int256" -func (e Event) Sig() string { - types := make([]string, len(e.Inputs)) - for i, input := range e.Inputs { - types[i] = input.Type.String() - } - return fmt.Sprintf("%v(%v)", e.RawName, strings.Join(types, ",")) -} - -// ID returns the canonical representation of the event's signature used by the -// abi definition to identify event names and types. -func (e Event) ID() common.Hash { - return common.BytesToHash(crypto.Keccak256([]byte(e.Sig()))) + return e.str } diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index c044c5d0ea..b3d517530d 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -104,8 +104,8 @@ func TestEventId(t *testing.T) { } for name, event := range abi.Events { - if event.ID() != test.expectations[name] { - t.Errorf("expected id to be %x, got %x", test.expectations[name], event.ID()) + if event.ID != test.expectations[name] { + t.Errorf("expected id to be %x, got %x", test.expectations[name], event.ID) } } } diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 3fe3a3954d..3e6573ad5c 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -23,6 +23,24 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" ) +// FunctionType represents different types of functions a contract might have. +type FunctionType int + +const ( + // Constructor represents the constructor of the contract. + // The constructor function is called while deploying a contract. + Constructor FunctionType = iota + // Fallback represents the fallback function. + // This function is executed if no other function matches the given function + // signature and no receive function is specified. + Fallback + // Receive represents the receive function. + // This function is executed on plain Ether transfers. + Receive + // Function represents a normal function. + Function +) + // Method represents a callable given a `Name` and whether the method is a constant. // If the method is `Const` no transaction needs to be created for this // particular Method call. It can easily be simulated using a local VM. @@ -44,6 +62,10 @@ type Method struct { Name string RawName string // RawName is the raw method name parsed from ABI + // Type indicates whether the method is a + // special fallback introduced in solidity v0.6.0 + Type FunctionType + // StateMutability indicates the mutability state of method, // the default value is nonpayable. It can be empty if the abi // is generated by legacy compiler. @@ -53,69 +75,84 @@ type Method struct { Constant bool Payable bool - // The following two flags indicates whether the method is a - // special fallback introduced in solidity v0.6.0 - IsFallback bool - IsReceive bool - Inputs Arguments Outputs Arguments + str string + // Sig returns the methods string signature according to the ABI spec. + // e.g. function foo(uint32 a, int b) = "foo(uint32,int256)" + // Please note that "int" is substitute for its canonical representation "int256" + Sig string + // ID returns the canonical representation of the method's signature used by the + // abi definition to identify method names and types. + ID []byte } -// Sig returns the methods string signature according to the ABI spec. -// -// Example -// -// function foo(uint32 a, int b) = "foo(uint32,int256)" -// -// Please note that "int" is substitute for its canonical representation "int256" -func (method Method) Sig() string { - // Short circuit if the method is special. Fallback - // and Receive don't have signature at all. - if method.IsFallback || method.IsReceive { - return "" - } - types := make([]string, len(method.Inputs)) - for i, input := range method.Inputs { +// NewMethod creates a new Method. +// A method should always be created using NewMethod. +// It also precomputes the sig representation and the string representation +// of the method. +func NewMethod(name string, rawName string, funType FunctionType, mutability string, isConst, isPayable bool, inputs Arguments, outputs Arguments) Method { + var ( + types = make([]string, len(inputs)) + inputNames = make([]string, len(inputs)) + outputNames = make([]string, len(outputs)) + ) + for i, input := range inputs { + inputNames[i] = fmt.Sprintf("%v %v", input.Type, input.Name) types[i] = input.Type.String() } - return fmt.Sprintf("%v(%v)", method.RawName, strings.Join(types, ",")) -} - -func (method Method) String() string { - inputs := make([]string, len(method.Inputs)) - for i, input := range method.Inputs { - inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name) - } - outputs := make([]string, len(method.Outputs)) - for i, output := range method.Outputs { - outputs[i] = output.Type.String() + for i, output := range outputs { + outputNames[i] = output.Type.String() if len(output.Name) > 0 { - outputs[i] += fmt.Sprintf(" %v", output.Name) + outputNames[i] += fmt.Sprintf(" %v", output.Name) } } + // calculate the signature and method id. Note only function + // has meaningful signature and id. + var ( + sig string + id []byte + ) + if funType == Function { + sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ",")) + id = crypto.Keccak256([]byte(sig))[:4] + } // Extract meaningful state mutability of solidity method. // If it's default value, never print it. - state := method.StateMutability + state := mutability if state == "nonpayable" { state = "" } if state != "" { state = state + " " } - identity := fmt.Sprintf("function %v", method.RawName) - if method.IsFallback { + identity := fmt.Sprintf("function %v", rawName) + if funType == Fallback { identity = "fallback" - } else if method.IsReceive { + } else if funType == Receive { identity = "receive" + } else if funType == Constructor { + identity = "constructor" + } + str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", ")) + + return Method{ + Name: name, + RawName: rawName, + Type: funType, + StateMutability: mutability, + Constant: isConst, + Payable: isPayable, + Inputs: inputs, + Outputs: outputs, + str: str, + Sig: sig, + ID: id, } - return fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputs, ", "), state, strings.Join(outputs, ", ")) } -// ID returns the canonical representation of the method's signature used by the -// abi definition to identify method names and types. -func (method Method) ID() []byte { - return crypto.Keccak256([]byte(method.Sig()))[:4] +func (method Method) String() string { + return method.str } // IsConstant returns the indicator whether the method is read-only. diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go index 66e53d8a29..eb6c65f69b 100644 --- a/accounts/abi/method_test.go +++ b/accounts/abi/method_test.go @@ -137,7 +137,7 @@ func TestMethodSig(t *testing.T) { } for _, test := range cases { - got := abi.Methods[test.method].Sig() + got := abi.Methods[test.method].Sig if got != test.expect { t.Errorf("expected string to be %s, got %s", test.expect, got) } diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index 92b8a7c187..d174ceb096 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -633,7 +633,7 @@ func TestMethodPack(t *testing.T) { t.Fatal(err) } - sig := abi.Methods["slice"].ID() + sig := abi.Methods["slice"].ID sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -647,7 +647,7 @@ func TestMethodPack(t *testing.T) { } var addrA, addrB = common.Address{1}, common.Address{2} - sig = abi.Methods["sliceAddress"].ID() + sig = abi.Methods["sliceAddress"].ID sig = append(sig, common.LeftPadBytes([]byte{32}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) sig = append(sig, common.LeftPadBytes(addrA[:], 32)...) @@ -662,7 +662,7 @@ func TestMethodPack(t *testing.T) { } var addrC, addrD = common.Address{3}, common.Address{4} - sig = abi.Methods["sliceMultiAddress"].ID() + sig = abi.Methods["sliceMultiAddress"].ID sig = append(sig, common.LeftPadBytes([]byte{64}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{160}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -680,7 +680,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["slice256"].ID() + sig = abi.Methods["slice256"].ID sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -694,7 +694,7 @@ func TestMethodPack(t *testing.T) { } a := [2][2]*big.Int{{big.NewInt(1), big.NewInt(1)}, {big.NewInt(2), big.NewInt(0)}} - sig = abi.Methods["nestedArray"].ID() + sig = abi.Methods["nestedArray"].ID sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{1}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{2}, 32)...) @@ -711,7 +711,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["nestedArray2"].ID() + sig = abi.Methods["nestedArray2"].ID sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x80}, 32)...) @@ -727,7 +727,7 @@ func TestMethodPack(t *testing.T) { t.Errorf("expected %x got %x", sig, packed) } - sig = abi.Methods["nestedSlice"].ID() + sig = abi.Methods["nestedSlice"].ID sig = append(sig, common.LeftPadBytes([]byte{0x20}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x02}, 32)...) sig = append(sig, common.LeftPadBytes([]byte{0x40}, 32)...) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 83e4059d2d..d791fbce73 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -118,18 +118,16 @@ func requireAssignable(dst, src reflect.Value) error { } // requireUnpackKind verifies preconditions for unpacking `args` into `kind` -func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, - args Arguments) error { - - switch k { +func requireUnpackKind(v reflect.Value, minLength int, args Arguments) error { + switch v.Kind() { case reflect.Struct: case reflect.Slice, reflect.Array: - if minLen := args.LengthNonIndexed(); v.Len() < minLen { + if v.Len() < minLength { return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d", - minLen, v.Len()) + minLength, v.Len()) } default: - return fmt.Errorf("abi: cannot unmarshal tuple into %v", t) + return fmt.Errorf("abi: cannot unmarshal tuple into %v", v.Type()) } return nil } @@ -156,9 +154,8 @@ func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[stri continue } // skip fields that have no abi:"" tag. - var ok bool - var tagName string - if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { + tagName, ok := typ.Field(i).Tag.Lookup("abi") + if !ok { continue } // check if tag is empty. From 91f6259135141ce85fcbf484e183a7576d3179b3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 105/280] accounts/abi: remove function Unpack2 (#20830) --- accounts/abi/abi.go | 6 +++--- accounts/abi/argument.go | 12 ------------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 4906858378..712bd58348 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -250,10 +250,10 @@ func UnpackRevert(data []byte) (string, error) { if !bytes.Equal(data[:4], revertSelector) { return "", errors.New("invalid data for unpacking") } + var reason string typ, _ := NewType("string", "", nil) - unpacked, err := (Arguments{{Type: typ}}).Unpack2(data[4:]) - if err != nil { + if err := (Arguments{{Type: typ}}).Unpack(&reason, data[4:]); err != nil { return "", err } - return unpacked[0].(string), nil + return reason, nil } diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index a5ee9839e7..27af0d8a66 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -18,7 +18,6 @@ package abi import ( "encoding/json" - "errors" "fmt" "reflect" "strings" @@ -113,17 +112,6 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { return arguments.unpackAtomic(v, marshalledValues[0]) } -// Unpack2 performs the operation hexdata -> Go format. -func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) { - if len(data) == 0 { - if len(arguments.NonIndexed()) != 0 { - return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected") - } - return make([]interface{}, 0), nil - } - return arguments.UnpackValues(data) -} - // UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { // Make sure map is not nil From 0d1cd42dc24e907a2d76323a73fde0db8659b0bd Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 106/280] accounts/keystore: fix double import race (#20915) * accounts/keystore: fix race in Import/ImportECDSA * accounts/keystore: added import/export tests * cmd/geth: improved TestAccountImport test * accounts/keystore: added import/export tests * accounts/keystore: fixed naming * accounts/keystore: fixed typo * accounts/keystore: use mutex instead of rwmutex * accounts: use errors instead of fmt --- accounts/keystore/keystore.go | 10 +++- accounts/keystore/keystore_test.go | 85 ++++++++++++++++++++++++++++++ cmd/XDC/accountcmd_test.go | 21 ++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 0ed77522e8..470102034e 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -66,7 +66,8 @@ type KeyStore struct { updateScope event.SubscriptionScope // Subscription scope tracking current live listeners updating bool // Whether the event notification loop is running - mu sync.RWMutex + mu sync.RWMutex + importMu sync.Mutex // Import Mutex locks the import to prevent two insertions from racing } type unlocked struct { @@ -449,12 +450,19 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac if err != nil { return accounts.Account{}, err } + ks.importMu.Lock() + defer ks.importMu.Unlock() + if ks.cache.hasAddress(key.Address) { + return accounts.Account{}, errors.New("account already exists") + } return ks.importKey(key, newPassphrase) } // ImportECDSA stores the given key into the key directory, encrypting it with the passphrase. func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { key := newKeyFromECDSA(priv) + ks.importMu.Lock() + defer ks.importMu.Unlock() if ks.cache.hasAddress(key.Address) { return accounts.Account{}, errors.New("account already exists") } diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index d74ab0d7e3..2e139cad0f 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -22,11 +22,14 @@ import ( "runtime" "sort" "strings" + "sync" + "sync/atomic" "testing" "time" "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/event" ) @@ -337,6 +340,88 @@ func TestWalletNotifications(t *testing.T) { checkEvents(t, wantEvents, events) } +// TestImportECDSA tests the import functionality of a keystore. +func TestImportECDSA(t *testing.T) { + dir, ks := tmpKeyStore(t, true) + defer os.RemoveAll(dir) + key, err := crypto.GenerateKey() + if err != nil { + t.Fatalf("failed to generate key: %v", key) + } + if _, err = ks.ImportECDSA(key, "old"); err != nil { + t.Errorf("importing failed: %v", err) + } + if _, err = ks.ImportECDSA(key, "old"); err == nil { + t.Errorf("importing same key twice succeeded") + } + if _, err = ks.ImportECDSA(key, "new"); err == nil { + t.Errorf("importing same key twice succeeded") + } +} + +// TestImportExport tests the import and export functionality of a keystore. +func TestImportExport(t *testing.T) { + dir, ks := tmpKeyStore(t, true) + defer os.RemoveAll(dir) + acc, err := ks.NewAccount("old") + if err != nil { + t.Fatalf("failed to create account: %v", acc) + } + json, err := ks.Export(acc, "old", "new") + if err != nil { + t.Fatalf("failed to export account: %v", acc) + } + dir2, ks2 := tmpKeyStore(t, true) + defer os.RemoveAll(dir2) + if _, err = ks2.Import(json, "old", "old"); err == nil { + t.Errorf("importing with invalid password succeeded") + } + acc2, err := ks2.Import(json, "new", "new") + if err != nil { + t.Errorf("importing failed: %v", err) + } + if acc.Address != acc2.Address { + t.Error("imported account does not match exported account") + } + if _, err = ks2.Import(json, "new", "new"); err == nil { + t.Errorf("importing a key twice succeeded") + } + +} + +// TestImportRace tests the keystore on races. +// This test should fail under -race if importing races. +func TestImportRace(t *testing.T) { + dir, ks := tmpKeyStore(t, true) + defer os.RemoveAll(dir) + acc, err := ks.NewAccount("old") + if err != nil { + t.Fatalf("failed to create account: %v", acc) + } + json, err := ks.Export(acc, "old", "new") + if err != nil { + t.Fatalf("failed to export account: %v", acc) + } + dir2, ks2 := tmpKeyStore(t, true) + defer os.RemoveAll(dir2) + var atom uint32 + var wg sync.WaitGroup + wg.Add(2) + for i := 0; i < 2; i++ { + go func() { + defer wg.Done() + if _, err := ks2.Import(json, "new", "new"); err != nil { + atomic.AddUint32(&atom, 1) + } + + }() + } + wg.Wait() + if atom != 1 { + t.Errorf("Import is racy") + } +} + // checkAccounts checks that all known live accounts are present in the wallet list. func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, wallets []accounts.Wallet) { if len(live) != len(wallets) { diff --git a/cmd/XDC/accountcmd_test.go b/cmd/XDC/accountcmd_test.go index 9bd57a350f..2afb457699 100644 --- a/cmd/XDC/accountcmd_test.go +++ b/cmd/XDC/accountcmd_test.go @@ -95,6 +95,27 @@ Path of the secret key file: .*UTC--.+--xdc[0-9a-fA-F]{40} `) } +func TestAccountImport(t *testing.T) { + tests := []struct{ name, key, output string }{ + { + name: "correct account", + key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + output: "Address: {xdcfcad0b19bb29d4674531d6f115237e16afce377c}\n", + }, + { + name: "invalid character", + key: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef1", + output: "Fatal: Failed to load the private key: invalid character '1' at end of key file\n", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + importAccountWithExpect(t, test.key, test.output) + }) + } +} + func TestAccountNewBadRepeat(t *testing.T) { XDC := runXDC(t, "account", "new", "--lightkdf") defer XDC.ExpectExit() From bca20a692a31a87012c9a262f96fe0e0768ce738 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 107/280] accounts/abi: added abi test cases, minor bug fixes (#20903) * accounts/abi: added documentation * accounts/abi: reduced usage of arguments.LengthNonIndexed * accounts/abi: simplified reflection logic * accounts/abi: moved testjson data into global declaration * accounts/abi: removed duplicate test cases * accounts/abi: reworked abi tests * accounts/abi: added more tests for abi packing * accounts/abi/bind: refactored base tests * accounts/abi: run pack tests as subtests * accounts/abi: removed duplicate tests * accounts/abi: removed unnused arguments.LengthNonIndexed Due to refactors to the code, we do not need the arguments.LengthNonIndexed function anymore. You can still get the length by calling len(arguments.NonIndexed()) * accounts/abi: added type test * accounts/abi: modified unpack test to pack test * accounts/abi: length check on arrayTy * accounts/abi: test invalid abi * accounts/abi: fixed rebase error * accounts/abi: fixed rebase errors * accounts/abi: removed unused definition * accounts/abi: merged packing/unpacking tests * accounts/abi: fixed [][][32]bytes encoding * accounts/abi: added tuple test cases * accounts/abi: renamed getMockLog -> newMockLog * accounts/abi: removed duplicate test * accounts/abi: bools -> booleans --- accounts/abi/abi_test.go | 263 +++++---- accounts/abi/argument.go | 22 +- accounts/abi/bind/base_test.go | 217 ++------ accounts/abi/error.go | 4 +- accounts/abi/pack_test.go | 630 ++------------------- accounts/abi/packing_test.go | 988 +++++++++++++++++++++++++++++++++ accounts/abi/reflect.go | 42 +- accounts/abi/type_test.go | 25 + accounts/abi/unpack_test.go | 338 ++--------- 9 files changed, 1332 insertions(+), 1197 deletions(-) create mode 100644 accounts/abi/packing_test.go diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 8f616e07cf..ee8ad048a0 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -33,12 +33,7 @@ import ( const jsondata = ` [ - { "type" : "function", "name" : "balance", "stateMutability" : "view" }, - { "type" : "function", "name" : "send", "inputs" : [ { "name" : "amount", "type" : "uint256" } ] } -]` - -const jsondata2 = ` -[ + { "type" : "function", "name" : "", "stateMutability" : "view" }, { "type" : "function", "name" : "balance", "stateMutability" : "view" }, { "type" : "function", "name" : "send", "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, { "type" : "function", "name" : "test", "inputs" : [ { "name" : "number", "type" : "uint32" } ] }, @@ -47,6 +42,7 @@ const jsondata2 = ` { "type" : "function", "name" : "address", "inputs" : [ { "name" : "inputs", "type" : "address" } ] }, { "type" : "function", "name" : "uint64[2]", "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] }, { "type" : "function", "name" : "uint64[]", "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] }, + { "type" : "function", "name" : "int8", "inputs" : [ { "name" : "inputs", "type" : "int8" } ] }, { "type" : "function", "name" : "foo", "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, { "type" : "function", "name" : "bar", "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, { "type" : "function", "name" : "slice", "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, @@ -55,16 +51,68 @@ const jsondata2 = ` { "type" : "function", "name" : "sliceMultiAddress", "inputs" : [ { "name" : "a", "type" : "address[]" }, { "name" : "b", "type" : "address[]" } ] }, { "type" : "function", "name" : "nestedArray", "inputs" : [ { "name" : "a", "type" : "uint256[2][2]" }, { "name" : "b", "type" : "address[]" } ] }, { "type" : "function", "name" : "nestedArray2", "inputs" : [ { "name" : "a", "type" : "uint8[][2]" } ] }, - { "type" : "function", "name" : "nestedSlice", "inputs" : [ { "name" : "a", "type" : "uint8[][]" } ] } + { "type" : "function", "name" : "nestedSlice", "inputs" : [ { "name" : "a", "type" : "uint8[][]" } ] }, + { "type" : "function", "name" : "receive", "inputs" : [ { "name" : "memo", "type" : "bytes" }], "outputs" : [], "payable" : true, "stateMutability" : "payable" }, + { "type" : "function", "name" : "fixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, + { "type" : "function", "name" : "fixedArrBytes", "stateMutability" : "view", "inputs" : [ { "name" : "bytes", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, + { "type" : "function", "name" : "mixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" } ] }, + { "type" : "function", "name" : "doubleFixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type" : "uint256[2]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] }, + { "type" : "function", "name" : "multipleMixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type" : "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] } ]` +var ( + Uint256, _ = NewType("uint256", "", nil) + Uint32, _ = NewType("uint32", "", nil) + Uint16, _ = NewType("uint16", "", nil) + String, _ = NewType("string", "", nil) + Bool, _ = NewType("bool", "", nil) + Bytes, _ = NewType("bytes", "", nil) + Address, _ = NewType("address", "", nil) + Uint64Arr, _ = NewType("uint64[]", "", nil) + AddressArr, _ = NewType("address[]", "", nil) + Int8, _ = NewType("int8", "", nil) + // Special types for testing + Uint32Arr2, _ = NewType("uint32[2]", "", nil) + Uint64Arr2, _ = NewType("uint64[2]", "", nil) + Uint256Arr, _ = NewType("uint256[]", "", nil) + Uint256Arr2, _ = NewType("uint256[2]", "", nil) + Uint256Arr3, _ = NewType("uint256[3]", "", nil) + Uint256ArrNested, _ = NewType("uint256[2][2]", "", nil) + Uint8ArrNested, _ = NewType("uint8[][2]", "", nil) + Uint8SliceNested, _ = NewType("uint8[][]", "", nil) +) + +var methods = map[string]Method{ + "": NewMethod("", "", Function, "view", false, false, nil, nil), + "balance": NewMethod("balance", "balance", Function, "view", false, false, nil, nil), + "send": NewMethod("send", "send", Function, "", false, false, []Argument{{"amount", Uint256, false}}, nil), + "test": NewMethod("test", "test", Function, "", false, false, []Argument{{"number", Uint32, false}}, nil), + "string": NewMethod("string", "string", Function, "", false, false, []Argument{{"inputs", String, false}}, nil), + "bool": NewMethod("bool", "bool", Function, "", false, false, []Argument{{"inputs", Bool, false}}, nil), + "address": NewMethod("address", "address", Function, "", false, false, []Argument{{"inputs", Address, false}}, nil), + "uint64[]": NewMethod("uint64[]", "uint64[]", Function, "", false, false, []Argument{{"inputs", Uint64Arr, false}}, nil), + "uint64[2]": NewMethod("uint64[2]", "uint64[2]", Function, "", false, false, []Argument{{"inputs", Uint64Arr2, false}}, nil), + "int8": NewMethod("int8", "int8", Function, "", false, false, []Argument{{"inputs", Int8, false}}, nil), + "foo": NewMethod("foo", "foo", Function, "", false, false, []Argument{{"inputs", Uint32, false}}, nil), + "bar": NewMethod("bar", "bar", Function, "", false, false, []Argument{{"inputs", Uint32, false}, {"string", Uint16, false}}, nil), + "slice": NewMethod("slice", "slice", Function, "", false, false, []Argument{{"inputs", Uint32Arr2, false}}, nil), + "slice256": NewMethod("slice256", "slice256", Function, "", false, false, []Argument{{"inputs", Uint256Arr2, false}}, nil), + "sliceAddress": NewMethod("sliceAddress", "sliceAddress", Function, "", false, false, []Argument{{"inputs", AddressArr, false}}, nil), + "sliceMultiAddress": NewMethod("sliceMultiAddress", "sliceMultiAddress", Function, "", false, false, []Argument{{"a", AddressArr, false}, {"b", AddressArr, false}}, nil), + "nestedArray": NewMethod("nestedArray", "nestedArray", Function, "", false, false, []Argument{{"a", Uint256ArrNested, false}, {"b", AddressArr, false}}, nil), + "nestedArray2": NewMethod("nestedArray2", "nestedArray2", Function, "", false, false, []Argument{{"a", Uint8ArrNested, false}}, nil), + "nestedSlice": NewMethod("nestedSlice", "nestedSlice", Function, "", false, false, []Argument{{"a", Uint8SliceNested, false}}, nil), + "receive": NewMethod("receive", "receive", Function, "payable", false, true, []Argument{{"memo", Bytes, false}}, []Argument{}), + "fixedArrStr": NewMethod("fixedArrStr", "fixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr", Uint256Arr2, false}}, nil), + "fixedArrBytes": NewMethod("fixedArrBytes", "fixedArrBytes", Function, "view", false, false, []Argument{{"bytes", Bytes, false}, {"fixedArr", Uint256Arr2, false}}, nil), + "mixedArrStr": NewMethod("mixedArrStr", "mixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr", Uint256Arr2, false}, {"dynArr", Uint256Arr, false}}, nil), + "doubleFixedArrStr": NewMethod("doubleFixedArrStr", "doubleFixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr1", Uint256Arr2, false}, {"fixedArr2", Uint256Arr3, false}}, nil), + "multipleMixedArrStr": NewMethod("multipleMixedArrStr", "multipleMixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr1", Uint256Arr2, false}, {"dynArr", Uint256Arr, false}, {"fixedArr2", Uint256Arr3, false}}, nil), +} + func TestReader(t *testing.T) { - Uint256, _ := NewType("uint256", "", nil) abi := ABI{ - Methods: map[string]Method{ - "balance": NewMethod("balance", "balance", Function, "view", false, false, nil, nil), - "send": NewMethod("send", "send", Function, "", false, false, []Argument{{"amount", Uint256, false}}, nil), - }, + Methods: methods, } exp, err := JSON(strings.NewReader(jsondata)) @@ -72,7 +120,6 @@ func TestReader(t *testing.T) { t.Error(err) } - // deep equal fails for some reason for name, expM := range exp.Methods { gotM, exist := abi.Methods[name] if !exist { @@ -94,8 +141,58 @@ func TestReader(t *testing.T) { } } +func TestInvalidABI(t *testing.T) { + json := `[{ "type" : "function", "name" : "", "constant" : fals }]` + _, err := JSON(strings.NewReader(json)) + if err == nil { + t.Fatal("invalid json should produce error") + } + json2 := `[{ "type" : "function", "name" : "send", "constant" : false, "inputs" : [ { "name" : "amount", "typ" : "uint256" } ] }]` + _, err = JSON(strings.NewReader(json2)) + if err == nil { + t.Fatal("invalid json should produce error") + } +} + +// TestConstructor tests a constructor function. +// The test is based on the following contract: +// contract TestConstructor { +// constructor(uint256 a, uint256 b) public{} +// } +func TestConstructor(t *testing.T) { + json := `[{ "inputs": [{"internalType": "uint256","name": "a","type": "uint256" },{ "internalType": "uint256","name": "b","type": "uint256"}],"stateMutability": "nonpayable","type": "constructor"}]` + method := NewMethod("", "", Constructor, "nonpayable", false, false, []Argument{{"a", Uint256, false}, {"b", Uint256, false}}, nil) + // Test from JSON + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(abi.Constructor, method) { + t.Error("Missing expected constructor") + } + // Test pack/unpack + packed, err := abi.Pack("", big.NewInt(1), big.NewInt(2)) + if err != nil { + t.Error(err) + } + v := struct { + A *big.Int + B *big.Int + }{new(big.Int), new(big.Int)} + //abi.Unpack(&v, "", packed) + if err := abi.Constructor.Inputs.Unpack(&v, packed); err != nil { + t.Error(err) + } + if !reflect.DeepEqual(v.A, big.NewInt(1)) { + t.Error("Unable to pack/unpack from constructor") + } + if !reflect.DeepEqual(v.B, big.NewInt(2)) { + t.Error("Unable to pack/unpack from constructor") + } +} + func TestTestNumbers(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) + abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) } @@ -131,44 +228,7 @@ func TestTestNumbers(t *testing.T) { } } -func TestTestString(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) - if err != nil { - t.Fatal(err) - } - - if _, err := abi.Pack("string", "hello world"); err != nil { - t.Error(err) - } -} - -func TestTestBool(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) - if err != nil { - t.Fatal(err) - } - - if _, err := abi.Pack("bool", true); err != nil { - t.Error(err) - } -} - -func TestTestSlice(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) - if err != nil { - t.Fatal(err) - } - slice := make([]uint64, 2) - if _, err := abi.Pack("uint64[2]", slice); err != nil { - t.Error(err) - } - if _, err := abi.Pack("uint64[]", slice); err != nil { - t.Error(err) - } -} - func TestMethodSignature(t *testing.T) { - String, _ := NewType("string", "", nil) m := NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil) exp := "foo(string,string)" if m.Sig != exp { @@ -180,8 +240,7 @@ func TestMethodSignature(t *testing.T) { t.Errorf("expected ids to match %x != %x", m.ID, idexp) } - uintt, _ := NewType("uint256", "", nil) - m = NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", uintt, false}}, nil) + m = NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", Uint256, false}}, nil) exp = "foo(uint256)" if m.Sig != exp { t.Error("signature mismatch", exp, "!=", m.Sig) @@ -231,7 +290,7 @@ func TestOverloadedMethodSignature(t *testing.T) { } func TestMultiPack(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) + abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) } @@ -397,15 +456,7 @@ func TestInputVariableInputLength(t *testing.T) { } func TestInputFixedArrayAndVariableInputLength(t *testing.T) { - const definition = `[ - { "type" : "function", "name" : "fixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, - { "type" : "function", "name" : "fixedArrBytes", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, - { "type" : "function", "name" : "mixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type": "uint256[2]" }, { "name" : "dynArr", "type": "uint256[]" } ] }, - { "type" : "function", "name" : "doubleFixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "fixedArr2", "type": "uint256[3]" } ] }, - { "type" : "function", "name" : "multipleMixedArrStr", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type": "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] } - ]` - - abi, err := JSON(strings.NewReader(definition)) + abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Error(err) } @@ -599,8 +650,6 @@ func TestBareEvents(t *testing.T) { { "type" : "event", "name" : "tuple", "inputs" : [{ "indexed":false, "name":"t", "type":"tuple", "components":[{"name":"a", "type":"uint256"}] }, { "indexed":true, "name":"arg1", "type":"address" }] } ]` - arg0, _ := NewType("uint256", "", nil) - arg1, _ := NewType("address", "", nil) tuple, _ := NewType("tuple", "", []ArgumentMarshaling{{Name: "a", Type: "uint256"}}) expectedEvents := map[string]struct { @@ -610,12 +659,12 @@ func TestBareEvents(t *testing.T) { "balance": {false, nil}, "anon": {true, nil}, "args": {false, []Argument{ - {Name: "arg0", Type: arg0, Indexed: false}, - {Name: "arg1", Type: arg1, Indexed: true}, + {Name: "arg0", Type: Uint256, Indexed: false}, + {Name: "arg1", Type: Address, Indexed: true}, }}, "tuple": {false, []Argument{ {Name: "t", Type: tuple, Indexed: false}, - {Name: "arg1", Type: arg1, Indexed: true}, + {Name: "arg1", Type: Address, Indexed: true}, }}, } @@ -891,31 +940,7 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) { } func TestABI_MethodById(t *testing.T) { - const abiJSON = `[ - {"type":"function","name":"receive","constant":false,"inputs":[{"name":"memo","type":"bytes"}],"outputs":[],"payable":true,"stateMutability":"payable"}, - {"type":"event","name":"received","anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}]}, - {"type":"function","name":"fixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"}]}, - {"type":"function","name":"fixedArrBytes","constant":true,"inputs":[{"name":"str","type":"bytes"},{"name":"fixedArr","type":"uint256[2]"}]}, - {"type":"function","name":"mixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"}]}, - {"type":"function","name":"doubleFixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"fixedArr2","type":"uint256[3]"}]}, - {"type":"function","name":"multipleMixedArrStr","constant":true,"inputs":[{"name":"str","type":"string"},{"name":"fixedArr1","type":"uint256[2]"},{"name":"dynArr","type":"uint256[]"},{"name":"fixedArr2","type":"uint256[3]"}]}, - {"type":"function","name":"balance","constant":true}, - {"type":"function","name":"send","constant":false,"inputs":[{"name":"amount","type":"uint256"}]}, - {"type":"function","name":"test","constant":false,"inputs":[{"name":"number","type":"uint32"}]}, - {"type":"function","name":"string","constant":false,"inputs":[{"name":"inputs","type":"string"}]}, - {"type":"function","name":"bool","constant":false,"inputs":[{"name":"inputs","type":"bool"}]}, - {"type":"function","name":"address","constant":false,"inputs":[{"name":"inputs","type":"address"}]}, - {"type":"function","name":"uint64[2]","constant":false,"inputs":[{"name":"inputs","type":"uint64[2]"}]}, - {"type":"function","name":"uint64[]","constant":false,"inputs":[{"name":"inputs","type":"uint64[]"}]}, - {"type":"function","name":"foo","constant":false,"inputs":[{"name":"inputs","type":"uint32"}]}, - {"type":"function","name":"bar","constant":false,"inputs":[{"name":"inputs","type":"uint32"},{"name":"string","type":"uint16"}]}, - {"type":"function","name":"_slice","constant":false,"inputs":[{"name":"inputs","type":"uint32[2]"}]}, - {"type":"function","name":"__slice256","constant":false,"inputs":[{"name":"inputs","type":"uint256[2]"}]}, - {"type":"function","name":"sliceAddress","constant":false,"inputs":[{"name":"inputs","type":"address[]"}]}, - {"type":"function","name":"sliceMultiAddress","constant":false,"inputs":[{"name":"a","type":"address[]"},{"name":"b","type":"address[]"}]} - ] -` - abi, err := JSON(strings.NewReader(abiJSON)) + abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) } @@ -930,6 +955,10 @@ func TestABI_MethodById(t *testing.T) { t.Errorf("Method %v (id %x) not 'findable' by id in ABI", name, m.ID) } } + // test unsuccessful lookups + if _, err = abi.MethodById(crypto.Keccak256()); err == nil { + t.Error("Expected error: no method with this id") + } // Also test empty if _, err := abi.MethodById([]byte{0x00}); err == nil { t.Errorf("Expected error, too short to decode data") @@ -1041,26 +1070,6 @@ func TestABI_EventById(t *testing.T) { } } -func TestDuplicateMethodNames(t *testing.T) { - abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` - contractAbi, err := JSON(strings.NewReader(abiJSON)) - if err != nil { - t.Fatal(err) - } - if _, ok := contractAbi.Methods["transfer"]; !ok { - t.Fatalf("Could not find original method") - } - if _, ok := contractAbi.Methods["transfer0"]; !ok { - t.Fatalf("Could not find duplicate method") - } - if _, ok := contractAbi.Methods["transfer1"]; !ok { - t.Fatalf("Could not find duplicate method") - } - if _, ok := contractAbi.Methods["transfer2"]; ok { - t.Fatalf("Should not have found extra method") - } -} - // TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name // conflict and that the second transfer method will be renamed transfer1. func TestDoubleDuplicateMethodNames(t *testing.T) { @@ -1083,6 +1092,34 @@ func TestDoubleDuplicateMethodNames(t *testing.T) { } } +// TestDoubleDuplicateEventNames checks that if send0 already exists, there won't be a name +// conflict and that the second send event will be renamed send1. +// The test runs the abi of the following contract. +// contract DuplicateEvent { +// event send(uint256 a); +// event send0(); +// event send(); +// } +func TestDoubleDuplicateEventNames(t *testing.T) { + abiJSON := `[{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "a","type": "uint256"}],"name": "send","type": "event"},{"anonymous": false,"inputs": [],"name": "send0","type": "event"},{ "anonymous": false, "inputs": [],"name": "send","type": "event"}]` + contractAbi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + if _, ok := contractAbi.Events["send"]; !ok { + t.Fatalf("Could not find original event") + } + if _, ok := contractAbi.Events["send0"]; !ok { + t.Fatalf("Could not find duplicate event") + } + if _, ok := contractAbi.Events["send1"]; !ok { + t.Fatalf("Could not find duplicate event") + } + if _, ok := contractAbi.Events["send2"]; ok { + t.Fatalf("Should not have found extra event") + } +} + // TestUnnamedEventParam checks that an event with unnamed parameters is // correctly handled // The test runs the abi of the following contract. diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 27af0d8a66..c0c87c5308 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -59,18 +59,6 @@ func (argument *Argument) UnmarshalJSON(data []byte) error { return nil } -// LengthNonIndexed returns the number of arguments when not counting 'indexed' ones. Only events -// can ever have 'indexed' arguments, it should always be false on arguments for method input/output -func (arguments Arguments) LengthNonIndexed() int { - out := 0 - for _, arg := range arguments { - if !arg.Indexed { - out++ - } - } - return out -} - // NonIndexed returns the arguments with indexed arguments filtered out func (arguments Arguments) NonIndexed() Arguments { var ret []Argument @@ -205,10 +193,11 @@ func unpack(t *Type, dst interface{}, src interface{}) error { // unpackAtomic unpacks ( hexdata -> go ) a single value func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { - if arguments.LengthNonIndexed() == 0 { + nonIndexedArgs := arguments.NonIndexed() + if len(nonIndexedArgs) == 0 { return nil } - argument := arguments.NonIndexed()[0] + argument := nonIndexedArgs[0] elem := reflect.ValueOf(v).Elem() if elem.Kind() == reflect.Struct && argument.Type.T != TupleTy { @@ -282,9 +271,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa // without supplying a struct to unpack into. Instead, this method returns a list containing the // values. An atomic argument will be a list with one element. func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { - retval := make([]interface{}, 0, arguments.LengthNonIndexed()) + nonIndexedArgs := arguments.NonIndexed() + retval := make([]interface{}, 0, len(nonIndexedArgs)) virtualArgs := 0 - for index, arg := range arguments.NonIndexed() { + for index, arg := range nonIndexedArgs { marshalledValue, err := ToGoType((index+virtualArgs)*32, arg.Type, data) if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) { // If we have a static array, like [3]uint256, these are coded as diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 5ab9300c33..538b01a5aa 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -17,9 +17,9 @@ package bind_test import ( - "bytes" "context" "math/big" + "reflect" "strings" "testing" @@ -186,51 +186,23 @@ const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16 func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { hash := crypto.Keccak256Hash([]byte("testName")) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x0"), - hash, - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x0"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, + topics := []common.Hash{ + common.HexToHash("0x0"), + hash, } + mockLog := newMockLog(topics, common.HexToHash("0x0")) abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) expectedReceivedMap := map[string]interface{}{ "name": hash, "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), "amount": big.NewInt(1), "memo": []byte{88}, } - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { - t.Error(err) - } - - if len(receivedMap) != 4 { - t.Fatal("unpacked map expected to have length 4") - } - if receivedMap["name"] != expectedReceivedMap["name"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { - t.Error("unpacked map does not match expected map") - } - if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { - t.Error("unpacked map does not match expected map") - } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { @@ -239,51 +211,23 @@ func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { t.Fatal(err) } hash := crypto.Keccak256Hash(sliceBytes) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x0"), - hash, - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x0"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, + topics := []common.Hash{ + common.HexToHash("0x0"), + hash, } + mockLog := newMockLog(topics, common.HexToHash("0x0")) abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) expectedReceivedMap := map[string]interface{}{ "names": hash, "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), "amount": big.NewInt(1), "memo": []byte{88}, } - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { - t.Error(err) - } - - if len(receivedMap) != 4 { - t.Fatal("unpacked map expected to have length 4") - } - if receivedMap["names"] != expectedReceivedMap["names"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { - t.Error("unpacked map does not match expected map") - } - if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { - t.Error("unpacked map does not match expected map") - } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { @@ -292,51 +236,23 @@ func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { t.Fatal(err) } hash := crypto.Keccak256Hash(arrBytes) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x0"), - hash, - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x0"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, + topics := []common.Hash{ + common.HexToHash("0x0"), + hash, } + mockLog := newMockLog(topics, common.HexToHash("0x0")) abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) expectedReceivedMap := map[string]interface{}{ "addresses": hash, "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), "amount": big.NewInt(1), "memo": []byte{88}, } - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { - t.Error(err) - } - - if len(receivedMap) != 4 { - t.Fatal("unpacked map expected to have length 4") - } - if receivedMap["addresses"] != expectedReceivedMap["addresses"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { - t.Error("unpacked map does not match expected map") - } - if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { - t.Error("unpacked map does not match expected map") - } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { @@ -347,99 +263,72 @@ func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { functionTyBytes := append(addrBytes, functionSelector...) var functionTy [24]byte copy(functionTy[:], functionTyBytes[0:24]) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), - common.BytesToHash(functionTyBytes), - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, + topics := []common.Hash{ + common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + common.BytesToHash(functionTyBytes), } - + mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) expectedReceivedMap := map[string]interface{}{ "function": functionTy, "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), "amount": big.NewInt(1), "memo": []byte{88}, } - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { - t.Error(err) - } - - if len(receivedMap) != 4 { - t.Fatal("unpacked map expected to have length 4") - } - if receivedMap["function"] != expectedReceivedMap["function"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { - t.Error("unpacked map does not match expected map") - } - if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { - t.Error("unpacked map does not match expected map") - } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { - byts := []byte{1, 2, 3, 4, 5} - hash := crypto.Keccak256Hash(byts) - mockLog := types.Log{ - Address: common.HexToAddress("0x0"), - Topics: []common.Hash{ - common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), - hash, - }, - Data: hexutil.MustDecode(hexData), - BlockNumber: uint64(26), - TxHash: common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"), - TxIndex: 111, - BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), - Index: 7, - Removed: false, + bytes := []byte{1, 2, 3, 4, 5} + hash := crypto.Keccak256Hash(bytes) + topics := []common.Hash{ + common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + hash, } + mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - receivedMap := make(map[string]interface{}) expectedReceivedMap := map[string]interface{}{ "content": hash, "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), "amount": big.NewInt(1), "memo": []byte{88}, } - if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil { + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + +func unpackAndCheck(t *testing.T, bc *bind.BoundContract, expected map[string]interface{}, mockLog types.Log) { + received := make(map[string]interface{}) + if err := bc.UnpackLogIntoMap(received, "received", mockLog); err != nil { t.Error(err) } - if len(receivedMap) != 4 { - t.Fatal("unpacked map expected to have length 4") + if len(received) != len(expected) { + t.Fatalf("unpacked map length %v not equal expected length of %v", len(received), len(expected)) } - if receivedMap["content"] != expectedReceivedMap["content"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["sender"] != expectedReceivedMap["sender"] { - t.Error("unpacked map does not match expected map") - } - if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 { - t.Error("unpacked map does not match expected map") - } - if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) { - t.Error("unpacked map does not match expected map") + for name, elem := range expected { + if !reflect.DeepEqual(elem, received[name]) { + t.Errorf("field %v does not match expected, want %v, got %v", name, elem, received[name]) + } + } +} + +func newMockLog(topics []common.Hash, txHash common.Hash) types.Log { + return types.Log{ + Address: common.HexToAddress("0x0"), + Topics: topics, + Data: hexutil.MustDecode(hexData), + BlockNumber: uint64(26), + TxHash: txHash, + TxIndex: 111, + BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), + Index: 7, + Removed: false, } } diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 9d8674ad08..338ef188c3 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -46,12 +46,10 @@ func sliceTypeCheck(t Type, val reflect.Value) error { return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) } - if t.Elem.T == SliceTy { + if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { if val.Len() > 0 { return sliceTypeCheck(*t.Elem, val.Index(0)) } - } else if t.Elem.T == ArrayTy { - return sliceTypeCheck(*t.Elem, val.Index(0)) } if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind { diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index d174ceb096..e7990ae294 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -18,617 +18,57 @@ package abi import ( "bytes" + "encoding/hex" + "fmt" "math" "math/big" "reflect" + "strconv" "strings" "testing" "github.com/XinFinOrg/XDPoSChain/common" ) +// TestPack tests the general pack/unpack tests in packing_test.go func TestPack(t *testing.T) { - for i, test := range []struct { - typ string - components []ArgumentMarshaling - input interface{} - output []byte - }{ - { - "uint8", - nil, - uint8(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint8[]", - nil, - []uint8{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint16", - nil, - uint16(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint16[]", - nil, - []uint16{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint32", - nil, - uint32(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint32[]", - nil, - []uint32{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint64", - nil, - uint64(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint64[]", - nil, - []uint64{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint256", - nil, - big.NewInt(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "uint256[]", - nil, - []*big.Int{big.NewInt(1), big.NewInt(2)}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int8", - nil, - int8(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int8[]", - nil, - []int8{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int16", - nil, - int16(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int16[]", - nil, - []int16{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int32", - nil, - int32(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int32[]", - nil, - []int32{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int64", - nil, - int64(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int64[]", - nil, - []int64{1, 2}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int256", - nil, - big.NewInt(2), - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "int256[]", - nil, - []*big.Int{big.NewInt(1), big.NewInt(2)}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002"), - }, - { - "bytes1", - nil, - [1]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes2", - nil, - [2]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes3", - nil, - [3]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes4", - nil, - [4]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes5", - nil, - [5]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes6", - nil, - [6]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes7", - nil, - [7]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes8", - nil, - [8]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes9", - nil, - [9]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes10", - nil, - [10]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes11", - nil, - [11]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes12", - nil, - [12]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes13", - nil, - [13]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes14", - nil, - [14]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes15", - nil, - [15]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes16", - nil, - [16]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes17", - nil, - [17]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes18", - nil, - [18]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes19", - nil, - [19]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes20", - nil, - [20]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes21", - nil, - [21]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes22", - nil, - [22]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes23", - nil, - [23]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes24", - nil, - [24]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes25", - nil, - [25]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes26", - nil, - [26]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes27", - nil, - [27]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes28", - nil, - [28]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes29", - nil, - [29]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes30", - nil, - [30]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes31", - nil, - [31]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "bytes32", - nil, - [32]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "uint32[2][3][4]", - nil, - [4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018"), - }, - { - "address[]", - nil, - []common.Address{{1}, {2}}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000"), - }, - { - "bytes32[]", - nil, - []common.Hash{{1}, {2}}, - common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000201000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000"), - }, - { - "function", - nil, - [24]byte{1}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, - { - "string", - nil, - "foobar", - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"), - }, - { - "string[]", - nil, - []string{"hello", "foobar"}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 - "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 - "0000000000000000000000000000000000000000000000000000000000000080" + // offset 128 to i = 1 - "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 - "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] - "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 - "666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1] - }, - { - "string[2]", - nil, - []string{"hello", "foobar"}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset to i = 0 - "0000000000000000000000000000000000000000000000000000000000000080" + // offset to i = 1 - "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 - "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] - "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 - "666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1] - }, - { - "bytes32[][]", - nil, - [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 - "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 - "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 - "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 - "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] - "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] - "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 - "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] - "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] - "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] - }, - - { - "bytes32[][2]", - nil, - [][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 - "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 - "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 - "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] - "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] - "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 - "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] - "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] - "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] - }, - { - "bytes32[3][2]", - nil, - [][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}}, - common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] - "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] - "0300000000000000000000000000000000000000000000000000000000000000" + // array[0][2] - "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] - "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] - "0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2] - }, - { - // static tuple - "tuple", - []ArgumentMarshaling{ - {Name: "a", Type: "int64"}, - {Name: "b", Type: "int256"}, - {Name: "c", Type: "int256"}, - {Name: "d", Type: "bool"}, - {Name: "e", Type: "bytes32[3][2]"}, - }, - struct { - A int64 - B *big.Int - C *big.Int - D bool - E [][]common.Hash - }{1, big.NewInt(1), big.NewInt(-1), true, [][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}}}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001" + // struct[a] - "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // struct[c] - "0000000000000000000000000000000000000000000000000000000000000001" + // struct[d] - "0100000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][0] - "0200000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][1] - "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][2] - "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][0] - "0400000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][1] - "0500000000000000000000000000000000000000000000000000000000000000"), // struct[e] array[1][2] - }, - { - // dynamic tuple - "tuple", - []ArgumentMarshaling{ - {Name: "a", Type: "string"}, - {Name: "b", Type: "int64"}, - {Name: "c", Type: "bytes"}, - {Name: "d", Type: "string[]"}, - {Name: "e", Type: "int256[]"}, - {Name: "f", Type: "address[]"}, - }, - struct { - FieldA string `abi:"a"` // Test whether abi tag works - FieldB int64 `abi:"b"` - C []byte - D []string - E []*big.Int - F []common.Address - }{"foobar", 1, []byte{1}, []string{"foo", "bar"}, []*big.Int{big.NewInt(1), big.NewInt(-1)}, []common.Address{{1}, {2}}}, - common.Hex2Bytes("00000000000000000000000000000000000000000000000000000000000000c0" + // struct[a] offset - "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] - "0000000000000000000000000000000000000000000000000000000000000100" + // struct[c] offset - "0000000000000000000000000000000000000000000000000000000000000140" + // struct[d] offset - "0000000000000000000000000000000000000000000000000000000000000220" + // struct[e] offset - "0000000000000000000000000000000000000000000000000000000000000280" + // struct[f] offset - "0000000000000000000000000000000000000000000000000000000000000006" + // struct[a] length - "666f6f6261720000000000000000000000000000000000000000000000000000" + // struct[a] "foobar" - "0000000000000000000000000000000000000000000000000000000000000001" + // struct[c] length - "0100000000000000000000000000000000000000000000000000000000000000" + // []byte{1} - "0000000000000000000000000000000000000000000000000000000000000002" + // struct[d] length - "0000000000000000000000000000000000000000000000000000000000000040" + // foo offset - "0000000000000000000000000000000000000000000000000000000000000080" + // bar offset - "0000000000000000000000000000000000000000000000000000000000000003" + // foo length - "666f6f0000000000000000000000000000000000000000000000000000000000" + // foo - "0000000000000000000000000000000000000000000000000000000000000003" + // bar offset - "6261720000000000000000000000000000000000000000000000000000000000" + // bar - "0000000000000000000000000000000000000000000000000000000000000002" + // struct[e] length - "0000000000000000000000000000000000000000000000000000000000000001" + // 1 - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // -1 - "0000000000000000000000000000000000000000000000000000000000000002" + // struct[f] length - "0000000000000000000000000100000000000000000000000000000000000000" + // common.Address{1} - "0000000000000000000000000200000000000000000000000000000000000000"), // common.Address{2} - }, - { - // nested tuple - "tuple", - []ArgumentMarshaling{ - {Name: "a", Type: "tuple", Components: []ArgumentMarshaling{{Name: "a", Type: "uint256"}, {Name: "b", Type: "uint256[]"}}}, - {Name: "b", Type: "int256[]"}, - }, - struct { - A struct { - FieldA *big.Int `abi:"a"` - B []*big.Int + for i, test := range packUnpackTests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + encb, err := hex.DecodeString(test.packed) + if err != nil { + t.Fatalf("invalid hex %s: %v", test.packed, err) + } + inDef := fmt.Sprintf(`[{ "name" : "method", "type": "function", "inputs": %s}]`, test.def) + inAbi, err := JSON(strings.NewReader(inDef)) + if err != nil { + t.Fatalf("invalid ABI definition %s, %v", inDef, err) + } + var packed []byte + if reflect.TypeOf(test.unpacked).Kind() != reflect.Struct { + packed, err = inAbi.Pack("method", test.unpacked) + } else { + // if want is a struct we need to use the components. + elem := reflect.ValueOf(test.unpacked) + var values []interface{} + for i := 0; i < elem.NumField(); i++ { + field := elem.Field(i) + values = append(values, field.Interface()) } - B []*big.Int - }{ - A: struct { - FieldA *big.Int `abi:"a"` // Test whether abi tag works for nested tuple - B []*big.Int - }{big.NewInt(1), []*big.Int{big.NewInt(1), big.NewInt(0)}}, - B: []*big.Int{big.NewInt(1), big.NewInt(0)}}, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // a offset - "00000000000000000000000000000000000000000000000000000000000000e0" + // b offset - "0000000000000000000000000000000000000000000000000000000000000001" + // a.a value - "0000000000000000000000000000000000000000000000000000000000000040" + // a.b offset - "0000000000000000000000000000000000000000000000000000000000000002" + // a.b length - "0000000000000000000000000000000000000000000000000000000000000001" + // a.b[0] value - "0000000000000000000000000000000000000000000000000000000000000000" + // a.b[1] value - "0000000000000000000000000000000000000000000000000000000000000002" + // b length - "0000000000000000000000000000000000000000000000000000000000000001" + // b[0] value - "0000000000000000000000000000000000000000000000000000000000000000"), // b[1] value - }, - { - // tuple slice - "tuple[]", - []ArgumentMarshaling{ - {Name: "a", Type: "int256"}, - {Name: "b", Type: "int256[]"}, - }, - []struct { - A *big.Int - B []*big.Int - }{ - {big.NewInt(-1), []*big.Int{big.NewInt(1), big.NewInt(0)}}, - {big.NewInt(1), []*big.Int{big.NewInt(2), big.NewInt(-1)}}, - }, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // tuple length - "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset - "00000000000000000000000000000000000000000000000000000000000000e0" + // tuple[1] offset - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A - "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0].B offset - "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].B length - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].B[0] value - "0000000000000000000000000000000000000000000000000000000000000000" + // tuple[0].B[1] value - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A - "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[1].B offset - "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B length - "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B[0] value - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].B[1] value - }, - { - // static tuple array - "tuple[2]", - []ArgumentMarshaling{ - {Name: "a", Type: "int256"}, - {Name: "b", Type: "int256"}, - }, - [2]struct { - A *big.Int - B *big.Int - }{ - {big.NewInt(-1), big.NewInt(1)}, - {big.NewInt(1), big.NewInt(-1)}, - }, - common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].a - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].b - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].a - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].b - }, - { - // dynamic tuple array - "tuple[2]", - []ArgumentMarshaling{ - {Name: "a", Type: "int256[]"}, - }, - [2]struct { - A []*big.Int - }{ - {[]*big.Int{big.NewInt(-1), big.NewInt(1)}}, - {[]*big.Int{big.NewInt(1), big.NewInt(-1)}}, - }, - common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset - "00000000000000000000000000000000000000000000000000000000000000c0" + // tuple[1] offset - "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[0].A offset - "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].A length - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A[0] - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].A[1] - "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[1].A offset - "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].A length - "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A[0] - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), // tuple[1].A[1] - }, - } { - typ, err := NewType(test.typ, "", test.components) - if err != nil { - t.Fatalf("%v failed. Unexpected parse error: %v", i, err) - } - output, err := typ.pack(reflect.ValueOf(test.input)) - if err != nil { - t.Fatalf("%v failed. Unexpected pack error: %v", i, err) - } + packed, err = inAbi.Pack("method", values...) + } - if !bytes.Equal(output, test.output) { - t.Errorf("%d failed. Expected bytes: '%x' Got: '%x'", i, test.output, output) - } + if err != nil { + t.Fatalf("test %d (%v) failed: %v", i, test.def, err) + } + if !reflect.DeepEqual(packed[4:], encb) { + t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, encb, packed[4:]) + } + }) } } func TestMethodPack(t *testing.T) { - abi, err := JSON(strings.NewReader(jsondata2)) + abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) } diff --git a/accounts/abi/packing_test.go b/accounts/abi/packing_test.go new file mode 100644 index 0000000000..5794c97a50 --- /dev/null +++ b/accounts/abi/packing_test.go @@ -0,0 +1,988 @@ +// Copyright 2020 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 . + +package abi + +import ( + "math/big" + + "github.com/XinFinOrg/XDPoSChain/common" +) + +type packUnpackTest struct { + def string + unpacked interface{} + packed string +} + +var packUnpackTests = []packUnpackTest{ + // Booleans + { + def: `[{ "type": "bool" }]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: true, + }, + { + def: `[{ "type": "bool" }]`, + packed: "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: false, + }, + // Integers + { + def: `[{ "type": "uint8" }]`, + unpacked: uint8(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{ "type": "uint8[]" }]`, + unpacked: []uint8{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{ "type": "uint16" }]`, + unpacked: uint16(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{ "type": "uint16[]" }]`, + unpacked: []uint16{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "uint17"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: big.NewInt(1), + }, + { + def: `[{"type": "uint32"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: uint32(1), + }, + { + def: `[{"type": "uint32[]"}]`, + unpacked: []uint32{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "uint64"}]`, + unpacked: uint64(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "uint64[]"}]`, + unpacked: []uint64{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "uint256"}]`, + unpacked: big.NewInt(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "uint256[]"}]`, + unpacked: []*big.Int{big.NewInt(1), big.NewInt(2)}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int8"}]`, + unpacked: int8(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int8[]"}]`, + unpacked: []int8{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int16"}]`, + unpacked: int16(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int16[]"}]`, + unpacked: []int16{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int17"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: big.NewInt(1), + }, + { + def: `[{"type": "int32"}]`, + unpacked: int32(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int32"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: int32(1), + }, + { + def: `[{"type": "int32[]"}]`, + unpacked: []int32{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int64"}]`, + unpacked: int64(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int64[]"}]`, + unpacked: []int64{1, 2}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int256"}]`, + unpacked: big.NewInt(2), + packed: "0000000000000000000000000000000000000000000000000000000000000002", + }, + { + def: `[{"type": "int256"}]`, + packed: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + unpacked: big.NewInt(-1), + }, + { + def: `[{"type": "int256[]"}]`, + unpacked: []*big.Int{big.NewInt(1), big.NewInt(2)}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + }, + // Address + { + def: `[{"type": "address"}]`, + packed: "0000000000000000000000000100000000000000000000000000000000000000", + unpacked: common.Address{1}, + }, + { + def: `[{"type": "address[]"}]`, + unpacked: []common.Address{{1}, {2}}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000100000000000000000000000000000000000000" + + "0000000000000000000000000200000000000000000000000000000000000000", + }, + // Bytes + { + def: `[{"type": "bytes1"}]`, + unpacked: [1]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes2"}]`, + unpacked: [2]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes3"}]`, + unpacked: [3]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes4"}]`, + unpacked: [4]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes5"}]`, + unpacked: [5]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes6"}]`, + unpacked: [6]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes7"}]`, + unpacked: [7]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes8"}]`, + unpacked: [8]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes9"}]`, + unpacked: [9]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes10"}]`, + unpacked: [10]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes11"}]`, + unpacked: [11]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes12"}]`, + unpacked: [12]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes13"}]`, + unpacked: [13]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes14"}]`, + unpacked: [14]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes15"}]`, + unpacked: [15]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes16"}]`, + unpacked: [16]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes17"}]`, + unpacked: [17]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes18"}]`, + unpacked: [18]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes19"}]`, + unpacked: [19]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes20"}]`, + unpacked: [20]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes21"}]`, + unpacked: [21]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes22"}]`, + unpacked: [22]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes23"}]`, + unpacked: [23]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes24"}]`, + unpacked: [24]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes25"}]`, + unpacked: [25]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes26"}]`, + unpacked: [26]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes27"}]`, + unpacked: [27]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes28"}]`, + unpacked: [28]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes29"}]`, + unpacked: [29]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes30"}]`, + unpacked: [30]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes31"}]`, + unpacked: [31]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes32"}]`, + unpacked: [32]byte{1}, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "bytes32"}]`, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + unpacked: [32]byte{1, 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}, + }, + { + def: `[{"type": "bytes"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000020" + + "0100000000000000000000000000000000000000000000000000000000000000", + unpacked: common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), + }, + { + def: `[{"type": "bytes32"}]`, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + unpacked: [32]byte{1, 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}, + }, + // Functions + { + def: `[{"type": "function"}]`, + packed: "0100000000000000000000000000000000000000000000000000000000000000", + unpacked: [24]byte{1}, + }, + // Slice and Array + { + def: `[{"type": "uint8[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []uint8{1, 2}, + }, + { + def: `[{"type": "uint8[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: []uint8{}, + }, + { + def: `[{"type": "uint256[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: []*big.Int{}, + }, + { + def: `[{"type": "uint8[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]uint8{1, 2}, + }, + { + def: `[{"type": "int8[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]int8{1, 2}, + }, + { + def: `[{"type": "int16[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []int16{1, 2}, + }, + { + def: `[{"type": "int16[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]int16{1, 2}, + }, + { + def: `[{"type": "int32[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []int32{1, 2}, + }, + { + def: `[{"type": "int32[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]int32{1, 2}, + }, + { + def: `[{"type": "int64[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []int64{1, 2}, + }, + { + def: `[{"type": "int64[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]int64{1, 2}, + }, + { + def: `[{"type": "int256[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []*big.Int{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"type": "int256[3]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003", + unpacked: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, + }, + // multi dimensional, if these pass, all types that don't require length prefix should pass + { + def: `[{"type": "uint8[][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: [][]uint8{}, + }, + { + def: `[{"type": "uint8[][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [][]uint8{{1, 2}, {1, 2}}, + }, + { + def: `[{"type": "uint8[][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003", + unpacked: [][]uint8{{1, 2}, {1, 2, 3}}, + }, + { + def: `[{"type": "uint8[2][2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2][2]uint8{{1, 2}, {1, 2}}, + }, + { + def: `[{"type": "uint8[][2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: [2][]uint8{{}, {}}, + }, + { + def: `[{"type": "uint8[][2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000080" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: [2][]uint8{{1}, {1}}, + }, + { + def: `[{"type": "uint8[2][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000000", + unpacked: [][2]uint8{}, + }, + { + def: `[{"type": "uint8[2][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [][2]uint8{{1, 2}}, + }, + { + def: `[{"type": "uint8[2][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [][2]uint8{{1, 2}, {1, 2}}, + }, + { + def: `[{"type": "uint16[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []uint16{1, 2}, + }, + { + def: `[{"type": "uint16[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]uint16{1, 2}, + }, + { + def: `[{"type": "uint32[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []uint32{1, 2}, + }, + { + def: `[{"type": "uint32[2][3][4]"}]`, + unpacked: [4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000004" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "0000000000000000000000000000000000000000000000000000000000000006" + + "0000000000000000000000000000000000000000000000000000000000000007" + + "0000000000000000000000000000000000000000000000000000000000000008" + + "0000000000000000000000000000000000000000000000000000000000000009" + + "000000000000000000000000000000000000000000000000000000000000000a" + + "000000000000000000000000000000000000000000000000000000000000000b" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "000000000000000000000000000000000000000000000000000000000000000d" + + "000000000000000000000000000000000000000000000000000000000000000e" + + "000000000000000000000000000000000000000000000000000000000000000f" + + "0000000000000000000000000000000000000000000000000000000000000010" + + "0000000000000000000000000000000000000000000000000000000000000011" + + "0000000000000000000000000000000000000000000000000000000000000012" + + "0000000000000000000000000000000000000000000000000000000000000013" + + "0000000000000000000000000000000000000000000000000000000000000014" + + "0000000000000000000000000000000000000000000000000000000000000015" + + "0000000000000000000000000000000000000000000000000000000000000016" + + "0000000000000000000000000000000000000000000000000000000000000017" + + "0000000000000000000000000000000000000000000000000000000000000018", + }, + + { + def: `[{"type": "bytes32[]"}]`, + unpacked: []common.Hash{{1}, {2}}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0100000000000000000000000000000000000000000000000000000000000000" + + "0200000000000000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "uint32[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]uint32{1, 2}, + }, + { + def: `[{"type": "uint64[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []uint64{1, 2}, + }, + { + def: `[{"type": "uint64[2]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: [2]uint64{1, 2}, + }, + { + def: `[{"type": "uint256[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: []*big.Int{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"type": "uint256[3]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003", + unpacked: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, + }, + { + def: `[{"type": "string[4]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000080" + + "00000000000000000000000000000000000000000000000000000000000000c0" + + "0000000000000000000000000000000000000000000000000000000000000100" + + "0000000000000000000000000000000000000000000000000000000000000140" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "48656c6c6f000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "576f726c64000000000000000000000000000000000000000000000000000000" + + "000000000000000000000000000000000000000000000000000000000000000b" + + "476f2d657468657265756d000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000008" + + "457468657265756d000000000000000000000000000000000000000000000000", + unpacked: [4]string{"Hello", "World", "Go-ethereum", "Ethereum"}, + }, + { + def: `[{"type": "string[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000080" + + "0000000000000000000000000000000000000000000000000000000000000008" + + "457468657265756d000000000000000000000000000000000000000000000000" + + "000000000000000000000000000000000000000000000000000000000000000b" + + "676f2d657468657265756d000000000000000000000000000000000000000000", + unpacked: []string{"Ethereum", "go-ethereum"}, + }, + { + def: `[{"type": "bytes[]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000080" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "f0f0f00000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "f0f0f00000000000000000000000000000000000000000000000000000000000", + unpacked: [][]byte{{0xf0, 0xf0, 0xf0}, {0xf0, 0xf0, 0xf0}}, + }, + { + def: `[{"type": "uint256[2][][]"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "00000000000000000000000000000000000000000000000000000000000000e0" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "00000000000000000000000000000000000000000000000000000000000000c8" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "00000000000000000000000000000000000000000000000000000000000003e8" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "00000000000000000000000000000000000000000000000000000000000000c8" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "00000000000000000000000000000000000000000000000000000000000003e8", + unpacked: [][][2]*big.Int{{{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}, {{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}}, + }, + // struct outputs + { + def: `[{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: struct { + Int1 *big.Int + Int2 *big.Int + }{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"name":"int_one","type":"int256"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int__one","type":"int256"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one_","type":"int256"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001", + unpacked: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}]`, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002", + unpacked: struct { + IntOne *big.Int + Intone *big.Int + }{big.NewInt(1), big.NewInt(2)}, + }, + { + def: `[{"type": "string"}]`, + unpacked: "foobar", + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000006" + + "666f6f6261720000000000000000000000000000000000000000000000000000", + }, + { + def: `[{"type": "string[]"}]`, + unpacked: []string{"hello", "foobar"}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 + "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "0000000000000000000000000000000000000000000000000000000000000080" + // offset 128 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 + "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] + "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 + "666f6f6261720000000000000000000000000000000000000000000000000000", // str[1] + }, + { + def: `[{"type": "string[2]"}]`, + unpacked: [2]string{"hello", "foobar"}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000040" + // offset to i = 0 + "0000000000000000000000000000000000000000000000000000000000000080" + // offset to i = 1 + "0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5 + "68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0] + "0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6 + "666f6f6261720000000000000000000000000000000000000000000000000000", // str[1] + }, + { + def: `[{"type": "bytes32[][]"}]`, + unpacked: [][][32]byte{{{1}, {2}}, {{3}, {4}, {5}}}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2 + "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 + "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000", // array[1][2] + }, + { + def: `[{"type": "bytes32[][2]"}]`, + unpacked: [2][][32]byte{{{1}, {2}}, {{3}, {4}, {5}}}, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0 + "00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1 + "0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2 + "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3 + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000", // array[1][2] + }, + { + def: `[{"type": "bytes32[3][2]"}]`, + unpacked: [2][3][32]byte{{{1}, {2}, {3}}, {{3}, {4}, {5}}}, + packed: "0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1] + "0300000000000000000000000000000000000000000000000000000000000000" + // array[0][2] + "0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000", // array[1][2] + }, + { + // static tuple + def: `[{"name":"a","type":"int64"}, + {"name":"b","type":"int256"}, + {"name":"c","type":"int256"}, + {"name":"d","type":"bool"}, + {"name":"e","type":"bytes32[3][2]"}]`, + unpacked: struct { + A int64 + B *big.Int + C *big.Int + D bool + E [2][3][32]byte + }{1, big.NewInt(1), big.NewInt(-1), true, [2][3][32]byte{{{1}, {2}, {3}}, {{3}, {4}, {5}}}}, + packed: "0000000000000000000000000000000000000000000000000000000000000001" + // struct[a] + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // struct[c] + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[d] + "0100000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][0] + "0200000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][1] + "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[0][2] + "0300000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][0] + "0400000000000000000000000000000000000000000000000000000000000000" + // struct[e] array[1][1] + "0500000000000000000000000000000000000000000000000000000000000000", // struct[e] array[1][2] + }, + { + def: `[{"name":"a","type":"string"}, + {"name":"b","type":"int64"}, + {"name":"c","type":"bytes"}, + {"name":"d","type":"string[]"}, + {"name":"e","type":"int256[]"}, + {"name":"f","type":"address[]"}]`, + unpacked: struct { + FieldA string `abi:"a"` // Test whether abi tag works + FieldB int64 `abi:"b"` + C []byte + D []string + E []*big.Int + F []common.Address + }{"foobar", 1, []byte{1}, []string{"foo", "bar"}, []*big.Int{big.NewInt(1), big.NewInt(-1)}, []common.Address{{1}, {2}}}, + packed: "00000000000000000000000000000000000000000000000000000000000000c0" + // struct[a] offset + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] + "0000000000000000000000000000000000000000000000000000000000000100" + // struct[c] offset + "0000000000000000000000000000000000000000000000000000000000000140" + // struct[d] offset + "0000000000000000000000000000000000000000000000000000000000000220" + // struct[e] offset + "0000000000000000000000000000000000000000000000000000000000000280" + // struct[f] offset + "0000000000000000000000000000000000000000000000000000000000000006" + // struct[a] length + "666f6f6261720000000000000000000000000000000000000000000000000000" + // struct[a] "foobar" + "0000000000000000000000000000000000000000000000000000000000000001" + // struct[c] length + "0100000000000000000000000000000000000000000000000000000000000000" + // []byte{1} + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[d] length + "0000000000000000000000000000000000000000000000000000000000000040" + // foo offset + "0000000000000000000000000000000000000000000000000000000000000080" + // bar offset + "0000000000000000000000000000000000000000000000000000000000000003" + // foo length + "666f6f0000000000000000000000000000000000000000000000000000000000" + // foo + "0000000000000000000000000000000000000000000000000000000000000003" + // bar offset + "6261720000000000000000000000000000000000000000000000000000000000" + // bar + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[e] length + "0000000000000000000000000000000000000000000000000000000000000001" + // 1 + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // -1 + "0000000000000000000000000000000000000000000000000000000000000002" + // struct[f] length + "0000000000000000000000000100000000000000000000000000000000000000" + // common.Address{1} + "0000000000000000000000000200000000000000000000000000000000000000", // common.Address{2} + }, + { + def: `[{"components": [{"name": "a","type": "uint256"}, + {"name": "b","type": "uint256[]"}], + "name": "a","type": "tuple"}, + {"name": "b","type": "uint256[]"}]`, + unpacked: struct { + A struct { + FieldA *big.Int `abi:"a"` + B []*big.Int + } + B []*big.Int + }{ + A: struct { + FieldA *big.Int `abi:"a"` // Test whether abi tag works for nested tuple + B []*big.Int + }{big.NewInt(1), []*big.Int{big.NewInt(1), big.NewInt(2)}}, + B: []*big.Int{big.NewInt(1), big.NewInt(2)}}, + packed: "0000000000000000000000000000000000000000000000000000000000000040" + // a offset + "00000000000000000000000000000000000000000000000000000000000000e0" + // b offset + "0000000000000000000000000000000000000000000000000000000000000001" + // a.a value + "0000000000000000000000000000000000000000000000000000000000000040" + // a.b offset + "0000000000000000000000000000000000000000000000000000000000000002" + // a.b length + "0000000000000000000000000000000000000000000000000000000000000001" + // a.b[0] value + "0000000000000000000000000000000000000000000000000000000000000002" + // a.b[1] value + "0000000000000000000000000000000000000000000000000000000000000002" + // b length + "0000000000000000000000000000000000000000000000000000000000000001" + // b[0] value + "0000000000000000000000000000000000000000000000000000000000000002", // b[1] value + }, + + { + def: `[{"components": [{"name": "a","type": "int256"}, + {"name": "b","type": "int256[]"}], + "name": "a","type": "tuple[]"}]`, + unpacked: []struct { + A *big.Int + B []*big.Int + }{ + {big.NewInt(-1), []*big.Int{big.NewInt(1), big.NewInt(3)}}, + {big.NewInt(1), []*big.Int{big.NewInt(2), big.NewInt(-1)}}, + }, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple length + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset + "00000000000000000000000000000000000000000000000000000000000000e0" + // tuple[1] offset + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0].B offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].B length + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].B[0] value + "0000000000000000000000000000000000000000000000000000000000000003" + // tuple[0].B[1] value + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[1].B offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B length + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].B[0] value + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // tuple[1].B[1] value + }, + { + def: `[{"components": [{"name": "a","type": "int256"}, + {"name": "b","type": "int256"}], + "name": "a","type": "tuple[2]"}]`, + unpacked: [2]struct { + A *big.Int + B *big.Int + }{ + {big.NewInt(-1), big.NewInt(1)}, + {big.NewInt(1), big.NewInt(-1)}, + }, + packed: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].a + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].b + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].a + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // tuple[1].b + }, + { + def: `[{"components": [{"name": "a","type": "int256[]"}], + "name": "a","type": "tuple[2]"}]`, + unpacked: [2]struct { + A []*big.Int + }{ + {[]*big.Int{big.NewInt(-1), big.NewInt(1)}}, + {[]*big.Int{big.NewInt(1), big.NewInt(-1)}}, + }, + packed: "0000000000000000000000000000000000000000000000000000000000000020" + + "0000000000000000000000000000000000000000000000000000000000000040" + // tuple[0] offset + "00000000000000000000000000000000000000000000000000000000000000c0" + // tuple[1] offset + "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[0].A offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[0].A length + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + // tuple[0].A[0] + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[0].A[1] + "0000000000000000000000000000000000000000000000000000000000000020" + // tuple[1].A offset + "0000000000000000000000000000000000000000000000000000000000000002" + // tuple[1].A length + "0000000000000000000000000000000000000000000000000000000000000001" + // tuple[1].A[0] + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // tuple[1].A[1] + }, +} diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index d791fbce73..afc448e642 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -42,26 +42,26 @@ func indirectInterfaceOrPtr(v reflect.Value) reflect.Value { // reflectIntKind returns the reflect using the given size and // unsignedness. func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) { - switch size { - case 8: - if unsigned { + if unsigned { + switch size { + case 8: return reflect.Uint8, uint8T - } - return reflect.Int8, int8T - case 16: - if unsigned { + case 16: return reflect.Uint16, uint16T - } - return reflect.Int16, int16T - case 32: - if unsigned { + case 32: return reflect.Uint32, uint32T - } - return reflect.Int32, int32T - case 64: - if unsigned { + case 64: return reflect.Uint64, uint64T } + } + switch size { + case 8: + return reflect.Int8, int8T + case 16: + return reflect.Int16, int16T + case 32: + return reflect.Int32, int32T + case 64: return reflect.Int64, int64T } return reflect.Ptr, bigT @@ -88,8 +88,8 @@ func set(dst, src reflect.Value) error { return set(dst.Elem(), src) case srcType.AssignableTo(dstType) && dst.CanSet(): dst.Set(src) - case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice: - return setSlice(dst, src) + case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice && dst.CanSet(): + setSlice(dst, src) default: return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) } @@ -98,15 +98,13 @@ func set(dst, src reflect.Value) error { // setSlice attempts to assign src to dst when slices are not assignable by default // e.g. src: [][]byte -> dst: [][15]byte -func setSlice(dst, src reflect.Value) error { +// setSlice ignores if we cannot copy all of src' elements. +func setSlice(dst, src reflect.Value) { slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) for i := 0; i < src.Len(); i++ { - v := src.Index(i) - reflect.Copy(slice.Index(i), v) + reflect.Copy(slice.Index(i), src.Index(i)) } - dst.Set(slice) - return nil } // requireAssignable assures that `dest` is a pointer and it's not an interface. diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index 8ff3d46b5a..d7bb8e7ba5 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -306,3 +306,28 @@ func TestTypeCheck(t *testing.T) { } } } + +func TestInternalType(t *testing.T) { + components := []ArgumentMarshaling{{Name: "a", Type: "int64"}} + internalType := "struct a.b[]" + kind := Type{ + Kind: reflect.Struct, + T: TupleTy, + Type: reflect.TypeOf(struct { + A int64 `json:"a"` + }{}), + stringKind: "(int64)", + TupleRawName: "ab[]", + TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, + TupleRawNames: []string{"a"}, + } + + blob := "tuple" + typ, err := NewType(blob, internalType, components) + if err != nil { + t.Errorf("type %q: failed to parse type string: %v", blob, err) + } + if !reflect.DeepEqual(typ, kind) { + t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind))) + } +} diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index c0525390f8..d52268d7e7 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -30,6 +30,34 @@ import ( "github.com/stretchr/testify/require" ) +// TestUnpack tests the general pack/unpack tests in packing_test.go +func TestUnpack(t *testing.T) { + for i, test := range packUnpackTests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + //Unpack + def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) + abi, err := JSON(strings.NewReader(def)) + if err != nil { + t.Fatalf("invalid ABI definition %s: %v", def, err) + } + encb, err := hex.DecodeString(test.packed) + if err != nil { + t.Fatalf("invalid hex %s: %v", test.packed, err) + } + outptr := reflect.New(reflect.TypeOf(test.unpacked)) + err = abi.Unpack(outptr.Interface(), "method", encb) + if err != nil { + t.Errorf("test %d (%v) failed: %v", i, test.def, err) + return + } + out := outptr.Elem().Interface() + if !reflect.DeepEqual(test.unpacked, out) { + t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.unpacked, out) + } + }) + } +} + type unpackTest struct { def string // ABI definition JSON enc string // evm return data @@ -52,16 +80,6 @@ func (test unpackTest) checkError(err error) error { var unpackTests = []unpackTest{ // Bools - { - def: `[{ "type": "bool" }]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001", - want: true, - }, - { - def: `[{ "type": "bool" }]`, - enc: "0000000000000000000000000000000000000000000000000000000000000000", - want: false, - }, { def: `[{ "type": "bool" }]`, enc: "0000000000000000000000000000000000000000000000000001000000000001", @@ -75,11 +93,6 @@ var unpackTests = []unpackTest{ err: "abi: improperly encoded boolean value", }, // Integers - { - def: `[{"type": "uint32"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001", - want: uint32(1), - }, { def: `[{"type": "uint32"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", @@ -92,16 +105,6 @@ var unpackTests = []unpackTest{ want: uint16(0), err: "abi: cannot unmarshal *big.Int in to uint16", }, - { - def: `[{"type": "uint17"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001", - want: big.NewInt(1), - }, - { - def: `[{"type": "int32"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001", - want: int32(1), - }, { def: `[{"type": "int32"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", @@ -114,33 +117,6 @@ var unpackTests = []unpackTest{ want: int16(0), err: "abi: cannot unmarshal *big.Int in to int16", }, - { - def: `[{"type": "int17"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001", - want: big.NewInt(1), - }, - { - def: `[{"type": "int256"}]`, - enc: "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - want: big.NewInt(-1), - }, - // Address - { - def: `[{"type": "address"}]`, - enc: "0000000000000000000000000100000000000000000000000000000000000000", - want: common.Address{1}, - }, - // Bytes - { - def: `[{"type": "bytes32"}]`, - enc: "0100000000000000000000000000000000000000000000000000000000000000", - want: [32]byte{1, 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}, - }, - { - def: `[{"type": "bytes"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000", - want: common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000"), - }, { def: `[{"type": "bytes"}]`, enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000", @@ -153,237 +129,6 @@ var unpackTests = []unpackTest{ want: []byte(nil), err: "abi: cannot unmarshal [32]uint8 in to []uint8", }, - { - def: `[{"type": "bytes32"}]`, - enc: "0100000000000000000000000000000000000000000000000000000000000000", - want: [32]byte{1, 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}, - }, - // Functions - { - def: `[{"type": "function"}]`, - enc: "0100000000000000000000000000000000000000000000000000000000000000", - want: [24]byte{1}, - }, - // Slice and Array - { - def: `[{"type": "uint8[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []uint8{1, 2}, - }, - { - def: `[{"type": "uint8[]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - want: []uint8{}, - }, - { - def: `[{"type": "uint256[]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - want: []*big.Int{}, - }, - { - def: `[{"type": "uint8[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]uint8{1, 2}, - }, - // multi dimensional, if these pass, all types that don't require length prefix should pass - { - def: `[{"type": "uint8[][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - want: [][]uint8{}, - }, - { - def: `[{"type": "uint8[][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [][]uint8{{1, 2}, {1, 2}}, - }, - { - def: `[{"type": "uint8[][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - want: [][]uint8{{1, 2}, {1, 2, 3}}, - }, - { - def: `[{"type": "uint8[2][2]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2][2]uint8{{1, 2}, {1, 2}}, - }, - { - def: `[{"type": "uint8[][2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - want: [2][]uint8{{}, {}}, - }, - { - def: `[{"type": "uint8[][2]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001", - want: [2][]uint8{{1}, {1}}, - }, - { - def: `[{"type": "uint8[2][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000", - want: [][2]uint8{}, - }, - { - def: `[{"type": "uint8[2][]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [][2]uint8{{1, 2}}, - }, - { - def: `[{"type": "uint8[2][]"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [][2]uint8{{1, 2}, {1, 2}}, - }, - { - def: `[{"type": "uint16[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []uint16{1, 2}, - }, - { - def: `[{"type": "uint16[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]uint16{1, 2}, - }, - { - def: `[{"type": "uint32[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []uint32{1, 2}, - }, - { - def: `[{"type": "uint32[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]uint32{1, 2}, - }, - { - def: `[{"type": "uint32[2][3][4]"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001300000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000015000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000018", - want: [4][3][2]uint32{{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}, - }, - { - def: `[{"type": "uint64[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []uint64{1, 2}, - }, - { - def: `[{"type": "uint64[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]uint64{1, 2}, - }, - { - def: `[{"type": "uint256[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []*big.Int{big.NewInt(1), big.NewInt(2)}, - }, - { - def: `[{"type": "uint256[3]"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, - }, - { - def: `[{"type": "string[4]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000548656c6c6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005576f726c64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b476f2d657468657265756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000", - want: [4]string{"Hello", "World", "Go-ethereum", "Ethereum"}, - }, - { - def: `[{"type": "string[]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b676f2d657468657265756d000000000000000000000000000000000000000000", - want: []string{"Ethereum", "go-ethereum"}, - }, - { - def: `[{"type": "bytes[]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003f0f0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f0f0f00000000000000000000000000000000000000000000000000000000000", - want: [][]byte{{0xf0, 0xf0, 0xf0}, {0xf0, 0xf0, 0xf0}}, - }, - { - def: `[{"type": "uint256[2][][]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003e8", - want: [][][2]*big.Int{{{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}, {{big.NewInt(1), big.NewInt(200)}, {big.NewInt(1), big.NewInt(1000)}}}, - }, - { - def: `[{"type": "int8[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []int8{1, 2}, - }, - { - def: `[{"type": "int8[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]int8{1, 2}, - }, - { - def: `[{"type": "int16[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []int16{1, 2}, - }, - { - def: `[{"type": "int16[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]int16{1, 2}, - }, - { - def: `[{"type": "int32[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []int32{1, 2}, - }, - { - def: `[{"type": "int32[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]int32{1, 2}, - }, - { - def: `[{"type": "int64[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []int64{1, 2}, - }, - { - def: `[{"type": "int64[2]"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: [2]int64{1, 2}, - }, - { - def: `[{"type": "int256[]"}]`, - enc: "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: []*big.Int{big.NewInt(1), big.NewInt(2)}, - }, - { - def: `[{"type": "int256[3]"}]`, - enc: "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - want: [3]*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, - }, - // struct outputs - { - def: `[{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: struct { - Int1 *big.Int - Int2 *big.Int - }{big.NewInt(1), big.NewInt(2)}, - }, - { - def: `[{"name":"int_one","type":"int256"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: struct { - IntOne *big.Int - }{big.NewInt(1)}, - }, - { - def: `[{"name":"int__one","type":"int256"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: struct { - IntOne *big.Int - }{big.NewInt(1)}, - }, - { - def: `[{"name":"int_one_","type":"int256"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: struct { - IntOne *big.Int - }{big.NewInt(1)}, - }, - { - def: `[{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}]`, - enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", - want: struct { - IntOne *big.Int - Intone *big.Int - }{big.NewInt(1), big.NewInt(2)}, - }, { def: `[{"name":"___","type":"int256"}]`, enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", @@ -438,11 +183,36 @@ var unpackTests = []unpackTest{ }{}, err: "abi: purely underscored output cannot unpack to struct", }, + // Make sure only the first argument is consumed + { + def: `[{"name":"int_one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int__one","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, + { + def: `[{"name":"int_one_","type":"int256"}]`, + enc: "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002", + want: struct { + IntOne *big.Int + }{big.NewInt(1)}, + }, } -func TestUnpack(t *testing.T) { +// TestLocalUnpackTests runs test specially designed only for unpacking. +// All test cases that can be used to test packing and unpacking should move to packing_test.go +func TestLocalUnpackTests(t *testing.T) { for i, test := range unpackTests { t.Run(strconv.Itoa(i), func(t *testing.T) { + //Unpack def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) abi, err := JSON(strings.NewReader(def)) if err != nil { From dabda3335a8ee9a8164c44e3b8b1bbbbde96155d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 108/280] accounts/abi: removed Kind from Type struct (#21009) * accounts/abi: removed Kind from Type struct * accounts/abi: removed unused code --- accounts/abi/error.go | 12 ++-- accounts/abi/reflect.go | 22 +++---- accounts/abi/type.go | 14 +---- accounts/abi/type_test.go | 117 +++++++++++++++++++------------------- accounts/abi/unpack.go | 24 ++++---- 5 files changed, 89 insertions(+), 100 deletions(-) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 338ef188c3..9ee27010aa 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -39,11 +39,11 @@ func formatSliceString(kind reflect.Kind, sliceSize int) string { // type in t. func sliceTypeCheck(t Type, val reflect.Value) error { if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { - return typeErr(formatSliceString(t.Kind, t.Size), val.Type()) + return typeErr(formatSliceString(t.Type.Kind(), t.Size), val.Type()) } if t.T == ArrayTy && val.Len() != t.Size { - return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) + return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) } if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { @@ -52,8 +52,8 @@ func sliceTypeCheck(t Type, val reflect.Value) error { } } - if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind { - return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type()) + if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Type.Kind() { + return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), val.Type()) } return nil } @@ -66,8 +66,8 @@ func typeCheck(t Type, value reflect.Value) error { } // Check base type validity. Element types will be checked later on. - if t.Kind != value.Kind() { - return typeErr(t.Kind, value.Kind()) + if t.Type.Kind() != value.Kind() { + return typeErr(t.Type.Kind(), value.Kind()) } else if t.T == FixedBytesTy && t.Size != value.Len() { return typeErr(t.Type, value.Type()) } else { diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index afc448e642..d4767edd0d 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -39,32 +39,32 @@ func indirectInterfaceOrPtr(v reflect.Value) reflect.Value { return v } -// reflectIntKind returns the reflect using the given size and +// reflectIntType returns the reflect using the given size and // unsignedness. -func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) { +func reflectIntType(unsigned bool, size int) reflect.Type { if unsigned { switch size { case 8: - return reflect.Uint8, uint8T + return uint8T case 16: - return reflect.Uint16, uint16T + return uint16T case 32: - return reflect.Uint32, uint32T + return uint32T case 64: - return reflect.Uint64, uint64T + return uint64T } } switch size { case 8: - return reflect.Int8, int8T + return int8T case 16: - return reflect.Int16, int16T + return int16T case 32: - return reflect.Int32, int32T + return int32T case 64: - return reflect.Int64, int64T + return int64T } - return reflect.Ptr, bigT + return bigT } // mustArrayToBytesSlice creates a new byte slice with the exact same size as value diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 6fe0b6e059..60c836d105 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -45,7 +45,6 @@ const ( // Type is the reflection of the supported argument type type Type struct { Elem *Type - Kind reflect.Kind Type reflect.Type Size int T byte // Our own type checking @@ -94,14 +93,12 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty if len(intz) == 0 { // is a slice typ.T = SliceTy - typ.Kind = reflect.Slice typ.Elem = &embeddedType typ.Type = reflect.SliceOf(embeddedType.Type) typ.stringKind = embeddedType.stringKind + sliced } else if len(intz) == 1 { // is a array typ.T = ArrayTy - typ.Kind = reflect.Array typ.Elem = &embeddedType typ.Size, err = strconv.Atoi(intz[0]) if err != nil { @@ -138,34 +135,29 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty // varType is the parsed abi type switch varType := parsedType[1]; varType { case "int": - typ.Kind, typ.Type = reflectIntKindAndType(false, varSize) + typ.Type = reflectIntType(false, varSize) typ.Size = varSize typ.T = IntTy case "uint": - typ.Kind, typ.Type = reflectIntKindAndType(true, varSize) + typ.Type = reflectIntType(true, varSize) typ.Size = varSize typ.T = UintTy case "bool": - typ.Kind = reflect.Bool typ.T = BoolTy typ.Type = reflect.TypeOf(bool(false)) case "address": - typ.Kind = reflect.Array typ.Type = addressT typ.Size = 20 typ.T = AddressTy case "string": - typ.Kind = reflect.String typ.Type = reflect.TypeOf("") typ.T = StringTy case "bytes": if varSize == 0 { typ.T = BytesTy - typ.Kind = reflect.Slice typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0))) } else { typ.T = FixedBytesTy - typ.Kind = reflect.Array typ.Size = varSize typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0))) } @@ -198,7 +190,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty } } expression += ")" - typ.Kind = reflect.Struct typ.Type = reflect.StructOf(fields) typ.TupleElems = elems typ.TupleRawNames = names @@ -216,7 +207,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty } case "function": - typ.Kind = reflect.Array typ.T = FunctionTy typ.Size = 24 typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0))) diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index d7bb8e7ba5..fec0eb152b 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -36,58 +36,58 @@ func TestTypeRegexp(t *testing.T) { components []ArgumentMarshaling kind Type }{ - {"bool", nil, Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, - {"bool[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, - {"bool[2]", nil, Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, - {"bool[2][]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, - {"bool[][]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, - {"bool[][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, - {"bool[2][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, - {"bool[2][][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, - {"bool[2][2][2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, - {"bool[][][]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, - {"bool[][2][]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, - {"int8", nil, Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, - {"int16", nil, Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, - {"int32", nil, Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, - {"int64", nil, Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, - {"int256", nil, Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, - {"int8[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, - {"int8[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, - {"int16[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, - {"int16[2]", nil, Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, - {"int32[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, - {"int32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, - {"int64[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, - {"int64[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, - {"int256[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, - {"int256[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, - {"uint8", nil, Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, - {"uint16", nil, Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, - {"uint32", nil, Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, - {"uint64", nil, Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, - {"uint256", nil, Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, - {"uint8[]", nil, Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, - {"uint8[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, - {"uint16[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, - {"uint16[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, - {"uint32[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, - {"uint32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, - {"uint64[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, - {"uint64[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, - {"uint256[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, - {"uint256[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, - {"bytes32", nil, Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, - {"bytes[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Kind: reflect.Slice, Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, - {"bytes[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), Kind: reflect.Slice, stringKind: "bytes"}, stringKind: "bytes[2]"}}, - {"bytes32[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Kind: reflect.Array, Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, - {"bytes32[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, - {"string", nil, Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, - {"string[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, - {"string[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, - {"address", nil, Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, - {"address[]", nil, Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, - {"address[2]", nil, Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, + {"bool", nil, Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, + {"bool[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, + {"bool[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, + {"bool[2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, + {"bool[][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, + {"bool[][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, + {"bool[2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, + {"bool[2][][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, + {"bool[2][2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, + {"bool[][][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, + {"bool[][2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, + {"int8", nil, Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, + {"int16", nil, Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, + {"int32", nil, Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, + {"int64", nil, Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, + {"int256", nil, Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, + {"int8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, + {"int8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, + {"int16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, + {"int16[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, + {"int32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, + {"int32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, + {"int64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, + {"int64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, + {"int256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, + {"int256[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, + {"uint8", nil, Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, + {"uint16", nil, Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, + {"uint32", nil, Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, + {"uint64", nil, Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, + {"uint256", nil, Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, + {"uint8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, + {"uint8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, + {"uint16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, + {"uint16[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, + {"uint32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, + {"uint32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, + {"uint64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, + {"uint64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, + {"uint256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, + {"uint256[2]", nil, Type{T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, + {"bytes32", nil, Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, + {"bytes[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, + {"bytes[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), stringKind: "bytes"}, stringKind: "bytes[2]"}}, + {"bytes32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, + {"bytes32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, + {"string", nil, Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, + {"string[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]string{}), Elem: &Type{Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, + {"string[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, + {"address", nil, Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, + {"address[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, + {"address[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, // TODO when fixed types are implemented properly // {"fixed", nil, Type{}}, // {"fixed128x128", nil, Type{}}, @@ -95,14 +95,14 @@ func TestTypeRegexp(t *testing.T) { // {"fixed[2]", nil, Type{}}, // {"fixed128x128[]", nil, Type{}}, // {"fixed128x128[2]", nil, Type{}}, - {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct { + {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { A int64 `json:"a"` }{}), stringKind: "(int64)", - TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, - {"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{Kind: reflect.Struct, T: TupleTy, Type: reflect.TypeOf(struct { + TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, + {"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { ATypicalParamName int64 `json:"aTypicalParamName"` }{}), stringKind: "(int64)", - TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, + TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, } for _, tt := range tests { @@ -311,14 +311,13 @@ func TestInternalType(t *testing.T) { components := []ArgumentMarshaling{{Name: "a", Type: "int64"}} internalType := "struct a.b[]" kind := Type{ - Kind: reflect.Struct, - T: TupleTy, + T: TupleTy, Type: reflect.TypeOf(struct { A int64 `json:"a"` }{}), stringKind: "(int64)", TupleRawName: "ab[]", - TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, + TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}, } diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 6b5ca98854..f7d53877e2 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -34,28 +34,28 @@ var ( ) // ReadInteger reads the integer based on its kind and returns the appropriate value -func ReadInteger(typ byte, kind reflect.Kind, b []byte) interface{} { - switch kind { - case reflect.Uint8: +func ReadInteger(typ Type, b []byte) interface{} { + switch typ.Type { + case uint8T: return b[len(b)-1] - case reflect.Uint16: + case uint16T: return binary.BigEndian.Uint16(b[len(b)-2:]) - case reflect.Uint32: + case uint32T: return binary.BigEndian.Uint32(b[len(b)-4:]) - case reflect.Uint64: + case uint64T: return binary.BigEndian.Uint64(b[len(b)-8:]) - case reflect.Int8: + case int8T: return int8(b[len(b)-1]) - case reflect.Int16: + case int16T: return int16(binary.BigEndian.Uint16(b[len(b)-2:])) - case reflect.Int32: + case int32T: return int32(binary.BigEndian.Uint32(b[len(b)-4:])) - case reflect.Int64: + case int64T: return int64(binary.BigEndian.Uint64(b[len(b)-8:])) default: // the only case left for integer is int256/uint256. ret := new(big.Int).SetBytes(b) - if typ == UintTy { + if typ.T == UintTy { return ret } // big.SetBytes can't tell if a number is negative or positive in itself. @@ -229,7 +229,7 @@ func ToGoType(index int, t Type, output []byte) (interface{}, error) { case StringTy: // variable arrays are written at the end of the return bytes return string(output[begin : begin+length]), nil case IntTy, UintTy: - return ReadInteger(t.T, t.Kind, returnOutput), nil + return ReadInteger(t, returnOutput), nil case BoolTy: return readBool(returnOutput) case AddressTy: From f6b6a2409341182cd7e2533bbabe0f955a89d00d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 109/280] account/abi: remove superfluous type checking (#21022) * accounts/abi: added getType func to Type struct * accounts/abi: fixed tuple unpack * accounts/abi: removed type.Type * accounts/abi: added comment * accounts/abi: removed unused types * accounts/abi: removed superfluous declarations * accounts/abi: typo --- accounts/abi/error.go | 14 ++--- accounts/abi/numbers.go | 38 ------------ accounts/abi/reflect.go | 23 +++---- accounts/abi/type.go | 60 ++++++++++++++----- accounts/abi/type_test.go | 116 ++++++++++++++++++------------------ accounts/abi/unpack.go | 48 ++++++++------- accounts/abi/unpack_test.go | 2 +- 7 files changed, 148 insertions(+), 153 deletions(-) delete mode 100644 accounts/abi/numbers.go diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 9ee27010aa..8d61d574c5 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -39,11 +39,11 @@ func formatSliceString(kind reflect.Kind, sliceSize int) string { // type in t. func sliceTypeCheck(t Type, val reflect.Value) error { if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { - return typeErr(formatSliceString(t.Type.Kind(), t.Size), val.Type()) + return typeErr(formatSliceString(t.getType().Kind(), t.Size), val.Type()) } if t.T == ArrayTy && val.Len() != t.Size { - return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) + return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) } if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { @@ -52,8 +52,8 @@ func sliceTypeCheck(t Type, val reflect.Value) error { } } - if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Type.Kind() { - return typeErr(formatSliceString(t.Elem.Type.Kind(), t.Size), val.Type()) + if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.getType().Kind() { + return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), val.Type()) } return nil } @@ -66,10 +66,10 @@ func typeCheck(t Type, value reflect.Value) error { } // Check base type validity. Element types will be checked later on. - if t.Type.Kind() != value.Kind() { - return typeErr(t.Type.Kind(), value.Kind()) + if t.getType().Kind() != value.Kind() { + return typeErr(t.getType().Kind(), value.Kind()) } else if t.T == FixedBytesTy && t.Size != value.Len() { - return typeErr(t.Type, value.Type()) + return typeErr(t.getType(), value.Type()) } else { return nil } diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go deleted file mode 100644 index e265d3f57c..0000000000 --- a/accounts/abi/numbers.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 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 . - -package abi - -import ( - "math/big" - "reflect" - - "github.com/XinFinOrg/XDPoSChain/common" -) - -var ( - bigT = reflect.TypeOf(&big.Int{}) - derefbigT = reflect.TypeOf(big.Int{}) - uint8T = reflect.TypeOf(uint8(0)) - uint16T = reflect.TypeOf(uint16(0)) - uint32T = reflect.TypeOf(uint32(0)) - uint64T = reflect.TypeOf(uint64(0)) - int8T = reflect.TypeOf(int8(0)) - int16T = reflect.TypeOf(int16(0)) - int32T = reflect.TypeOf(int32(0)) - int64T = reflect.TypeOf(int64(0)) - addressT = reflect.TypeOf(common.Address{}) -) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index d4767edd0d..dbff10ae6f 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -18,6 +18,7 @@ package abi import ( "fmt" + "math/big" "reflect" "strings" ) @@ -25,7 +26,7 @@ import ( // indirect recursively dereferences the value until it either gets the value // or finds a big.Int func indirect(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { + if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeOf(big.Int{}) { return indirect(v.Elem()) } return v @@ -45,26 +46,26 @@ func reflectIntType(unsigned bool, size int) reflect.Type { if unsigned { switch size { case 8: - return uint8T + return reflect.TypeOf(uint8(0)) case 16: - return uint16T + return reflect.TypeOf(uint16(0)) case 32: - return uint32T + return reflect.TypeOf(uint32(0)) case 64: - return uint64T + return reflect.TypeOf(uint64(0)) } } switch size { case 8: - return int8T + return reflect.TypeOf(int8(0)) case 16: - return int16T + return reflect.TypeOf(int16(0)) case 32: - return int32T + return reflect.TypeOf(int32(0)) case 64: - return int64T + return reflect.TypeOf(int64(0)) } - return bigT + return reflect.TypeOf(&big.Int{}) } // mustArrayToBytesSlice creates a new byte slice with the exact same size as value @@ -84,7 +85,7 @@ func set(dst, src reflect.Value) error { switch { case dstType.Kind() == reflect.Interface && dst.Elem().IsValid(): return set(dst.Elem(), src) - case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT: + case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeOf(big.Int{}): return set(dst.Elem(), src) case srcType.AssignableTo(dstType) && dst.CanSet(): dst.Set(src) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 60c836d105..eacea7f8c1 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -23,6 +23,8 @@ import ( "regexp" "strconv" "strings" + + "github.com/XinFinOrg/XDPoSChain/common" ) // Type enumerator @@ -45,16 +47,16 @@ const ( // Type is the reflection of the supported argument type type Type struct { Elem *Type - Type reflect.Type Size int T byte // Our own type checking stringKind string // holds the unparsed string for deriving signatures // Tuple relative fields - TupleRawName string // Raw struct name defined in source code, may be empty. - TupleElems []*Type // Type information of all tuple fields - TupleRawNames []string // Raw field name of all tuple fields + TupleRawName string // Raw struct name defined in source code, may be empty. + TupleElems []*Type // Type information of all tuple fields + TupleRawNames []string // Raw field name of all tuple fields + TupleType reflect.Type // Underlying struct of the tuple } var ( @@ -94,7 +96,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty // is a slice typ.T = SliceTy typ.Elem = &embeddedType - typ.Type = reflect.SliceOf(embeddedType.Type) typ.stringKind = embeddedType.stringKind + sliced } else if len(intz) == 1 { // is a array @@ -104,7 +105,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty if err != nil { return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err) } - typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type) typ.stringKind = embeddedType.stringKind + sliced } else { return Type{}, errors.New("invalid formatting of array type") @@ -135,31 +135,24 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty // varType is the parsed abi type switch varType := parsedType[1]; varType { case "int": - typ.Type = reflectIntType(false, varSize) typ.Size = varSize typ.T = IntTy case "uint": - typ.Type = reflectIntType(true, varSize) typ.Size = varSize typ.T = UintTy case "bool": typ.T = BoolTy - typ.Type = reflect.TypeOf(bool(false)) case "address": - typ.Type = addressT typ.Size = 20 typ.T = AddressTy case "string": - typ.Type = reflect.TypeOf("") typ.T = StringTy case "bytes": if varSize == 0 { typ.T = BytesTy - typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0))) } else { typ.T = FixedBytesTy typ.Size = varSize - typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0))) } case "tuple": var ( @@ -179,7 +172,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty } fields = append(fields, reflect.StructField{ Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field. - Type: cType.Type, + Type: cType.getType(), Tag: reflect.StructTag("json:\"" + c.Name + "\""), }) elems = append(elems, &cType) @@ -190,7 +183,8 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty } } expression += ")" - typ.Type = reflect.StructOf(fields) + + typ.TupleType = reflect.StructOf(fields) typ.TupleElems = elems typ.TupleRawNames = names typ.T = TupleTy @@ -209,7 +203,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty case "function": typ.T = FunctionTy typ.Size = 24 - typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0))) default: return Type{}, fmt.Errorf("unsupported arg type: %s", t) } @@ -217,6 +210,41 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty return } +func (t Type) getType() reflect.Type { + switch t.T { + case IntTy: + return reflectIntType(false, t.Size) + case UintTy: + return reflectIntType(true, t.Size) + case BoolTy: + return reflect.TypeOf(false) + case StringTy: + return reflect.TypeOf("") + case SliceTy: + return reflect.SliceOf(t.Elem.getType()) + case ArrayTy: + return reflect.ArrayOf(t.Size, t.Elem.getType()) + case TupleTy: + return t.TupleType + case AddressTy: + return reflect.TypeOf(common.Address{}) + case FixedBytesTy: + return reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0))) + case BytesTy: + return reflect.SliceOf(reflect.TypeOf(byte(0))) + case HashTy: + // hashtype currently not used + return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) + case FixedPointTy: + // fixedpoint type currently not used + return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) + case FunctionTy: + return reflect.ArrayOf(24, reflect.TypeOf(byte(0))) + default: + panic("Invalid type") + } +} + // String implements Stringer func (t Type) String() (out string) { return t.stringKind diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index fec0eb152b..df76646346 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -36,58 +36,58 @@ func TestTypeRegexp(t *testing.T) { components []ArgumentMarshaling kind Type }{ - {"bool", nil, Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}}, - {"bool[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]bool(nil)), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}}, - {"bool[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}}, - {"bool[2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, - {"bool[][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, - {"bool[][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, - {"bool[2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, - {"bool[2][][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][][2]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, - {"bool[2][2][2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, - {"bool[][][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, - {"bool[][2][]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Type: reflect.TypeOf([]bool{}), Elem: &Type{T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, - {"int8", nil, Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, - {"int16", nil, Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, - {"int32", nil, Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, - {"int64", nil, Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, - {"int256", nil, Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, - {"int8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, - {"int8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, - {"int16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, - {"int16[2]", nil, Type{Size: 2, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, - {"int32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, - {"int32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, - {"int64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, - {"int64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, - {"int256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, - {"int256[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, - {"uint8", nil, Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, - {"uint16", nil, Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, - {"uint32", nil, Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, - {"uint64", nil, Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, - {"uint256", nil, Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, - {"uint8[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, - {"uint8[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, - {"uint16[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, - {"uint16[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, - {"uint32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, - {"uint32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, - {"uint64[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, - {"uint64[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, - {"uint256[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, - {"uint256[2]", nil, Type{T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, - {"bytes32", nil, Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, - {"bytes[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, - {"bytes[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), stringKind: "bytes"}, stringKind: "bytes[2]"}}, - {"bytes32[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([][32]byte{}), Elem: &Type{Type: reflect.TypeOf([32]byte{}), T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, - {"bytes32[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][32]byte{}), Elem: &Type{T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, - {"string", nil, Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, - {"string[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]string{}), Elem: &Type{Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, - {"string[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, - {"address", nil, Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, - {"address[]", nil, Type{T: SliceTy, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, - {"address[2]", nil, Type{T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, + {"bool", nil, Type{T: BoolTy, stringKind: "bool"}}, + {"bool[]", nil, Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}}, + {"bool[2]", nil, Type{Size: 2, T: ArrayTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}}, + {"bool[2][]", nil, Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}}, + {"bool[][]", nil, Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}}, + {"bool[][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}}, + {"bool[2][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}}, + {"bool[2][][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][]"}, stringKind: "bool[2][][2]"}}, + {"bool[2][2][2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, + {"bool[][][]", nil, Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, + {"bool[][2][]", nil, Type{T: SliceTy, Elem: &Type{T: ArrayTy, Size: 2, Elem: &Type{T: SliceTy, Elem: &Type{T: BoolTy, stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, + {"int8", nil, Type{Size: 8, T: IntTy, stringKind: "int8"}}, + {"int16", nil, Type{Size: 16, T: IntTy, stringKind: "int16"}}, + {"int32", nil, Type{Size: 32, T: IntTy, stringKind: "int32"}}, + {"int64", nil, Type{Size: 64, T: IntTy, stringKind: "int64"}}, + {"int256", nil, Type{Size: 256, T: IntTy, stringKind: "int256"}}, + {"int8[]", nil, Type{T: SliceTy, Elem: &Type{Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, + {"int8[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, + {"int16[]", nil, Type{T: SliceTy, Elem: &Type{Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, + {"int16[2]", nil, Type{Size: 2, T: ArrayTy, Elem: &Type{Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, + {"int32[]", nil, Type{T: SliceTy, Elem: &Type{Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, + {"int32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, + {"int64[]", nil, Type{T: SliceTy, Elem: &Type{Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, + {"int64[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, + {"int256[]", nil, Type{T: SliceTy, Elem: &Type{Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, + {"int256[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, + {"uint8", nil, Type{Size: 8, T: UintTy, stringKind: "uint8"}}, + {"uint16", nil, Type{Size: 16, T: UintTy, stringKind: "uint16"}}, + {"uint32", nil, Type{Size: 32, T: UintTy, stringKind: "uint32"}}, + {"uint64", nil, Type{Size: 64, T: UintTy, stringKind: "uint64"}}, + {"uint256", nil, Type{Size: 256, T: UintTy, stringKind: "uint256"}}, + {"uint8[]", nil, Type{T: SliceTy, Elem: &Type{Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, + {"uint8[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, + {"uint16[]", nil, Type{T: SliceTy, Elem: &Type{Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, + {"uint16[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, + {"uint32[]", nil, Type{T: SliceTy, Elem: &Type{Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, + {"uint32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, + {"uint64[]", nil, Type{T: SliceTy, Elem: &Type{Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, + {"uint64[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, + {"uint256[]", nil, Type{T: SliceTy, Elem: &Type{Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, + {"uint256[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, + {"bytes32", nil, Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}}, + {"bytes[]", nil, Type{T: SliceTy, Elem: &Type{T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, + {"bytes[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[2]"}}, + {"bytes32[]", nil, Type{T: SliceTy, Elem: &Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, + {"bytes32[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: FixedBytesTy, Size: 32, stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, + {"string", nil, Type{T: StringTy, stringKind: "string"}}, + {"string[]", nil, Type{T: SliceTy, Elem: &Type{T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, + {"string[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{T: StringTy, stringKind: "string"}, stringKind: "string[2]"}}, + {"address", nil, Type{Size: 20, T: AddressTy, stringKind: "address"}}, + {"address[]", nil, Type{T: SliceTy, Elem: &Type{Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, + {"address[2]", nil, Type{T: ArrayTy, Size: 2, Elem: &Type{Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, // TODO when fixed types are implemented properly // {"fixed", nil, Type{}}, // {"fixed128x128", nil, Type{}}, @@ -95,14 +95,14 @@ func TestTypeRegexp(t *testing.T) { // {"fixed[2]", nil, Type{}}, // {"fixed128x128[]", nil, Type{}}, // {"fixed128x128[2]", nil, Type{}}, - {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { + {"tuple", []ArgumentMarshaling{{Name: "a", Type: "int64"}}, Type{T: TupleTy, TupleType: reflect.TypeOf(struct { A int64 `json:"a"` }{}), stringKind: "(int64)", - TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, - {"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{T: TupleTy, Type: reflect.TypeOf(struct { + TupleElems: []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}}}, + {"tuple with long name", []ArgumentMarshaling{{Name: "aTypicalParamName", Type: "int64"}}, Type{T: TupleTy, TupleType: reflect.TypeOf(struct { ATypicalParamName int64 `json:"aTypicalParamName"` }{}), stringKind: "(int64)", - TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, + TupleElems: []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"aTypicalParamName"}}}, } for _, tt := range tests { @@ -312,12 +312,12 @@ func TestInternalType(t *testing.T) { internalType := "struct a.b[]" kind := Type{ T: TupleTy, - Type: reflect.TypeOf(struct { + TupleType: reflect.TypeOf(struct { A int64 `json:"a"` }{}), stringKind: "(int64)", TupleRawName: "ab[]", - TupleElems: []*Type{{T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}}, + TupleElems: []*Type{{T: IntTy, Size: 64, stringKind: "int64"}}, TupleRawNames: []string{"a"}, } diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index f7d53877e2..e438c86234 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -35,32 +35,36 @@ var ( // ReadInteger reads the integer based on its kind and returns the appropriate value func ReadInteger(typ Type, b []byte) interface{} { - switch typ.Type { - case uint8T: - return b[len(b)-1] - case uint16T: - return binary.BigEndian.Uint16(b[len(b)-2:]) - case uint32T: - return binary.BigEndian.Uint32(b[len(b)-4:]) - case uint64T: - return binary.BigEndian.Uint64(b[len(b)-8:]) - case int8T: + if typ.T == UintTy { + switch typ.Size { + case 8: + return b[len(b)-1] + case 16: + return binary.BigEndian.Uint16(b[len(b)-2:]) + case 32: + return binary.BigEndian.Uint32(b[len(b)-4:]) + case 64: + return binary.BigEndian.Uint64(b[len(b)-8:]) + default: + // the only case left for unsigned integer is uint256. + return new(big.Int).SetBytes(b) + } + } + switch typ.Size { + case 8: return int8(b[len(b)-1]) - case int16T: + case 16: return int16(binary.BigEndian.Uint16(b[len(b)-2:])) - case int32T: + case 32: return int32(binary.BigEndian.Uint32(b[len(b)-4:])) - case int64T: + case 64: return int64(binary.BigEndian.Uint64(b[len(b)-8:])) default: - // the only case left for integer is int256/uint256. - ret := new(big.Int).SetBytes(b) - if typ.T == UintTy { - return ret - } + // the only case left for integer is int256 // big.SetBytes can't tell if a number is negative or positive in itself. // On EVM, if the returned number > max int256, it is negative. // A number is > max int256 if the bit at position 255 is set. + ret := new(big.Int).SetBytes(b) if ret.Bit(255) == 1 { ret.Add(MaxUint256, new(big.Int).Neg(ret)) ret.Add(ret, common.Big1) @@ -107,7 +111,7 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) { return nil, errors.New("abi: invalid type in call to make fixed byte array") } // convert - array := reflect.New(t.Type).Elem() + array := reflect.New(t.getType()).Elem() reflect.Copy(array, reflect.ValueOf(word[0:t.Size])) return array.Interface(), nil @@ -128,10 +132,10 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) if t.T == SliceTy { // declare our slice - refSlice = reflect.MakeSlice(t.Type, size, size) + refSlice = reflect.MakeSlice(t.getType(), size, size) } else if t.T == ArrayTy { // declare our array - refSlice = reflect.New(t.Type).Elem() + refSlice = reflect.New(t.getType()).Elem() } else { return nil, errors.New("abi: invalid type in array/slice unpacking stage") } @@ -155,7 +159,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) } func forTupleUnpack(t Type, output []byte) (interface{}, error) { - retval := reflect.New(t.Type).Elem() + retval := reflect.New(t.getType()).Elem() virtualArgs := 0 for index, elem := range t.TupleElems { marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output) diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index d52268d7e7..fabd5f6b88 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -33,7 +33,7 @@ import ( // TestUnpack tests the general pack/unpack tests in packing_test.go func TestUnpack(t *testing.T) { for i, test := range packUnpackTests { - t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Run(strconv.Itoa(i)+" "+test.def, func(t *testing.T) { //Unpack def := fmt.Sprintf(`[{ "name" : "method", "type": "function", "outputs": %s}]`, test.def) abi, err := JSON(strings.NewReader(def)) From 7e3079cedc46ab1aa640d43739a05bcf710da7d3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 110/280] accounts/abi: move topics to abi package (#21057) * accounts/abi/bind: added test cases for waitDeployed * accounts/abi/bind: added test case for boundContract * accounts/abi/bind: removed unnecessary resolve methods * accounts/abi: moved topics from /bind to /abi * accounts/abi/bind: cleaned up format... functions * accounts/abi: improved log message * accounts/abi: added type tests * accounts/abi/bind: remove superfluous template methods --- accounts/abi/argument.go | 4 +- accounts/abi/bind/base.go | 8 +- accounts/abi/bind/bind.go | 77 +------------- accounts/abi/bind/template.go | 30 +++--- accounts/abi/bind/util_test.go | 40 +++++++- accounts/abi/{bind => }/topics.go | 31 +++--- accounts/abi/{bind => }/topics_test.go | 135 ++++++++++++++++++++++--- accounts/abi/unpack.go | 11 +- 8 files changed, 201 insertions(+), 135 deletions(-) rename accounts/abi/{bind => }/topics.go (84%) rename accounts/abi/{bind => }/topics_test.go (67%) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index c0c87c5308..5c1e391f51 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -275,7 +275,7 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { retval := make([]interface{}, 0, len(nonIndexedArgs)) virtualArgs := 0 for index, arg := range nonIndexedArgs { - marshalledValue, err := ToGoType((index+virtualArgs)*32, arg.Type, data) + marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. @@ -312,7 +312,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { // Make sure arguments match up and pack them abiArgs := arguments if len(args) != len(abiArgs) { - return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(abiArgs)) + return nil, fmt.Errorf("argument count mismatch: got %d for %d", len(args), len(abiArgs)) } // variable input is the output appended at the end of packed // output. This is used for strings and bytes types input. diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 48b136ffbe..80578e280d 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -378,7 +378,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int // Append the event selector to the query parameters and construct the topic set query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) - topics, err := makeTopics(query...) + topics, err := abi.MakeTopics(query...) if err != nil { return nil, nil, err } @@ -424,7 +424,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter // Append the event selector to the query parameters and construct the topic set query = append([][]interface{}{{c.abi.Events[name].ID}}, query...) - topics, err := makeTopics(query...) + topics, err := abi.MakeTopics(query...) if err != nil { return nil, nil, err } @@ -465,7 +465,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) indexed = append(indexed, arg) } } - return parseTopics(out, indexed, log.Topics[1:]) + return abi.ParseTopics(out, indexed, log.Topics[1:]) } // UnpackLogIntoMap unpacks a retrieved log into the provided map. @@ -481,7 +481,7 @@ func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event strin indexed = append(indexed, arg) } } - return parseTopicsIntoMap(out, indexed, log.Topics[1:]) + return abi.ParseTopicsIntoMap(out, indexed, log.Topics[1:]) } // ensureContext is a helper method to ensure a context is not nil, even if the diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index a90f0492ca..53e278274b 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -213,8 +213,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] "bindtype": bindType[lang], "bindtopictype": bindTopicType[lang], "namedtype": namedType[lang], - "formatmethod": formatMethod, - "formatevent": formatEvent, "capitalise": capitalise, "decapitalise": decapitalise, } @@ -370,9 +368,7 @@ var methodNormalizer = map[Lang]func(string) string{ } // capitalise makes a camel-case string which starts with an upper case character. -func capitalise(input string) string { - return abi.ToCamelCase(input) -} +var capitalise = abi.ToCamelCase // decapitalise makes a camel-case string which starts with a lower case character. func decapitalise(input string) string { @@ -421,74 +417,3 @@ func hasStruct(t abi.Type) bool { return false } } - -// resolveArgName converts a raw argument representation into a user friendly format. -func resolveArgName(arg abi.Argument, structs map[string]*tmplStruct) string { - var ( - prefix string - embedded string - typ = &arg.Type - ) -loop: - for { - switch typ.T { - case abi.SliceTy: - prefix += "[]" - case abi.ArrayTy: - prefix += fmt.Sprintf("[%d]", typ.Size) - default: - embedded = typ.TupleRawName + typ.String() - break loop - } - typ = typ.Elem - } - if s, exist := structs[embedded]; exist { - return prefix + s.Name - } else { - return arg.Type.String() - } -} - -// formatMethod transforms raw method representation into a user friendly one. -func formatMethod(method abi.Method, structs map[string]*tmplStruct) string { - inputs := make([]string, len(method.Inputs)) - for i, input := range method.Inputs { - inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name) - } - outputs := make([]string, len(method.Outputs)) - for i, output := range method.Outputs { - outputs[i] = resolveArgName(output, structs) - if len(output.Name) > 0 { - outputs[i] += fmt.Sprintf(" %v", output.Name) - } - } - // Extract meaningful state mutability of solidity method. - // If it's default value, never print it. - state := method.StateMutability - if state == "nonpayable" { - state = "" - } - if state != "" { - state = state + " " - } - identity := fmt.Sprintf("function %v", method.RawName) - if method.Type == abi.Fallback { - identity = "fallback" - } else if method.Type == abi.Receive { - identity = "receive" - } - return fmt.Sprintf("%s(%v) %sreturns(%v)", identity, strings.Join(inputs, ", "), state, strings.Join(outputs, ", ")) -} - -// formatEvent transforms raw event representation into a user friendly one. -func formatEvent(event abi.Event, structs map[string]*tmplStruct) string { - inputs := make([]string, len(event.Inputs)) - for i, input := range event.Inputs { - if input.Indexed { - inputs[i] = fmt.Sprintf("%v indexed %v", resolveArgName(input, structs), input.Name) - } else { - inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name) - } - } - return fmt.Sprintf("event %v(%v)", event.RawName, strings.Join(inputs, ", ")) -} diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 00d38a6a1e..0c2ae8957c 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -296,7 +296,7 @@ var ( {{range .Calls}} // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { {{if .Structured}}ret := new(struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}} @@ -315,14 +315,14 @@ var ( // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } @@ -331,21 +331,21 @@ var ( {{range .Transacts}} // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) } // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatmethod .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) } @@ -354,21 +354,21 @@ var ( {{if .Fallback}} // Fallback is a paid mutator transaction binding the contract fallback function. // - // Solidity: {{formatmethod .Fallback.Original $structs}} + // Solidity: {{.Fallback.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { return _{{$contract.Type}}.contract.RawTransact(opts, calldata) } // Fallback is a paid mutator transaction binding the contract fallback function. // - // Solidity: {{formatmethod .Fallback.Original $structs}} + // Solidity: {{.Fallback.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) } // Fallback is a paid mutator transaction binding the contract fallback function. // - // Solidity: {{formatmethod .Fallback.Original $structs}} + // Solidity: {{.Fallback.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) } @@ -377,21 +377,21 @@ var ( {{if .Receive}} // Receive is a paid mutator transaction binding the contract receive function. // - // Solidity: {{formatmethod .Receive.Original $structs}} + // Solidity: {{.Receive.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function } // Receive is a paid mutator transaction binding the contract receive function. // - // Solidity: {{formatmethod .Receive.Original $structs}} + // Solidity: {{.Receive.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) } // Receive is a paid mutator transaction binding the contract receive function. // - // Solidity: {{formatmethod .Receive.Original $structs}} + // Solidity: {{.Receive.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) } @@ -470,7 +470,7 @@ var ( // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatevent .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { {{range .Normalized.Inputs}} {{if .Indexed}}var {{.Name}}Rule []interface{} @@ -487,7 +487,7 @@ var ( // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatevent .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { {{range .Normalized.Inputs}} {{if .Indexed}}var {{.Name}}Rule []interface{} @@ -529,7 +529,7 @@ var ( // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. // - // Solidity: {{formatevent .Original $structs}} + // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { event := new({{$contract.Type}}{{.Normalized.Name}}) if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 7475374c4f..3ebc832ccd 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -18,6 +18,7 @@ package bind_test import ( "context" + "errors" "math/big" "testing" "time" @@ -91,7 +92,7 @@ func TestWaitDeployed(t *testing.T) { select { case <-mined: if err != test.wantErr { - t.Errorf("test %q: error mismatch: got %q, want %q", name, err, test.wantErr) + t.Errorf("test %q: error mismatch: want %q, got %q", name, test.wantErr, err) } if address != test.wantAddress { t.Errorf("test %q: unexpected contract address %s", name, address.Hex()) @@ -101,3 +102,40 @@ func TestWaitDeployed(t *testing.T) { } } } + +func TestWaitDeployedCornerCases(t *testing.T) { + backend := backends.NewSimulatedBackend( + core.GenesisAlloc{ + crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)}, + }, + 10000000, + ) + defer backend.Close() + + // Create a transaction to an account. + code := "6060604052600a8060106000396000f360606040526008565b00" + tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code)) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + backend.SendTransaction(ctx, tx) + backend.Commit() + notContentCreation := errors.New("tx is not contract creation") + if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() { + t.Errorf("error missmatch: want %q, got %q, ", notContentCreation, err) + } + + // Create a transaction that is not mined. + tx = types.NewContractCreation(1, big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code)) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) + + go func() { + contextCanceled := errors.New("context canceled") + if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != contextCanceled.Error() { + t.Errorf("error missmatch: want %q, got %q, ", contextCanceled, err) + } + }() + + backend.SendTransaction(ctx, tx) + cancel() +} diff --git a/accounts/abi/bind/topics.go b/accounts/abi/topics.go similarity index 84% rename from accounts/abi/bind/topics.go rename to accounts/abi/topics.go index 0bee4f39a1..a46968b385 100644 --- a/accounts/abi/bind/topics.go +++ b/accounts/abi/topics.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package bind +package abi import ( "encoding/binary" @@ -23,13 +23,12 @@ import ( "math/big" "reflect" - "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" ) -// makeTopics converts a filter query argument list into a filter topic set. -func makeTopics(query ...[]interface{}) ([][]common.Hash, error) { +// MakeTopics converts a filter query argument list into a filter topic set. +func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) { topics := make([][]common.Hash, len(query)) for i, filter := range query { for _, rule := range filter { @@ -112,19 +111,19 @@ func genIntType(rule int64, size uint) []byte { return topic[:] } -// parseTopics converts the indexed topic fields into actual log field values. -func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) error { +// ParseTopics converts the indexed topic fields into actual log field values. +func ParseTopics(out interface{}, fields Arguments, topics []common.Hash) error { return parseTopicWithSetter(fields, topics, - func(arg abi.Argument, reconstr interface{}) { - field := reflect.ValueOf(out).Elem().FieldByName(capitalise(arg.Name)) + func(arg Argument, reconstr interface{}) { + field := reflect.ValueOf(out).Elem().FieldByName(ToCamelCase(arg.Name)) field.Set(reflect.ValueOf(reconstr)) }) } -// parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs -func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error { +// ParseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs +func ParseTopicsIntoMap(out map[string]interface{}, fields Arguments, topics []common.Hash) error { return parseTopicWithSetter(fields, topics, - func(arg abi.Argument, reconstr interface{}) { + func(arg Argument, reconstr interface{}) { out[arg.Name] = reconstr }) } @@ -134,7 +133,7 @@ func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics // // Note, dynamic types cannot be reconstructed since they get mapped to Keccak256 // hashes as the topic value! -func parseTopicWithSetter(fields abi.Arguments, topics []common.Hash, setter func(abi.Argument, interface{})) error { +func parseTopicWithSetter(fields Arguments, topics []common.Hash, setter func(Argument, interface{})) error { // Sanity check that the fields and topics match up if len(fields) != len(topics) { return errors.New("topic/field count mismatch") @@ -146,13 +145,13 @@ func parseTopicWithSetter(fields abi.Arguments, topics []common.Hash, setter fun } var reconstr interface{} switch arg.Type.T { - case abi.TupleTy: + case TupleTy: return errors.New("tuple type in topic reconstruction") - case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy: + case StringTy, BytesTy, SliceTy, ArrayTy: // Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash // whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash reconstr = topics[i] - case abi.FunctionTy: + case FunctionTy: if garbage := binary.BigEndian.Uint64(topics[i][0:8]); garbage != 0 { return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[i].Bytes()) } @@ -161,7 +160,7 @@ func parseTopicWithSetter(fields abi.Arguments, topics []common.Hash, setter fun reconstr = tmp default: var err error - reconstr, err = abi.ToGoType(0, arg.Type, topics[i].Bytes()) + reconstr, err = toGoType(0, arg.Type, topics[i].Bytes()) if err != nil { return err } diff --git a/accounts/abi/bind/topics_test.go b/accounts/abi/topics_test.go similarity index 67% rename from accounts/abi/bind/topics_test.go rename to accounts/abi/topics_test.go index c74b90cacd..1ebf3eb7c2 100644 --- a/accounts/abi/bind/topics_test.go +++ b/accounts/abi/topics_test.go @@ -14,14 +14,13 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package bind +package abi import ( "math/big" "reflect" "testing" - "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -119,7 +118,7 @@ func TestMakeTopics(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := makeTopics(tt.args.query...) + got, err := MakeTopics(tt.args.query...) if (err != nil) != tt.wantErr { t.Errorf("makeTopics() error = %v, wantErr %v", err, tt.wantErr) return @@ -135,7 +134,7 @@ type args struct { createObj func() interface{} resultObj func() interface{} resultMap func() map[string]interface{} - fields abi.Arguments + fields Arguments topics []common.Hash } @@ -149,6 +148,14 @@ type int256Struct struct { Int256Value *big.Int } +type hashStruct struct { + HashValue common.Hash +} + +type funcStruct struct { + FuncValue [24]byte +} + type topicTest struct { name string args args @@ -156,10 +163,12 @@ type topicTest struct { } func setupTopicsTests() []topicTest { - bytesType, _ := abi.NewType("bytes5", "", nil) - int8Type, _ := abi.NewType("int8", "", nil) - int256Type, _ := abi.NewType("int256", "", nil) - tupleType, _ := abi.NewType("tuple(int256,int8)", "", nil) + bytesType, _ := NewType("bytes5", "", nil) + int8Type, _ := NewType("int8", "", nil) + int256Type, _ := NewType("int256", "", nil) + tupleType, _ := NewType("tuple(int256,int8)", "", nil) + stringType, _ := NewType("string", "", nil) + funcType, _ := NewType("function", "", nil) tests := []topicTest{ { @@ -170,7 +179,7 @@ func setupTopicsTests() []topicTest { resultMap: func() map[string]interface{} { return map[string]interface{}{"staticBytes": [5]byte{1, 2, 3, 4, 5}} }, - fields: abi.Arguments{abi.Argument{ + fields: Arguments{Argument{ Name: "staticBytes", Type: bytesType, Indexed: true, @@ -189,7 +198,7 @@ func setupTopicsTests() []topicTest { resultMap: func() map[string]interface{} { return map[string]interface{}{"int8Value": int8(-1)} }, - fields: abi.Arguments{abi.Argument{ + fields: Arguments{Argument{ Name: "int8Value", Type: int8Type, Indexed: true, @@ -209,7 +218,7 @@ func setupTopicsTests() []topicTest { resultMap: func() map[string]interface{} { return map[string]interface{}{"int256Value": big.NewInt(-1)} }, - fields: abi.Arguments{abi.Argument{ + fields: Arguments{Argument{ Name: "int256Value", Type: int256Type, Indexed: true, @@ -222,12 +231,55 @@ func setupTopicsTests() []topicTest { wantErr: false, }, { - name: "tuple(int256, int8)", + name: "hash type", + args: args{ + createObj: func() interface{} { return &hashStruct{} }, + resultObj: func() interface{} { return &hashStruct{crypto.Keccak256Hash([]byte("stringtopic"))} }, + resultMap: func() map[string]interface{} { + return map[string]interface{}{"hashValue": crypto.Keccak256Hash([]byte("stringtopic"))} + }, + fields: Arguments{Argument{ + Name: "hashValue", + Type: stringType, + Indexed: true, + }}, + topics: []common.Hash{ + crypto.Keccak256Hash([]byte("stringtopic")), + }, + }, + wantErr: false, + }, + { + name: "function type", + args: args{ + createObj: func() interface{} { return &funcStruct{} }, + resultObj: func() interface{} { + return &funcStruct{[24]byte{255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}} + }, + resultMap: func() map[string]interface{} { + return map[string]interface{}{"funcValue": [24]byte{255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}} + }, + fields: Arguments{Argument{ + Name: "funcValue", + Type: funcType, + Indexed: true, + }}, + topics: []common.Hash{ + {0, 0, 0, 0, 0, 0, 0, 0, 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: "error on topic/field count mismatch", 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{ + fields: Arguments{Argument{ Name: "tupletype", Type: tupleType, Indexed: true, @@ -236,6 +288,59 @@ func setupTopicsTests() []topicTest { }, wantErr: true, }, + { + name: "error on unindexed arguments", + args: args{ + createObj: func() interface{} { return &int256Struct{} }, + resultObj: func() interface{} { return &int256Struct{} }, + resultMap: func() map[string]interface{} { return make(map[string]interface{}) }, + fields: Arguments{Argument{ + Name: "int256Value", + Type: int256Type, + Indexed: false, + }}, + 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: true, + }, + { + name: "error on tuple in topic reconstruction", + args: args{ + createObj: func() interface{} { return &tupleType }, + resultObj: func() interface{} { return &tupleType }, + resultMap: func() map[string]interface{} { return make(map[string]interface{}) }, + fields: Arguments{Argument{ + Name: "tupletype", + Type: tupleType, + Indexed: true, + }}, + topics: []common.Hash{{0}}, + }, + wantErr: true, + }, + { + name: "error on improper encoded function", + args: args{ + createObj: func() interface{} { return &funcStruct{} }, + resultObj: func() interface{} { return &funcStruct{} }, + resultMap: func() map[string]interface{} { + return make(map[string]interface{}) + }, + fields: Arguments{Argument{ + Name: "funcValue", + Type: funcType, + Indexed: true, + }}, + topics: []common.Hash{ + {0, 0, 0, 0, 0, 0, 0, 128, 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: true, + }, } return tests @@ -247,7 +352,7 @@ func TestParseTopics(t *testing.T) { 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 { + 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() @@ -264,7 +369,7 @@ func TestParseTopicsIntoMap(t *testing.T) { 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 { + 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() diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index e438c86234..278301776f 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -145,7 +145,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) elemSize := getTypeSize(*t.Elem) for i, j := start, 0; j < size; i, j = i+elemSize, j+1 { - inter, err := ToGoType(i, *t.Elem, output) + inter, err := toGoType(i, *t.Elem, output) if err != nil { return nil, err } @@ -162,7 +162,7 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { retval := reflect.New(t.getType()).Elem() virtualArgs := 0 for index, elem := range t.TupleElems { - marshalledValue, err := ToGoType((index+virtualArgs)*32, *elem, output) + marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output) if elem.T == ArrayTy && !isDynamicType(*elem) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. @@ -188,9 +188,9 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { return retval.Interface(), nil } -// ToGoType parses the output bytes and recursively assigns the value of these bytes +// toGoType parses the output bytes and recursively assigns the value of these bytes // into a go type with accordance with the ABI spec. -func ToGoType(index int, t Type, output []byte) (interface{}, error) { +func toGoType(index int, t Type, output []byte) (interface{}, error) { if index+32 > len(output) { return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32) } @@ -219,9 +219,8 @@ func ToGoType(index int, t Type, output []byte) (interface{}, error) { return nil, err } return forTupleUnpack(t, output[begin:]) - } else { - return forTupleUnpack(t, output[index:]) } + return forTupleUnpack(t, output[index:]) case SliceTy: return forEachUnpack(t, output[begin:], 0, length) case ArrayTy: From e836f32ba4ba8f6befac3e41fbb4a8b8ef071d15 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 111/280] accounts/abi: allow overloaded argument names (#21060) * accounts/abi: allow overloaded argument names In solidity it is possible to create the following contract: ``` contract Overloader { struct F { uint _f; uint __f; uint f; } function f(F memory f) public {} } ``` This however resulted in a panic in the abi package. * accounts/abi fixed error handling --- accounts/abi/abi_test.go | 10 ++++++++-- accounts/abi/type.go | 23 ++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index ee8ad048a0..48aa462357 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -57,7 +57,8 @@ const jsondata = ` { "type" : "function", "name" : "fixedArrBytes", "stateMutability" : "view", "inputs" : [ { "name" : "bytes", "type" : "bytes" }, { "name" : "fixedArr", "type" : "uint256[2]" } ] }, { "type" : "function", "name" : "mixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr", "type" : "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" } ] }, { "type" : "function", "name" : "doubleFixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type" : "uint256[2]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] }, - { "type" : "function", "name" : "multipleMixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type" : "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] } + { "type" : "function", "name" : "multipleMixedArrStr", "stateMutability" : "view", "inputs" : [ { "name" : "str", "type" : "string" }, { "name" : "fixedArr1", "type" : "uint256[2]" }, { "name" : "dynArr", "type" : "uint256[]" }, { "name" : "fixedArr2", "type" : "uint256[3]" } ] }, + { "type" : "function", "name" : "overloadedNames", "stateMutability" : "view", "inputs": [ { "components": [ { "internalType": "uint256", "name": "_f", "type": "uint256" }, { "internalType": "uint256", "name": "__f", "type": "uint256"}, { "internalType": "uint256", "name": "f", "type": "uint256"}],"internalType": "struct Overloader.F", "name": "f","type": "tuple"}]} ]` var ( @@ -80,6 +81,10 @@ var ( Uint256ArrNested, _ = NewType("uint256[2][2]", "", nil) Uint8ArrNested, _ = NewType("uint8[][2]", "", nil) Uint8SliceNested, _ = NewType("uint8[][]", "", nil) + TupleF, _ = NewType("tuple", "struct Overloader.F", []ArgumentMarshaling{ + {Name: "_f", Type: "uint256"}, + {Name: "__f", Type: "uint256"}, + {Name: "f", Type: "uint256"}}) ) var methods = map[string]Method{ @@ -108,6 +113,7 @@ var methods = map[string]Method{ "mixedArrStr": NewMethod("mixedArrStr", "mixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr", Uint256Arr2, false}, {"dynArr", Uint256Arr, false}}, nil), "doubleFixedArrStr": NewMethod("doubleFixedArrStr", "doubleFixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr1", Uint256Arr2, false}, {"fixedArr2", Uint256Arr3, false}}, nil), "multipleMixedArrStr": NewMethod("multipleMixedArrStr", "multipleMixedArrStr", Function, "view", false, false, []Argument{{"str", String, false}, {"fixedArr1", Uint256Arr2, false}, {"dynArr", Uint256Arr, false}, {"fixedArr2", Uint256Arr3, false}}, nil), + "overloadedNames": NewMethod("overloadedNames", "overloadedNames", Function, "view", false, false, []Argument{{"f", TupleF, false}}, nil), } func TestReader(t *testing.T) { @@ -117,7 +123,7 @@ func TestReader(t *testing.T) { exp, err := JSON(strings.NewReader(jsondata)) if err != nil { - t.Error(err) + t.Fatal(err) } for name, expM := range exp.Methods { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index eacea7f8c1..00f4c805f2 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -162,16 +162,19 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty expression string // canonical parameter expression ) expression += "(" + overloadedNames := make(map[string]string) for idx, c := range components { cType, err := NewType(c.Type, c.InternalType, c.Components) if err != nil { return Type{}, err } - if ToCamelCase(c.Name) == "" { - return Type{}, errors.New("abi: purely anonymous or underscored field is not supported") + fieldName, err := overloadedArgName(c.Name, overloadedNames) + if err != nil { + return Type{}, err } + overloadedNames[fieldName] = fieldName fields = append(fields, reflect.StructField{ - Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field. + Name: fieldName, // reflect.StructOf will panic for any exported field. Type: cType.getType(), Tag: reflect.StructTag("json:\"" + c.Name + "\""), }) @@ -245,6 +248,20 @@ func (t Type) getType() reflect.Type { } } +func overloadedArgName(rawName string, names map[string]string) (string, error) { + fieldName := ToCamelCase(rawName) + if fieldName == "" { + return "", errors.New("abi: purely anonymous or underscored field is not supported") + } + // Handle overloaded fieldNames + _, ok := names[fieldName] + for idx := 0; ok; idx++ { + fieldName = fmt.Sprintf("%s%d", ToCamelCase(rawName), idx) + _, ok = names[fieldName] + } + return fieldName, nil +} + // String implements Stringer func (t Type) String() (out string) { return t.stringKind From b9bcf17694f645458a5b018deb14d5ff14b66d37 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 112/280] accounts/abi: simplify reflection logic (#21058) * accounts/abi: simplified reflection logic * accounts/abi: simplified reflection logic * accounts/abi: removed unpack * accounts/abi: removed comments * accounts/abi: removed uneccessary complications * accounts/abi: minor changes in error messages * accounts/abi: removed unnused code * accounts/abi: fixed indexed argument unpacking * accounts/abi: removed superfluous test cases This commit removes two test cases. The first one is trivially invalid as we have the same test cases as passing in packing_test.go L375. The second one passes now, because we don't need the mapArgNamesToStructFields in unpack_atomic anymore. Checking for purely underscored arg names generally should not be something we do as the abi/contract is generally out of the control of the user. * accounts/abi: removed comments, debug println * accounts/abi: added commented out code * accounts/abi: addressed comments * accounts/abi: remove unnecessary dst.CanSet check * accounts/abi: added dst.CanSet checks --- accounts/abi/argument.go | 142 ++++++------------------------------ accounts/abi/event_test.go | 4 +- accounts/abi/reflect.go | 85 ++++++++++++--------- accounts/abi/unpack_test.go | 8 +- 4 files changed, 81 insertions(+), 158 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 5c1e391f51..81151ef0e0 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -122,149 +122,55 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) return nil } -// unpack sets the unmarshalled value to go format. -// Note the dst here must be settable. -func unpack(t *Type, dst interface{}, src interface{}) error { - var ( - dstVal = reflect.ValueOf(dst).Elem() - srcVal = reflect.ValueOf(src) - ) - tuple, typ := false, t - for { - if typ.T == SliceTy || typ.T == ArrayTy { - typ = typ.Elem - continue - } - tuple = typ.T == TupleTy - break - } - if !tuple { - return set(dstVal, srcVal) - } - - // Dereferences interface or pointer wrapper - dstVal = indirectInterfaceOrPtr(dstVal) - - switch t.T { - case TupleTy: - if dstVal.Kind() != reflect.Struct { - return fmt.Errorf("abi: invalid dst value for unpack, want struct, got %s", dstVal.Kind()) - } - fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, dstVal) - if err != nil { - return err - } - for i, elem := range t.TupleElems { - fname := fieldmap[t.TupleRawNames[i]] - field := dstVal.FieldByName(fname) - if !field.IsValid() { - return fmt.Errorf("abi: field %s can't found in the given value", t.TupleRawNames[i]) - } - if err := unpack(elem, field.Addr().Interface(), srcVal.Field(i).Interface()); err != nil { - return err - } - } - return nil - case SliceTy: - if dstVal.Kind() != reflect.Slice { - return fmt.Errorf("abi: invalid dst value for unpack, want slice, got %s", dstVal.Kind()) - } - slice := reflect.MakeSlice(dstVal.Type(), srcVal.Len(), srcVal.Len()) - for i := 0; i < slice.Len(); i++ { - if err := unpack(t.Elem, slice.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil { - return err - } - } - dstVal.Set(slice) - case ArrayTy: - if dstVal.Kind() != reflect.Array { - return fmt.Errorf("abi: invalid dst value for unpack, want array, got %s", dstVal.Kind()) - } - array := reflect.New(dstVal.Type()).Elem() - for i := 0; i < array.Len(); i++ { - if err := unpack(t.Elem, array.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil { - return err - } - } - dstVal.Set(array) - } - return nil -} - // unpackAtomic unpacks ( hexdata -> go ) a single value func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { - nonIndexedArgs := arguments.NonIndexed() - if len(nonIndexedArgs) == 0 { - return nil - } - argument := nonIndexedArgs[0] - elem := reflect.ValueOf(v).Elem() + dst := reflect.ValueOf(v).Elem() + src := reflect.ValueOf(marshalledValues) - if elem.Kind() == reflect.Struct && argument.Type.T != TupleTy { - fieldmap, err := mapArgNamesToStructFields([]string{argument.Name}, elem) - if err != nil { - return err - } - field := elem.FieldByName(fieldmap[argument.Name]) - if !field.IsValid() { - return fmt.Errorf("abi: field %s can't be found in the given value", argument.Name) - } - return unpack(&argument.Type, field.Addr().Interface(), marshalledValues) + if dst.Kind() == reflect.Struct && src.Kind() != reflect.Struct { + return set(dst.Field(0), src) } - return unpack(&argument.Type, elem.Addr().Interface(), marshalledValues) + return set(dst, src) } // unpackTuple unpacks ( hexdata -> go ) a batch of values. func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { - var ( - value = reflect.ValueOf(v).Elem() - typ = value.Type() - kind = value.Kind() - nonIndexedArgs = arguments.NonIndexed() - ) - if err := requireUnpackKind(value, len(nonIndexedArgs), arguments); err != nil { - return err - } + value := reflect.ValueOf(v).Elem() + nonIndexedArgs := arguments.NonIndexed() - // If the interface is a struct, get of abi->struct_field mapping - var abi2struct map[string]string - if kind == reflect.Struct { + switch value.Kind() { + case reflect.Struct: argNames := make([]string, len(nonIndexedArgs)) for i, arg := range nonIndexedArgs { argNames[i] = arg.Name } var err error - if abi2struct, err = mapArgNamesToStructFields(argNames, value); err != nil { + abi2struct, err := mapArgNamesToStructFields(argNames, value) + if err != nil { return err } - } - for i, arg := range nonIndexedArgs { - switch kind { - case reflect.Struct: + for i, arg := range nonIndexedArgs { field := value.FieldByName(abi2struct[arg.Name]) if !field.IsValid() { return fmt.Errorf("abi: field %s can't be found in the given value", arg.Name) } - if err := unpack(&arg.Type, field.Addr().Interface(), marshalledValues[i]); err != nil { + if err := set(field, reflect.ValueOf(marshalledValues[i])); err != nil { return err } - case reflect.Slice, reflect.Array: - if value.Len() < i { - return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len()) - } - v := value.Index(i) - if err := requireAssignable(v, reflect.ValueOf(marshalledValues[i])); err != nil { - return err - } - if err := unpack(&arg.Type, v.Addr().Interface(), marshalledValues[i]); err != nil { - return err - } - default: - return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", typ) } + case reflect.Slice, reflect.Array: + if value.Len() < len(marshalledValues) { + return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len()) + } + for i := range nonIndexedArgs { + if err := set(value.Index(i), reflect.ValueOf(marshalledValues[i])); err != nil { + return err + } + } + default: + return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", value.Type()) } return nil - } // UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification, diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index b3d517530d..836b3fadcf 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -312,14 +312,14 @@ func TestEventTupleUnpack(t *testing.T) { &[]interface{}{common.Address{}, new(big.Int)}, &[]interface{}{}, jsonEventPledge, - "abi: insufficient number of elements in the list/array for unpack, want 3, got 2", + "abi: insufficient number of arguments for unpack, want 3, got 2", "Can not unpack Pledge event into too short slice", }, { pledgeData1, new(map[string]interface{}), &[]interface{}{}, jsonEventPledge, - "abi: cannot unmarshal tuple into map[string]interface {}", + "abi:[2] cannot unmarshal tuple in to map[string]interface {}", "Can not unpack Pledge event into map", }, { mixedCaseData1, diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index dbff10ae6f..7892c730e3 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -17,6 +17,7 @@ package abi import ( + "errors" "fmt" "math/big" "reflect" @@ -32,14 +33,6 @@ func indirect(v reflect.Value) reflect.Value { return v } -// indirectInterfaceOrPtr recursively dereferences the value until value is not interface. -func indirectInterfaceOrPtr(v reflect.Value) reflect.Value { - if (v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr) && v.Elem().IsValid() { - return indirect(v.Elem()) - } - return v -} - // reflectIntType returns the reflect using the given size and // unsignedness. func reflectIntType(unsigned bool, size int) reflect.Type { @@ -90,7 +83,11 @@ func set(dst, src reflect.Value) error { case srcType.AssignableTo(dstType) && dst.CanSet(): dst.Set(src) case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice && dst.CanSet(): - setSlice(dst, src) + return setSlice(dst, src) + case dstType.Kind() == reflect.Array: + return setArray(dst, src) + case dstType.Kind() == reflect.Struct: + return setStruct(dst, src) default: return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type()) } @@ -100,33 +97,55 @@ func set(dst, src reflect.Value) error { // setSlice attempts to assign src to dst when slices are not assignable by default // e.g. src: [][]byte -> dst: [][15]byte // setSlice ignores if we cannot copy all of src' elements. -func setSlice(dst, src reflect.Value) { +func setSlice(dst, src reflect.Value) error { slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) for i := 0; i < src.Len(); i++ { - reflect.Copy(slice.Index(i), src.Index(i)) - } - dst.Set(slice) -} - -// requireAssignable assures that `dest` is a pointer and it's not an interface. -func requireAssignable(dst, src reflect.Value) error { - if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface { - return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type()) - } - return nil -} - -// requireUnpackKind verifies preconditions for unpacking `args` into `kind` -func requireUnpackKind(v reflect.Value, minLength int, args Arguments) error { - switch v.Kind() { - case reflect.Struct: - case reflect.Slice, reflect.Array: - if v.Len() < minLength { - return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d", - minLength, v.Len()) + if src.Index(i).Kind() == reflect.Struct { + if err := set(slice.Index(i), src.Index(i)); err != nil { + return err + } + } else { + // e.g. [][32]uint8 to []common.Hash + if err := set(slice.Index(i), src.Index(i)); err != nil { + return err + } + } + } + if dst.CanSet() { + dst.Set(slice) + return nil + } + return errors.New("Cannot set slice, destination not settable") +} + +func setArray(dst, src reflect.Value) error { + array := reflect.New(dst.Type()).Elem() + min := src.Len() + if src.Len() > dst.Len() { + min = dst.Len() + } + for i := 0; i < min; i++ { + if err := set(array.Index(i), src.Index(i)); err != nil { + return err + } + } + if dst.CanSet() { + dst.Set(array) + return nil + } + return errors.New("Cannot set array, destination not settable") +} + +func setStruct(dst, src reflect.Value) error { + for i := 0; i < src.NumField(); i++ { + srcField := src.Field(i) + dstField := dst.Field(i) + if !dstField.IsValid() || !srcField.IsValid() { + return fmt.Errorf("Could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField) + } + if err := set(dstField, srcField); err != nil { + return err } - default: - return fmt.Errorf("abi: cannot unmarshal tuple into %v", v.Type()) } return nil } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index fabd5f6b88..d51031442a 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -120,8 +120,7 @@ var unpackTests = []unpackTest{ { def: `[{"type": "bytes"}]`, enc: "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200100000000000000000000000000000000000000000000000000000000000000", - want: [32]byte{}, - err: "abi: cannot unmarshal []uint8 in to [32]uint8", + want: [32]byte{1}, }, { def: `[{"type": "bytes32"}]`, @@ -135,8 +134,7 @@ var unpackTests = []unpackTest{ want: struct { IntOne *big.Int Intone *big.Int - }{}, - err: "abi: purely underscored output cannot unpack to struct", + }{IntOne: big.NewInt(1)}, }, { def: `[{"name":"int_one","type":"int256"},{"name":"IntOne","type":"int256"}]`, @@ -362,7 +360,7 @@ func TestMethodMultiReturn(t *testing.T) { }, { &[]interface{}{new(int)}, &[]interface{}{}, - "abi: insufficient number of elements in the list/array for unpack, want 2, got 1", + "abi: insufficient number of arguments for unpack, want 2, got 1", "Can not unpack into a slice with wrong types", }} for _, tc := range testCases { From e28727e2c991227b72bbeb02bf6372537db84611 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:10 +0800 Subject: [PATCH 113/280] accounts: add blockByNumberNoLock() to avoid double-lock (#20983) * abi/bind/backends: testcase for double-lock * accounts: add blockByNumberNoLock to avoid double-lock * backend/simulated: use stateroot, not blockhash for retrieveing state Co-authored-by: Martin Holst Swende --- accounts/abi/bind/backends/simulated.go | 10 ++++++++-- accounts/abi/bind/backends/simulated_test.go | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fe5ae20a74..fd7885b553 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -208,11 +208,11 @@ func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber * if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 { return b.blockchain.State() } - block, err := b.BlockByNumber(ctx, blockNumber) + block, err := b.blockByNumberNoLock(ctx, blockNumber) if err != nil { return nil, err } - return b.blockchain.StateAt(block.Hash()) + return b.blockchain.StateAt(block.Root()) } // CodeAt returns the code associated with a certain account in the blockchain. @@ -332,6 +332,12 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) ( b.mu.Lock() defer b.mu.Unlock() + return b.blockByNumberNoLock(ctx, number) +} + +// blockByNumberNoLock retrieves a block from the database by number, caching it +// (associated with its hash) if found without Lock. +func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) { if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 { return b.blockchain.CurrentBlock(), nil } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 632fc7290e..99aebcb617 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -268,6 +268,16 @@ func TestSimulatedBackend_NonceAt(t *testing.T) { if newNonce != nonce+uint64(1) { t.Errorf("received incorrect nonce. expected 1, got %v", nonce) } + // create some more blocks + sim.Commit() + // Check that we can get data for an older block/state + newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1)) + if err != nil { + t.Fatalf("could not get nonce for test addr: %v", err) + } + if newNonce != nonce+uint64(1) { + t.Fatalf("received incorrect nonce. expected 1, got %v", nonce) + } } func TestSimulatedBackend_SendTransaction(t *testing.T) { From afc814b00df337f965997265176185457968549c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 114/280] accounts: fix typos in comments (#21118) --- accounts/abi/bind/base.go | 2 +- accounts/abi/bind/template.go | 2 +- accounts/abi/type.go | 2 +- accounts/hd_test.go | 2 +- accounts/scwallet/hub.go | 2 +- accounts/scwallet/wallet.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 80578e280d..ee66ae5c86 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -53,7 +53,7 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) - Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds) + Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds) GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle) GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 0c2ae8957c..49c877d4a4 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -64,7 +64,7 @@ type tmplField struct { SolKind abi.Type // Raw abi type information } -// tmplStruct is a wrapper around an abi.tuple contains a auto-generated +// tmplStruct is a wrapper around an abi.tuple contains an auto-generated // struct name. type tmplStruct struct { Name string // Auto-generated struct name(before solidity v0.5.11) or raw name. diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 00f4c805f2..999d57e2e4 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -98,7 +98,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty typ.Elem = &embeddedType typ.stringKind = embeddedType.stringKind + sliced } else if len(intz) == 1 { - // is a array + // is an array typ.T = ArrayTy typ.Elem = &embeddedType typ.Size, err = strconv.Atoi(intz[0]) diff --git a/accounts/hd_test.go b/accounts/hd_test.go index b6b23230dc..3156a487ee 100644 --- a/accounts/hd_test.go +++ b/accounts/hd_test.go @@ -61,7 +61,7 @@ func TestHDPathParsing(t *testing.T) { // Weird inputs just to ensure they work {" m / 44 '\n/\n 60 \n\n\t' /\n0 ' /\t\t 0", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - // Invaid derivation paths + // Invalid derivation paths {"", nil}, // Empty relative derivation path {"m", nil}, // Empty absolute derivation path {"m/", nil}, // Missing last derivation component diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index 93267984f0..9f5c32570d 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -220,7 +220,7 @@ func (hub *Hub) refreshWallets() { // Mark the reader as present seen[reader] = struct{}{} - // If we alreay know about this card, skip to the next reader, otherwise clean up + // If we already know about this card, skip to the next reader, otherwise clean up if wallet, ok := hub.wallets[reader]; ok { if err := wallet.ping(); err == nil { continue diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index af557a7018..8dfabcd6c3 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -362,7 +362,7 @@ func (w *Wallet) Open(passphrase string) error { return err } // Pairing succeeded, fall through to PIN checks. This will of course fail, - // but we can't return ErrPINNeeded directly here becase we don't know whether + // but we can't return ErrPINNeeded directly here because we don't know whether // a PIN check or a PIN reset is needed. passphrase = "" } From d918e53c8ae80ceca10186cdaf53ac43ac6142a9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 115/280] acounts/keystore, cmd/faucet: fix faucet double import (#21172) --- accounts/keystore/keystore.go | 8 ++++++-- cmd/faucet/faucet.go | 9 ++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 470102034e..bcd4845ce5 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -43,6 +43,10 @@ var ( ErrLocked = accounts.NewAuthNeededError("password or unlock") ErrNoMatch = errors.New("no key for given address or file") ErrDecrypt = errors.New("could not decrypt key with given password") + + // ErrAccountAlreadyExists is returned if an account attempted to import is + // already present in the keystore. + ErrAccountAlreadyExists = errors.New("account alreaady exists") ) // KeyStoreType is the reflect type of a keystore backend. @@ -453,7 +457,7 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac ks.importMu.Lock() defer ks.importMu.Unlock() if ks.cache.hasAddress(key.Address) { - return accounts.Account{}, errors.New("account already exists") + return accounts.Account{}, ErrAccountAlreadyExists } return ks.importKey(key, newPassphrase) } @@ -464,7 +468,7 @@ func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (acco ks.importMu.Lock() defer ks.importMu.Unlock() if ks.cache.hasAddress(key.Address) { - return accounts.Account{}, errors.New("account already exists") + return accounts.Account{}, ErrAccountAlreadyExists } return ks.importKey(key, passphrase) } diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 393dbed9c3..599a7ff57a 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -163,7 +163,7 @@ func main() { log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err) } acc, err := ks.Import(blob, pass, pass) - if err != nil { + if err != nil && err != keystore.ErrAccountAlreadyExists { log.Crit("Failed to import faucet signer account", "err", err) } ks.Unlock(acc, pass) @@ -710,8 +710,11 @@ func authTwitter(url string) (string, string, common.Address, error) { return "", "", common.Address{}, errors.New("invalid Twitter status URL") } // Twitter's API isn't really friendly with direct links. Still, we don't - // want to do ask read permissions from users, so just load the public posts and - // scrape it for the Ethereum address and profile URL. + // want to do ask read permissions from users, so just load the public posts + // and scrape it for the Ethereum address and profile URL. We need to load + // the mobile page though since the main page loads tweet contents via JS. + url = strings.Replace(url, "https://twitter.com/", "https://mobile.twitter.com/", 1) + res, err := http.Get(url) if err != nil { return "", "", common.Address{}, err From 5e3755c46a7e3c5bd0c0db02f5269892a2f5a7be Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 116/280] accounts/keystore, cmd/faucet: return old account to allow unlock (#21173) --- accounts/keystore/keystore.go | 12 +++++++++--- cmd/faucet/faucet.go | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index bcd4845ce5..09dd02cc98 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -456,19 +456,25 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac } ks.importMu.Lock() defer ks.importMu.Unlock() + if ks.cache.hasAddress(key.Address) { - return accounts.Account{}, ErrAccountAlreadyExists + return accounts.Account{ + Address: key.Address, + }, ErrAccountAlreadyExists } return ks.importKey(key, newPassphrase) } // ImportECDSA stores the given key into the key directory, encrypting it with the passphrase. func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { - key := newKeyFromECDSA(priv) ks.importMu.Lock() defer ks.importMu.Unlock() + + key := newKeyFromECDSA(priv) if ks.cache.hasAddress(key.Address) { - return accounts.Account{}, ErrAccountAlreadyExists + return accounts.Account{ + Address: key.Address, + }, ErrAccountAlreadyExists } return ks.importKey(key, passphrase) } diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 599a7ff57a..64b7f3c1f2 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -156,7 +156,7 @@ func main() { if blob, err = os.ReadFile(*accPassFlag); err != nil { log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err) } - pass := string(blob) + pass := strings.TrimSuffix(string(blob), "\n") ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP) if blob, err = os.ReadFile(*accJSONFlag); err != nil { @@ -166,8 +166,9 @@ func main() { if err != nil && err != keystore.ErrAccountAlreadyExists { log.Crit("Failed to import faucet signer account", "err", err) } - ks.Unlock(acc, pass) - + if err := ks.Unlock(acc, pass); err != nil { + log.Crit("Failed to unlock faucet signer account", "err", err) + } // Assemble and start the faucet light service faucet, err := newFaucet(genesis, *ethPortFlag, enodes, *netFlag, *statsFlag, ks, website.Bytes()) if err != nil { From ef80645f90d1a62b670e3c8476c1d604fa92663b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 117/280] accounts/abi/bind: fix test --- accounts/abi/bind/bind_test.go | 299 +++++++++++++++++++++++++++++++++ params/config.go | 2 +- 2 files changed, 300 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 003cdf09e8..243dce37ef 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1116,6 +1116,249 @@ var bindTests = []struct { nil, nil, }, + { + `Tuple`, + ` + pragma solidity >=0.4.19 <0.6.0; + pragma experimental ABIEncoderV2; + + contract Tuple { + struct S { uint a; uint[] b; T[] c; } + struct T { uint x; uint y; } + struct P { uint8 x; uint8 y; } + struct Q { uint16 x; uint16 y; } + event TupleEvent(S a, T[2][] b, T[][2] c, S[] d, uint[] e); + event TupleEvent2(P[]); + + function func1(S memory a, T[2][] memory b, T[][2] memory c, S[] memory d, uint[] memory e) public pure returns (S memory, T[2][] memory, T[][2] memory, S[] memory, uint[] memory) { + return (a, b, c, d, e); + } + function func2(S memory a, T[2][] memory b, T[][2] memory c, S[] memory d, uint[] memory e) public { + emit TupleEvent(a, b, c, d, e); + } + function func3(Q[] memory) public pure {} // call function, nothing to return + } + `, + []string{`60806040523480156100115760006000fd5b50610017565b6110b2806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100465760003560e01c8063443c79b41461004c578063d0062cdd14610080578063e4d9a43b1461009c57610046565b60006000fd5b610066600480360361006191908101906107b8565b6100b8565b604051610077959493929190610ccb565b60405180910390f35b61009a600480360361009591908101906107b8565b6100ef565b005b6100b660048036036100b19190810190610775565b610136565b005b6100c061013a565b60606100ca61015e565b606060608989898989945094509450945094506100e2565b9550955095509550959050565b7f18d6e66efa53739ca6d13626f35ebc700b31cced3eddb50c70bbe9c082c6cd008585858585604051610126959493929190610ccb565b60405180910390a15b5050505050565b5b50565b60405180606001604052806000815260200160608152602001606081526020015090565b60405180604001604052806002905b606081526020019060019003908161016d57905050905661106e565b600082601f830112151561019d5760006000fd5b81356101b06101ab82610d6f565b610d41565b915081818352602084019350602081019050838560808402820111156101d65760006000fd5b60005b8381101561020757816101ec888261037a565b8452602084019350608083019250505b6001810190506101d9565b5050505092915050565b600082601f83011215156102255760006000fd5b600261023861023382610d98565b610d41565b9150818360005b83811015610270578135860161025588826103f3565b8452602084019350602083019250505b60018101905061023f565b5050505092915050565b600082601f830112151561028e5760006000fd5b81356102a161029c82610dbb565b610d41565b915081818352602084019350602081019050838560408402820111156102c75760006000fd5b60005b838110156102f857816102dd888261058b565b8452602084019350604083019250505b6001810190506102ca565b5050505092915050565b600082601f83011215156103165760006000fd5b813561032961032482610de4565b610d41565b9150818183526020840193506020810190508360005b83811015610370578135860161035588826105d8565b8452602084019350602083019250505b60018101905061033f565b5050505092915050565b600082601f830112151561038e5760006000fd5b60026103a161039c82610e0d565b610d41565b915081838560408402820111156103b85760006000fd5b60005b838110156103e957816103ce88826106fe565b8452602084019350604083019250505b6001810190506103bb565b5050505092915050565b600082601f83011215156104075760006000fd5b813561041a61041582610e30565b610d41565b915081818352602084019350602081019050838560408402820111156104405760006000fd5b60005b83811015610471578161045688826106fe565b8452602084019350604083019250505b600181019050610443565b5050505092915050565b600082601f830112151561048f5760006000fd5b81356104a261049d82610e59565b610d41565b915081818352602084019350602081019050838560208402820111156104c85760006000fd5b60005b838110156104f957816104de8882610760565b8452602084019350602083019250505b6001810190506104cb565b5050505092915050565b600082601f83011215156105175760006000fd5b813561052a61052582610e82565b610d41565b915081818352602084019350602081019050838560208402820111156105505760006000fd5b60005b8381101561058157816105668882610760565b8452602084019350602083019250505b600181019050610553565b5050505092915050565b60006040828403121561059e5760006000fd5b6105a86040610d41565b905060006105b88482850161074b565b60008301525060206105cc8482850161074b565b60208301525092915050565b6000606082840312156105eb5760006000fd5b6105f56060610d41565b9050600061060584828501610760565b600083015250602082013567ffffffffffffffff8111156106265760006000fd5b6106328482850161047b565b602083015250604082013567ffffffffffffffff8111156106535760006000fd5b61065f848285016103f3565b60408301525092915050565b60006060828403121561067e5760006000fd5b6106886060610d41565b9050600061069884828501610760565b600083015250602082013567ffffffffffffffff8111156106b95760006000fd5b6106c58482850161047b565b602083015250604082013567ffffffffffffffff8111156106e65760006000fd5b6106f2848285016103f3565b60408301525092915050565b6000604082840312156107115760006000fd5b61071b6040610d41565b9050600061072b84828501610760565b600083015250602061073f84828501610760565b60208301525092915050565b60008135905061075a8161103a565b92915050565b60008135905061076f81611054565b92915050565b6000602082840312156107885760006000fd5b600082013567ffffffffffffffff8111156107a35760006000fd5b6107af8482850161027a565b91505092915050565b6000600060006000600060a086880312156107d35760006000fd5b600086013567ffffffffffffffff8111156107ee5760006000fd5b6107fa8882890161066b565b955050602086013567ffffffffffffffff8111156108185760006000fd5b61082488828901610189565b945050604086013567ffffffffffffffff8111156108425760006000fd5b61084e88828901610211565b935050606086013567ffffffffffffffff81111561086c5760006000fd5b61087888828901610302565b925050608086013567ffffffffffffffff8111156108965760006000fd5b6108a288828901610503565b9150509295509295909350565b60006108bb8383610a6a565b60808301905092915050565b60006108d38383610ac2565b905092915050565b60006108e78383610c36565b905092915050565b60006108fb8383610c8d565b60408301905092915050565b60006109138383610cbc565b60208301905092915050565b600061092a82610f0f565b6109348185610fb7565b935061093f83610eab565b8060005b8381101561097157815161095788826108af565b975061096283610f5c565b9250505b600181019050610943565b5085935050505092915050565b600061098982610f1a565b6109938185610fc8565b9350836020820285016109a585610ebb565b8060005b858110156109e257848403895281516109c285826108c7565b94506109cd83610f69565b925060208a019950505b6001810190506109a9565b50829750879550505050505092915050565b60006109ff82610f25565b610a098185610fd3565b935083602082028501610a1b85610ec5565b8060005b85811015610a585784840389528151610a3885826108db565b9450610a4383610f76565b925060208a019950505b600181019050610a1f565b50829750879550505050505092915050565b610a7381610f30565b610a7d8184610fe4565b9250610a8882610ed5565b8060005b83811015610aba578151610aa087826108ef565b9650610aab83610f83565b9250505b600181019050610a8c565b505050505050565b6000610acd82610f3b565b610ad78185610fef565b9350610ae283610edf565b8060005b83811015610b14578151610afa88826108ef565b9750610b0583610f90565b9250505b600181019050610ae6565b5085935050505092915050565b6000610b2c82610f51565b610b368185611011565b9350610b4183610eff565b8060005b83811015610b73578151610b598882610907565b9750610b6483610faa565b9250505b600181019050610b45565b5085935050505092915050565b6000610b8b82610f46565b610b958185611000565b9350610ba083610eef565b8060005b83811015610bd2578151610bb88882610907565b9750610bc383610f9d565b9250505b600181019050610ba4565b5085935050505092915050565b6000606083016000830151610bf76000860182610cbc565b5060208301518482036020860152610c0f8282610b80565b91505060408301518482036040860152610c298282610ac2565b9150508091505092915050565b6000606083016000830151610c4e6000860182610cbc565b5060208301518482036020860152610c668282610b80565b91505060408301518482036040860152610c808282610ac2565b9150508091505092915050565b604082016000820151610ca36000850182610cbc565b506020820151610cb66020850182610cbc565b50505050565b610cc581611030565b82525050565b600060a0820190508181036000830152610ce58188610bdf565b90508181036020830152610cf9818761091f565b90508181036040830152610d0d818661097e565b90508181036060830152610d2181856109f4565b90508181036080830152610d358184610b21565b90509695505050505050565b6000604051905081810181811067ffffffffffffffff82111715610d655760006000fd5b8060405250919050565b600067ffffffffffffffff821115610d875760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610db05760006000fd5b602082029050919050565b600067ffffffffffffffff821115610dd35760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610dfc5760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e255760006000fd5b602082029050919050565b600067ffffffffffffffff821115610e485760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e715760006000fd5b602082029050602081019050919050565b600067ffffffffffffffff821115610e9a5760006000fd5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050919050565b6000819050602082019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600060029050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600061ffff82169050919050565b6000819050919050565b61104381611022565b811415156110515760006000fd5b50565b61105d81611030565b8114151561106b5760006000fd5b50565bfea365627a7a72315820d78c6ba7ee332581e6c4d9daa5fc07941841230f7ce49edf6e05b1b63853e8746c6578706572696d656e74616cf564736f6c634300050c0040`}, + []string{` +[{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"indexed":false,"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"indexed":false,"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"indexed":false,"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"indexed":false,"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"indexed":false,"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"TupleEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"}],"indexed":false,"internalType":"struct Tuple.P[]","name":"","type":"tuple[]"}],"name":"TupleEvent2","type":"event"},{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"func1","outputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"","type":"tuple[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S","name":"a","type":"tuple"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[2][]","name":"b","type":"tuple[2][]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[][2]","name":"c","type":"tuple[][2]"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256[]","name":"b","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"internalType":"struct Tuple.T[]","name":"c","type":"tuple[]"}],"internalType":"struct Tuple.S[]","name":"d","type":"tuple[]"},{"internalType":"uint256[]","name":"e","type":"uint256[]"}],"name":"func2","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"components":[{"internalType":"uint16","name":"x","type":"uint16"},{"internalType":"uint16","name":"y","type":"uint16"}],"internalType":"struct Tuple.Q[]","name":"","type":"tuple[]"}],"name":"func3","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}] + `}, + ` + "math/big" + "reflect" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + + ` + key, _ := crypto.GenerateKey() + auth := bind.NewKeyedTransactor(key) + + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + _, _, contract, err := DeployTuple(auth, sim) + if err != nil { + t.Fatalf("deploy contract failed %v", err) + } + sim.Commit() + + check := func(a, b interface{}, errMsg string) { + if !reflect.DeepEqual(a, b) { + t.Fatal(errMsg) + } + } + + a := TupleS{ + A: big.NewInt(1), + B: []*big.Int{big.NewInt(2), big.NewInt(3)}, + C: []TupleT{ + { + X: big.NewInt(4), + Y: big.NewInt(5), + }, + { + X: big.NewInt(6), + Y: big.NewInt(7), + }, + }, + } + + b := [][2]TupleT{ + { + { + X: big.NewInt(8), + Y: big.NewInt(9), + }, + { + X: big.NewInt(10), + Y: big.NewInt(11), + }, + }, + } + + c := [2][]TupleT{ + { + { + X: big.NewInt(12), + Y: big.NewInt(13), + }, + { + X: big.NewInt(14), + Y: big.NewInt(15), + }, + }, + { + { + X: big.NewInt(16), + Y: big.NewInt(17), + }, + }, + } + + d := []TupleS{a} + + e := []*big.Int{big.NewInt(18), big.NewInt(19)} + ret1, ret2, ret3, ret4, ret5, err := contract.Func1(nil, a, b, c, d, e) + if err != nil { + t.Fatalf("invoke contract failed, err %v", err) + } + check(ret1, a, "ret1 mismatch") + check(ret2, b, "ret2 mismatch") + check(ret3, c, "ret3 mismatch") + check(ret4, d, "ret4 mismatch") + check(ret5, e, "ret5 mismatch") + + _, err = contract.Func2(auth, a, b, c, d, e) + if err != nil { + t.Fatalf("invoke contract failed, err %v", err) + } + sim.Commit() + + iter, err := contract.FilterTupleEvent(nil) + if err != nil { + t.Fatalf("failed to create event filter, err %v", err) + } + defer iter.Close() + + iter.Next() + check(iter.Event.A, a, "field1 mismatch") + check(iter.Event.B, b, "field2 mismatch") + check(iter.Event.C, c, "field3 mismatch") + check(iter.Event.D, d, "field4 mismatch") + check(iter.Event.E, e, "field5 mismatch") + + err = contract.Func3(nil, nil) + if err != nil { + t.Fatalf("failed to call function which has no return, err %v", err) + } + `, + nil, + nil, + nil, + nil, + }, + { + "Overload", + ` + pragma solidity ^0.5.10; + + contract overload { + mapping(address => uint256) balances; + + event bar(uint256 i); + event bar(uint256 i, uint256 j); + + function foo(uint256 i) public { + emit bar(i); + } + function foo(uint256 i, uint256 j) public { + emit bar(i, j); + } + } + `, + []string{`608060405234801561001057600080fd5b50610153806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806304bc52f81461003b5780632fbebd3814610073575b600080fd5b6100716004803603604081101561005157600080fd5b8101908080359060200190929190803590602001909291905050506100a1565b005b61009f6004803603602081101561008957600080fd5b81019080803590602001909291905050506100e4565b005b7fae42e9514233792a47a1e4554624e83fe852228e1503f63cd383e8a431f4f46d8282604051808381526020018281526020019250505060405180910390a15050565b7f0423a1321222a0a8716c22b92fac42d85a45a612b696a461784d9fa537c81e5c816040518082815260200191505060405180910390a15056fea265627a7a72305820e22b049858b33291cbe67eeaece0c5f64333e439d27032ea8337d08b1de18fe864736f6c634300050a0032`}, + []string{`[{"constant":false,"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"i","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"}],"name":"bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"},{"indexed":false,"name":"j","type":"uint256"}],"name":"bar","type":"event"}]`}, + ` + "math/big" + "time" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Initialize test accounts + key, _ := crypto.GenerateKey() + auth := bind.NewKeyedTransactor(key) + + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + // deploy the test contract + _, _, contract, err := DeployOverload(auth, sim) + if err != nil { + t.Fatalf("Failed to deploy contract: %v", err) + } + // Finish deploy. + sim.Commit() + + resCh, stopCh := make(chan uint64), make(chan struct{}) + + go func() { + barSink := make(chan *OverloadBar) + sub, _ := contract.WatchBar(nil, barSink) + defer sub.Unsubscribe() + + bar0Sink := make(chan *OverloadBar0) + sub0, _ := contract.WatchBar0(nil, bar0Sink) + defer sub0.Unsubscribe() + + for { + select { + case ev := <-barSink: + resCh <- ev.I.Uint64() + case ev := <-bar0Sink: + resCh <- ev.I.Uint64() + ev.J.Uint64() + case <-stopCh: + return + } + } + }() + contract.Foo(auth, big.NewInt(1), big.NewInt(2)) + sim.Commit() + select { + case n := <-resCh: + if n != 3 { + t.Fatalf("Invalid bar0 event") + } + case <-time.NewTimer(3 * time.Second).C: + t.Fatalf("Wait bar0 event timeout") + } + + contract.Foo0(auth, big.NewInt(1)) + sim.Commit() + select { + case n := <-resCh: + if n != 1 { + t.Fatalf("Invalid bar event") + } + case <-time.NewTimer(3 * time.Second).C: + t.Fatalf("Wait bar event timeout") + } + close(stopCh) + `, + nil, + nil, + nil, + nil, + }, { "IdentifierCollision", ` @@ -1243,6 +1486,62 @@ var bindTests = []struct { nil, []string{"ContractOne", "ContractTwo", "ExternalLib"}, }, + // Test the existence of the free retrieval calls + { + `PureAndView`, + `pragma solidity >=0.6.0; + contract PureAndView { + function PureFunc() public pure returns (uint) { + return 42; + } + function ViewFunc() public view returns (uint) { + return block.number; + } + } + `, + []string{`608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806376b5686a146037578063bb38c66c146053575b600080fd5b603d606f565b6040518082815260200191505060405180910390f35b60596077565b6040518082815260200191505060405180910390f35b600043905090565b6000602a90509056fea2646970667358221220d158c2ab7fdfce366a7998ec79ab84edd43b9815630bbaede2c760ea77f29f7f64736f6c63430006000033`}, + []string{`[{"inputs": [],"name": "PureFunc","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "ViewFunc","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"}]`}, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Generate a new random account and a funded simulator + key, _ := crypto.GenerateKey() + auth := bind.NewKeyedTransactor(key) + + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + // Deploy a tester contract and execute a structured call on it + _, _, pav, err := DeployPureAndView(auth, sim) + if err != nil { + t.Fatalf("Failed to deploy PureAndView contract: %v", err) + } + sim.Commit() + + // This test the existence of the free retreiver call for view and pure functions + if num, err := pav.PureFunc(nil); err != nil { + t.Fatalf("Failed to call anonymous field retriever: %v", err) + } else if num.Cmp(big.NewInt(42)) != 0 { + t.Fatalf("Retrieved value mismatch: have %v, want %v", num, 42) + } + if num, err := pav.ViewFunc(nil); err != nil { + t.Fatalf("Failed to call anonymous field retriever: %v", err) + } else if num.Cmp(big.NewInt(1)) != 0 { + t.Fatalf("Retrieved value mismatch: have %v, want %v", num, 1) + } + `, + nil, + nil, + nil, + nil, + }, // Test fallback separation introduced in v0.6.0 { `NewFallbacks`, diff --git a/params/config.go b/params/config.go index f6d795560d..0a0a63ea5c 100644 --- a/params/config.go +++ b/params/config.go @@ -336,7 +336,7 @@ var ( EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: nil, + ConstantinopleBlock: big.NewInt(0), Ethash: new(EthashConfig), Clique: nil, XDPoS: &XDPoSConfig{ From 593fe5351916f7ffaa630cc467e72a029f5c3353 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 118/280] internal/ethapi: return revert reason for eth_call (#21083) --- accounts/abi/bind/backends/simulated.go | 53 ++++- accounts/abi/bind/backends/simulated_test.go | 221 +++++++++++++------ accounts/abi/bind/bind_test.go | 4 +- console/bridge.go | 31 ++- internal/ethapi/api.go | 30 +-- 5 files changed, 224 insertions(+), 115 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fd7885b553..c7eb412ba1 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -34,6 +34,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" @@ -432,6 +433,36 @@ func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Ad return b.pendingState.GetCode(contract), nil } +func newRevertError(result *core.ExecutionResult) *revertError { + reason, errUnpack := abi.UnpackRevert(result.Revert()) + err := errors.New("execution reverted") + if errUnpack == nil { + err = fmt.Errorf("execution reverted: %v", reason) + } + return &revertError{ + error: err, + reason: hexutil.Encode(result.Revert()), + } +} + +// revertError is an API error that encompassas an EVM revertal with JSON error +// code and a binary data blob. +type revertError struct { + error + reason string // revert reason hex encoded +} + +// ErrorCode returns the JSON error code for a revertal. +// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal +func (e *revertError) ErrorCode() int { + return 3 +} + +// ErrorData returns the hex encoded revert reason. +func (e *revertError) ErrorData() interface{} { + return e.reason +} + // CallContract executes a contract call. func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { b.mu.Lock() @@ -448,7 +479,11 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM if err != nil { return nil, err } - return res.Return(), nil + // If the result contains a revert reason, try to unpack and return it. + if len(res.Revert()) > 0 { + return nil, newRevertError(res) + } + return res.Return(), res.Err } // PendingCallContract executes a contract call on the pending state. @@ -461,7 +496,11 @@ func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereu if err != nil { return nil, err } - return res.Return(), nil + // If the result contains a revert reason, try to unpack and return it. + if len(res.Revert()) > 0 { + return nil, newRevertError(res) + } + return res.Return(), res.Err } // PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving @@ -548,16 +587,10 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs } if failed { if result != nil && result.Err != vm.ErrOutOfGas { - errMsg := fmt.Sprintf("always failing transaction (%v)", result.Err) if len(result.Revert()) > 0 { - ret, err := abi.UnpackRevert(result.Revert()) - if err != nil { - errMsg += fmt.Sprintf(" (%#x)", result.Revert()) - } else { - errMsg += fmt.Sprintf(" (%s)", ret) - } + return 0, newRevertError(result) } - return 0, errors.New(errMsg) + return 0, result.Err } // Otherwise, the specified gas cap is too low return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 99aebcb617..c2116c30e8 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -21,6 +21,7 @@ import ( "context" "errors" "math/big" + "reflect" "strings" "testing" "time" @@ -106,14 +107,18 @@ const deployedCode = `60806040526004361061003b576000357c010000000000000000000000 // expected return value contains "hello world" var expectedReturn = []byte{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, 32, 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, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +func simTestBackend(testAddr common.Address) *SimulatedBackend { + return NewSimulatedBackend( + core.GenesisAlloc{ + testAddr: {Balance: big.NewInt(10000000000)}, + }, 10000000, + ) +} + func TestNewSimulatedBackend(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(10000000000) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: expectedBal}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() if sim.config != params.AllEthashProtocolChanges { @@ -152,11 +157,7 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { func TestSimulatedBackend_BalanceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(10000000000) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: expectedBal}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -229,11 +230,7 @@ func TestSimulatedBackend_BlockByNumber(t *testing.T) { func TestSimulatedBackend_NonceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -283,11 +280,7 @@ func TestSimulatedBackend_NonceAt(t *testing.T) { func TestSimulatedBackend_SendTransaction(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -394,7 +387,6 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { }, }, }) - defer sim.Close() parsed, _ := abi.JSON(strings.NewReader(contractAbi)) @@ -406,6 +398,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { message ethereum.CallMsg expect uint64 expectError error + expectData interface{} }{ {"plain transfer(valid)", ethereum.CallMsg{ From: addr, @@ -414,7 +407,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: big.NewInt(1), Data: nil, - }, params.TxGas, nil}, + }, params.TxGas, nil, nil}, {"plain transfer(invalid)", ethereum.CallMsg{ From: addr, @@ -423,7 +416,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: big.NewInt(1), Data: nil, - }, 0, errors.New("always failing transaction (execution reverted)")}, + }, 0, errors.New("execution reverted"), nil}, {"Revert", ethereum.CallMsg{ From: addr, @@ -432,7 +425,8 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: nil, Data: common.Hex2Bytes("d8b98391"), - }, 0, errors.New("always failing transaction (execution reverted) (revert reason)")}, + }, 0, errors.New("execution reverted: revert reason"), + "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000"}, {"PureRevert", ethereum.CallMsg{ From: addr, @@ -441,7 +435,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: nil, Data: common.Hex2Bytes("aa8b1d30"), - }, 0, errors.New("always failing transaction (execution reverted)")}, + }, 0, errors.New("execution reverted"), nil}, {"OOG", ethereum.CallMsg{ From: addr, @@ -450,7 +444,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: nil, Data: common.Hex2Bytes("50f6fe34"), - }, 0, errors.New("gas required exceeds allowance (100000)")}, + }, 0, errors.New("gas required exceeds allowance (100000)"), nil}, {"Assert", ethereum.CallMsg{ From: addr, @@ -459,7 +453,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: nil, Data: common.Hex2Bytes("b9b046f9"), - }, 0, errors.New("always failing transaction (invalid opcode: INVALID)")}, + }, 0, errors.New("invalid opcode: INVALID"), nil}, {"Valid", ethereum.CallMsg{ From: addr, @@ -468,7 +462,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { GasPrice: big.NewInt(0), Value: nil, Data: common.Hex2Bytes("e09fface"), - }, 21483, nil}, + }, 21483, nil, nil}, } for _, c := range cases { got, err := sim.EstimateGas(context.Background(), c.message) @@ -479,6 +473,13 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { if c.expectError.Error() != err.Error() { t.Fatalf("Expect error, want %v, got %v", c.expectError, err) } + if c.expectData != nil { + if err, ok := err.(*revertError); !ok { + t.Fatalf("Expect revert error, got %T", err) + } else if !reflect.DeepEqual(err.ErrorData(), c.expectData) { + t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.ErrorData()) + } + } continue } if got != c.expect { @@ -490,11 +491,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { func TestSimulatedBackend_HeaderByHash(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -515,11 +512,7 @@ func TestSimulatedBackend_HeaderByHash(t *testing.T) { func TestSimulatedBackend_HeaderByNumber(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -566,11 +559,7 @@ func TestSimulatedBackend_HeaderByNumber(t *testing.T) { func TestSimulatedBackend_TransactionCount(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() currentBlock, err := sim.BlockByNumber(bgCtx, nil) @@ -620,11 +609,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) { func TestSimulatedBackend_TransactionInBlock(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -687,11 +672,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) { func TestSimulatedBackend_PendingNonceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -803,12 +784,7 @@ func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { func TestSimulatedBackend_PendingCodeAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, - 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() code, err := sim.CodeAt(bgCtx, testAddr, nil) @@ -844,12 +820,7 @@ func TestSimulatedBackend_PendingCodeAt(t *testing.T) { func TestSimulatedBackend_CodeAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, - 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() code, err := sim.CodeAt(bgCtx, testAddr, nil) @@ -889,12 +860,7 @@ func TestSimulatedBackend_CodeAt(t *testing.T) { // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, - 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -910,7 +876,7 @@ func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { input, err := parsed.Pack("receive", []byte("X")) if err != nil { - t.Errorf("could pack receive function on contract: %v", err) + t.Errorf("could not pack receive function on contract: %v", err) } // make sure you can call the contract in pending state @@ -950,3 +916,114 @@ func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) } } + +// This test is based on the following contract: +/* +contract Reverter { + function revertString() public pure{ + require(false, "some error"); + } + function revertNoString() public pure { + require(false, ""); + } + function revertASM() public pure { + assembly { + revert(0x0, 0x0) + } + } + function noRevert() public pure { + assembly { + // Assembles something that looks like require(false, "some error") but is not reverted + mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) + mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020) + mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a) + mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000) + return(0x0, 0x64) + } + } +}*/ +func TestSimulatedBackend_CallContractRevert(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + // sim := simTestBackend(testAddr) + sim := NewXDCSimulatedBackend(core.GenesisAlloc{testAddr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + bgCtx := context.Background() + + reverterABI := `[{"inputs": [],"name": "noRevert","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertASM","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertNoString","outputs": [],"stateMutability": "pure","type": "function"},{"inputs": [],"name": "revertString","outputs": [],"stateMutability": "pure","type": "function"}]` + reverterBin := "608060405234801561001057600080fd5b506101d3806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80634b409e01146100515780639b340e361461005b5780639bd6103714610065578063b7246fc11461006f575b600080fd5b610059610079565b005b6100636100ca565b005b61006d6100cf565b005b610077610145565b005b60006100c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526000815260200160200191505060405180910390fd5b565b600080fd5b6000610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f736f6d65206572726f720000000000000000000000000000000000000000000081525060200191505060405180910390fd5b565b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f3fea2646970667358221220cdd8af0609ec4996b7360c7c780bad5c735740c64b1fffc3445aa12d37f07cb164736f6c63430006070033" + + parsed, err := abi.JSON(strings.NewReader(reverterABI)) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + contractAuth := bind.NewKeyedTransactor(testKey) + addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim) + if err != nil { + t.Errorf("could not deploy contract: %v", err) + } + + inputs := make(map[string]interface{}, 3) + inputs["revertASM"] = nil + inputs["revertNoString"] = "" + inputs["revertString"] = "some error" + + call := make([]func([]byte) ([]byte, error), 2) + call[0] = func(input []byte) ([]byte, error) { + return sim.PendingCallContract(bgCtx, ethereum.CallMsg{ + From: testAddr, + To: &addr, + Data: input, + }) + } + call[1] = func(input []byte) ([]byte, error) { + return sim.CallContract(bgCtx, ethereum.CallMsg{ + From: testAddr, + To: &addr, + Data: input, + }, nil) + } + + // Run pending calls then commit + for _, cl := range call { + for key, val := range inputs { + input, err := parsed.Pack(key) + if err != nil { + t.Errorf("could not pack %v function on contract: %v", key, err) + } + + res, err := cl(input) + if err == nil { + t.Errorf("call to %v was not reverted", key) + } + if res != nil { + t.Errorf("result from %v was not nil: %v", key, res) + } + if val != nil { + rerr, ok := err.(*revertError) + if !ok { + t.Errorf("expect revert error") + } + if rerr.Error() != "execution reverted: "+val.(string) { + t.Errorf("error was malformed: got %v want %v", rerr.Error(), val) + } + } else { + // revert(0x0,0x0) + if err.Error() != "execution reverted" { + t.Errorf("error was malformed: got %v want %v", err, "execution reverted") + } + } + } + input, err := parsed.Pack("noRevert") + if err != nil { + t.Errorf("could not pack noRevert function on contract: %v", err) + } + res, err := cl(input) + if err != nil { + t.Error("call to noRevert was reverted") + } + if res == nil { + t.Errorf("result from noRevert was nil") + } + sim.Commit() + } +} diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 243dce37ef..fd6af530d7 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1466,7 +1466,7 @@ var bindTests = []struct { F2: [32]byte{0x01, 0x02, 0x03}, }) if err != nil { - t.Fatal("Failed to invoke function") + t.Fatal("Failed to invoke function, err:", err) } _, _, c2, err := DeployContractTwo(transactOpts, sim) if err != nil { @@ -1478,7 +1478,7 @@ var bindTests = []struct { F2: [32]byte{0x01, 0x02, 0x03}, }) if err != nil { - t.Fatal("Failed to invoke function") + t.Fatal("Failed to invoke function, err:", err) } `, nil, diff --git a/console/bridge.go b/console/bridge.go index 3f7982b5f6..43556b9488 100644 --- a/console/bridge.go +++ b/console/bridge.go @@ -351,9 +351,7 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) { resp.Set("id", req.ID) var result json.RawMessage - err = b.client.Call(&result, req.Method, req.Params...) - switch err := err.(type) { - case nil: + if err = b.client.Call(&result, req.Method, req.Params...); err == nil { if result == nil { // Special case null because it is decoded as an empty // raw message for some reason. @@ -366,19 +364,24 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) { } resultVal, err := parse(goja.Null(), call.VM.ToValue(string(result))) if err != nil { - setError(resp, -32603, err.Error()) + setError(resp, -32603, err.Error(), nil) } else { resp.Set("result", resultVal) } } - case rpc.Error: - setError(resp, err.ErrorCode(), err.Error()) - default: - setError(resp, -32603, err.Error()) + } else { + code := -32603 + var data interface{} + if err, ok := err.(rpc.Error); ok { + code = err.ErrorCode() + } + if err, ok := err.(rpc.DataError); ok { + data = err.ErrorData() + } + setError(resp, code, err.Error(), data) } resps = append(resps, resp) } - // Return the responses either to the callback (if supplied) // or directly as the return value. var result goja.Value @@ -394,8 +397,14 @@ func (b *bridge) Send(call jsre.Call) (goja.Value, error) { return result, nil } -func setError(resp *goja.Object, code int, msg string) { - resp.Set("error", map[string]interface{}{"code": code, "message": msg}) +func setError(resp *goja.Object, code int, msg string, data interface{}) { + err := make(map[string]interface{}) + err["code"] = code + err["message"] = msg + if data != nil { + err["data"] = data + } + resp.Set("error", err) } // isNumber returns true if input value is a JS number. diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 99221c9745..dd15b4fa5d 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1382,19 +1382,19 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash return result, err } -func newRevertError(res []byte) *revertError { - reason, errUnpack := abi.UnpackRevert(res) +func newRevertError(result *core.ExecutionResult) *revertError { + reason, errUnpack := abi.UnpackRevert(result.Revert()) err := errors.New("execution reverted") if errUnpack == nil { err = fmt.Errorf("execution reverted: %v", reason) } return &revertError{ error: err, - reason: hexutil.Encode(res), + reason: hexutil.Encode(result.Revert()), } } -// revertError is an API error that encompasses an EVM revertal with JSON error +// revertError is an API error that encompassas an EVM revertal with JSON error // code and a binary data blob. type revertError struct { error @@ -1428,10 +1428,10 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, bl return nil, err } // If the result contains a revert reason, try to unpack and return it. - if result.Failed() { - return nil, newRevertError(result.Return()) + if len(result.Revert()) > 0 { + return nil, newRevertError(result) } - return result.Return(), nil + return result.Return(), result.Err } type estimateGasError struct { @@ -1546,23 +1546,13 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if failed { if result != nil && result.Err != vm.ErrOutOfGas { - var revert string if len(result.Revert()) > 0 { - ret, err := abi.UnpackRevert(result.Revert()) - if err != nil { - revert = hexutil.Encode(result.Revert()) - } else { - revert = ret - } - } - return 0, estimateGasError{ - error: "always failing transaction", - vmerr: result.Err, - revert: revert, + return 0, newRevertError(result) } + return 0, result.Err } // Otherwise, the specified gas cap is too low - return 0, estimateGasError{error: fmt.Sprintf("gas required exceeds allowance (%d)", cap)} + return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } } return hexutil.Uint64(hi), nil From 9c5dff2554af073063d97636bf0a571c9c443640 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 119/280] accounts/keystore: fix typo in error message (#21200) --- accounts/keystore/keystore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 09dd02cc98..bc8b8d980a 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -46,7 +46,7 @@ var ( // ErrAccountAlreadyExists is returned if an account attempted to import is // already present in the keystore. - ErrAccountAlreadyExists = errors.New("account alreaady exists") + ErrAccountAlreadyExists = errors.New("account already exists") ) // KeyStoreType is the reflect type of a keystore backend. From 25d42fef2ccb8e4eaae460f8dc4172c303086009 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 120/280] =?UTF-8?q?accounts/abi:=C2=A0make=20GetType=20pub?= =?UTF-8?q?lic=20again=20(#21157)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- accounts/abi/error.go | 14 +++++++------- accounts/abi/type.go | 9 +++++---- accounts/abi/unpack.go | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 8d61d574c5..b63a215ad9 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -39,11 +39,11 @@ func formatSliceString(kind reflect.Kind, sliceSize int) string { // type in t. func sliceTypeCheck(t Type, val reflect.Value) error { if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { - return typeErr(formatSliceString(t.getType().Kind(), t.Size), val.Type()) + return typeErr(formatSliceString(t.GetType().Kind(), t.Size), val.Type()) } if t.T == ArrayTy && val.Len() != t.Size { - return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) + return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) } if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { @@ -52,8 +52,8 @@ func sliceTypeCheck(t Type, val reflect.Value) error { } } - if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.getType().Kind() { - return typeErr(formatSliceString(t.Elem.getType().Kind(), t.Size), val.Type()) + if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.GetType().Kind() { + return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), val.Type()) } return nil } @@ -66,10 +66,10 @@ func typeCheck(t Type, value reflect.Value) error { } // Check base type validity. Element types will be checked later on. - if t.getType().Kind() != value.Kind() { - return typeErr(t.getType().Kind(), value.Kind()) + if t.GetType().Kind() != value.Kind() { + return typeErr(t.GetType().Kind(), value.Kind()) } else if t.T == FixedBytesTy && t.Size != value.Len() { - return typeErr(t.getType(), value.Type()) + return typeErr(t.GetType(), value.Type()) } else { return nil } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 999d57e2e4..292ef6fa5c 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -175,7 +175,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty overloadedNames[fieldName] = fieldName fields = append(fields, reflect.StructField{ Name: fieldName, // reflect.StructOf will panic for any exported field. - Type: cType.getType(), + Type: cType.GetType(), Tag: reflect.StructTag("json:\"" + c.Name + "\""), }) elems = append(elems, &cType) @@ -213,7 +213,8 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty return } -func (t Type) getType() reflect.Type { +// GetType returns the reflection type of the ABI type. +func (t Type) GetType() reflect.Type { switch t.T { case IntTy: return reflectIntType(false, t.Size) @@ -224,9 +225,9 @@ func (t Type) getType() reflect.Type { case StringTy: return reflect.TypeOf("") case SliceTy: - return reflect.SliceOf(t.Elem.getType()) + return reflect.SliceOf(t.Elem.GetType()) case ArrayTy: - return reflect.ArrayOf(t.Size, t.Elem.getType()) + return reflect.ArrayOf(t.Size, t.Elem.GetType()) case TupleTy: return t.TupleType case AddressTy: diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 278301776f..15da1827ad 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -111,7 +111,7 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) { return nil, errors.New("abi: invalid type in call to make fixed byte array") } // convert - array := reflect.New(t.getType()).Elem() + array := reflect.New(t.GetType()).Elem() reflect.Copy(array, reflect.ValueOf(word[0:t.Size])) return array.Interface(), nil @@ -132,10 +132,10 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) if t.T == SliceTy { // declare our slice - refSlice = reflect.MakeSlice(t.getType(), size, size) + refSlice = reflect.MakeSlice(t.GetType(), size, size) } else if t.T == ArrayTy { // declare our array - refSlice = reflect.New(t.getType()).Elem() + refSlice = reflect.New(t.GetType()).Elem() } else { return nil, errors.New("abi: invalid type in array/slice unpacking stage") } @@ -159,7 +159,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) } func forTupleUnpack(t Type, output []byte) (interface{}, error) { - retval := reflect.New(t.getType()).Elem() + retval := reflect.New(t.GetType()).Elem() virtualArgs := 0 for index, elem := range t.TupleElems { marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output) From 089242bb39acd952e8380e59bc69b31a519ba8d6 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 121/280] accounts/abi/bind/backends: Disallow AdjustTime for non-empty blocks (#21334) --- accounts/abi/bind/backends/simulated.go | 9 +++-- accounts/abi/bind/backends/simulated_test.go | 41 +++++++++++++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index c7eb412ba1..57d2aff10a 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -794,13 +794,16 @@ func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *type } // AdjustTime adds a time shift to the simulated clock. +// It can only be called on empty blocks. func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { b.mu.Lock() defer b.mu.Unlock() + + if len(b.pendingBlock.Transactions()) != 0 { + return errors.New("could not adjust time on non-empty block") + } + blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { - for _, tx := range b.pendingBlock.Transactions() { - block.AddTx(tx) - } block.OffsetTime(int64(adjustment.Seconds())) }) statedb, _ := b.blockchain.State() diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index c2116c30e8..ca5993a57d 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -143,8 +143,7 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { defer sim.Close() prevTime := sim.pendingBlock.Time().Uint64() - err := sim.AdjustTime(time.Second) - if err != nil { + if err := sim.AdjustTime(time.Second); err != nil { t.Error(err) } newTime := sim.pendingBlock.Time().Uint64() @@ -154,6 +153,44 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { } } +func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + // Create tx and send + tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + sim.SendTransaction(context.Background(), signedTx) + // AdjustTime should fail on non-empty block + if err := sim.AdjustTime(time.Second); err == nil { + t.Error("Expected adjust time to error on non-empty block") + } + sim.Commit() + + prevTime := sim.pendingBlock.Time().Uint64() + if err := sim.AdjustTime(time.Minute); err != nil { + t.Error(err) + } + newTime := sim.pendingBlock.Time().Uint64() + if newTime-prevTime != uint64(time.Minute.Seconds()) { + t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) + } + // Put a transaction after adjusting time + tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + sim.SendTransaction(context.Background(), signedTx2) + sim.Commit() + newTime = sim.pendingBlock.Time().Uint64() + if newTime-prevTime >= uint64(time.Minute.Seconds()) { + t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime) + } +} + func TestSimulatedBackend_BalanceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(10000000000) From f4feaebb401d4fb464bccc676a9f488196c75c7f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 122/280] accounts/abi: fix a bug in getTypeSize method (#21501) * accounts/abi: fix a bug in getTypeSize method e.g. for "Tuple[2]" type, the element of the array is a tuple type and the size of the tuple may not be 32. * accounts/abi: add unit test of getTypeSize method --- accounts/abi/type.go | 2 +- accounts/abi/type_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 292ef6fa5c..5b6d580e4b 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -385,7 +385,7 @@ func isDynamicType(t Type) bool { func getTypeSize(t Type) int { if t.T == ArrayTy && !isDynamicType(*t.Elem) { // Recursively calculate type size if it is a nested array - if t.Elem.T == ArrayTy { + if t.Elem.T == ArrayTy || t.Elem.T == TupleTy { return t.Size * getTypeSize(*t.Elem) } return t.Size * 32 diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index df76646346..504e938ec1 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -330,3 +330,39 @@ func TestInternalType(t *testing.T) { t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind))) } } + +func TestGetTypeSize(t *testing.T) { + var testCases = []struct { + typ string + components []ArgumentMarshaling + typSize int + }{ + // simple array + {"uint256[2]", nil, 32 * 2}, + {"address[3]", nil, 32 * 3}, + {"bytes32[4]", nil, 32 * 4}, + // array array + {"uint256[2][3][4]", nil, 32 * (2 * 3 * 4)}, + // array tuple + {"tuple[2]", []ArgumentMarshaling{{Name: "x", Type: "bytes32"}, {Name: "y", Type: "bytes32"}}, (32 * 2) * 2}, + // simple tuple + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "uint256"}, {Name: "y", Type: "uint256"}}, 32 * 2}, + // tuple array + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}}, 32 * 2}, + // tuple tuple + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32"}}}}, 32}, + {"tuple", []ArgumentMarshaling{{Name: "x", Type: "tuple", Components: []ArgumentMarshaling{{Name: "x", Type: "bytes32[2]"}, {Name: "y", Type: "uint256"}}}}, 32 * (2 + 1)}, + } + + for i, data := range testCases { + typ, err := NewType(data.typ, "", data.components) + if err != nil { + t.Errorf("type %q: failed to parse type string: %v", data.typ, err) + } + + result := getTypeSize(typ) + if result != data.typSize { + t.Errorf("case %d type %q: get type size error: actual: %d expected: %d", i, data.typ, result, data.typSize) + } + } +} From c9643e9c901ad8a719dcce7e3031473e53abafd0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 123/280] accounts/abi/bind/backends: clean doc errors (#21514) --- accounts/abi/bind/backends/simulated.go | 56 ++++++++++---------- accounts/abi/bind/backends/simulated_test.go | 4 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 57d2aff10a..6641f4ed64 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -53,7 +53,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/rpc" ) -// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend. +// This nil assignment ensures at compile time that SimulatedBackend implements bind.ContractBackend. var _ bind.ContractBackend = (*SimulatedBackend)(nil) var ( @@ -63,7 +63,7 @@ var ( ) // SimulatedBackend implements bind.ContractBackend, simulating a blockchain in -// the background. Its main purpose is to allow easily testing contract bindings. +// the background. Its main purpose is to allow for easy testing of contract bindings. // Simulated backend implements the following interfaces: // ChainReader, ChainStateReader, ContractBackend, ContractCaller, ContractFilterer, ContractTransactor, // DeployBackend, GasEstimator, GasPricer, LogFilterer, PendingContractCaller, TransactionReader, and TransactionSender @@ -198,10 +198,10 @@ func (b *SimulatedBackend) Rollback() { func (b *SimulatedBackend) rollback() { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(int, *core.BlockGen) {}) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database()) } // stateByBlockNumber retrieves a state by a given blocknumber. @@ -221,12 +221,12 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - return statedb.GetCode(contract), nil + return stateDB.GetCode(contract), nil } // BalanceAt returns the wei balance of a certain account in the blockchain. @@ -234,12 +234,12 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - return statedb.GetBalance(contract), nil + return stateDB.GetBalance(contract), nil } // NonceAt returns the nonce of a certain account in the blockchain. @@ -247,12 +247,12 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return 0, err } - return statedb.GetNonce(contract), nil + return stateDB.GetNonce(contract), nil } // StorageAt returns the value of key in the storage of an account in the blockchain. @@ -260,12 +260,12 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres b.mu.Lock() defer b.mu.Unlock() - statedb, err := b.stateByBlockNumber(ctx, blockNumber) + stateDB, err := b.stateByBlockNumber(ctx, blockNumber) if err != nil { return nil, err } - val := statedb.GetState(contract, key) + val := stateDB.GetState(contract, key) return val[:], nil } @@ -277,8 +277,8 @@ func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { return errBlockNumberUnsupported } - statedb, _ := b.blockchain.State() - statedb.ForEachStorage(contract, f) + stateDB, _ := b.blockchain.State() + stateDB.ForEachStorage(contract, f) return nil } @@ -310,7 +310,7 @@ func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common. return nil, false, ethereum.ErrNotFound } -// BlockByHash retrieves a block based on the block hash +// BlockByHash retrieves a block based on the block hash. func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { b.mu.Lock() defer b.mu.Unlock() @@ -381,7 +381,7 @@ func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) ( return b.blockchain.GetHeaderByNumber(uint64(block.Int64())), nil } -// TransactionCount returns the number of transactions in a given block +// TransactionCount returns the number of transactions in a given block. func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { b.mu.Lock() defer b.mu.Unlock() @@ -398,7 +398,7 @@ func (b *SimulatedBackend) TransactionCount(ctx context.Context, blockHash commo return uint(block.Transactions().Len()), nil } -// TransactionInBlock returns the transaction for a specific block at a specific index +// TransactionInBlock returns the transaction for a specific block at a specific index. func (b *SimulatedBackend) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { b.mu.Lock() defer b.mu.Unlock() @@ -445,14 +445,14 @@ func newRevertError(result *core.ExecutionResult) *revertError { } } -// revertError is an API error that encompassas an EVM revertal with JSON error +// revertError is an API error that encompasses an EVM revert with JSON error // code and a binary data blob. type revertError struct { error reason string // revert reason hex encoded } -// ErrorCode returns the JSON error code for a revertal. +// ErrorCode returns the JSON error code for a revert. // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal func (e *revertError) ErrorCode() int { return 3 @@ -601,7 +601,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs // callContract implements common code between normal and pending contract calls. // state is modified during execution, make sure to copy it if necessary. -func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) { +func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, stateDB *state.StateDB) (*core.ExecutionResult, error) { // Gas prices post 1559 need to be initialized if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) { return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") @@ -644,11 +644,11 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM call.Value = new(big.Int) } // Set infinite balance to the fake caller account. - from := statedb.GetOrNewStateObject(call.From) + from := stateDB.GetOrNewStateObject(call.From) from.SetBalance(math.MaxBig256) // Execute the call. msg := callMsg{call} - feeCapacity := state.GetTRC21FeeCapacityFromState(statedb) + feeCapacity := state.GetTRC21FeeCapacityFromState(stateDB) if msg.To() != nil { if value, ok := feeCapacity[*msg.To()]; ok { msg.CallMsg.BalanceTokenFee = value @@ -659,7 +659,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM evmContext := core.NewEVMBlockContext(block.Header(), b.blockchain, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(evmContext, txContext, statedb, nil, b.config, vm.Config{NoBaseFee: true}) + vmenv := vm.NewEVM(evmContext, txContext, stateDB, nil, b.config, vm.Config{NoBaseFee: true}) gaspool := new(core.GasPool).AddGas(gomath.MaxUint64) owner := common.Address{} return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) @@ -690,10 +690,10 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa } block.AddTxWithChain(b.blockchain, tx) }) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database()) b.pendingReceipts = receipts[0] return nil } @@ -766,7 +766,7 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethere }), nil } -// SubscribeNewHead returns an event subscription for a new header +// SubscribeNewHead returns an event subscription for a new header. func (b *SimulatedBackend) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { // subscribe to a new head sink := make(chan *types.Header) @@ -806,10 +806,10 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { block.OffsetTime(int64(adjustment.Seconds())) }) - statedb, _ := b.blockchain.State() + stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] - b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database()) + b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database()) return nil } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index ca5993a57d..69a96b04c3 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -129,8 +129,8 @@ func TestNewSimulatedBackend(t *testing.T) { t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) } - statedb, _ := sim.blockchain.State() - bal := statedb.GetBalance(testAddr) + stateDB, _ := sim.blockchain.State() + bal := stateDB.GetBalance(testAddr) if bal.Cmp(expectedBal) != 0 { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) } From 321bcff620aed9856d6fce6a03a55e877cee48c8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 124/280] accounts/usbwallet, signer/core: show accounts from ledger legacy derivation paths (#21517) * accounts/usbwallet, signer/core: un-hide accounts from ledger legacy derivation paths * Update accounts/usbwallet/wallet.go * Update signer/core/api.go * Update signer/core/api.go --- accounts/usbwallet/wallet.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 659d164cca..7cb512e21c 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -368,18 +368,22 @@ func (w *wallet) selfDerive() { w.log.Warn("USB wallet nonce retrieval failed", "err", err) break } - // If the next account is empty, stop self-derivation, but add for the last base path + // We've just self-derived a new account, start tracking it locally + // unless the account was empty. + path := make(accounts.DerivationPath, len(nextPaths[i])) + copy(path[:], nextPaths[i][:]) if balance.Sign() == 0 && nonce == 0 { empty = true + // If it indeed was empty, make a log output for it anyway. In the case + // of legacy-ledger, the first account on the legacy-path will + // be shown to the user, even if we don't actively track it if i < len(nextAddrs)-1 { + w.log.Info("Skipping trakcking first account on legacy path, use personal.deriveAccount(,, false) to track", + "path", path, "address", nextAddrs[i]) break } } - // We've just self-derived a new account, start tracking it locally - path := make(accounts.DerivationPath, len(nextPaths[i])) - copy(path[:], nextPaths[i][:]) paths = append(paths, path) - account := accounts.Account{ Address: nextAddrs[i], URL: accounts.URL{Scheme: w.url.Scheme, Path: fmt.Sprintf("%s/%s", w.url.Path, path)}, From 7c3c7035596b716696def8280564933ec70ea3d8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 125/280] tests/fuzzers/abi: add fuzzer for fuzzing package accounts/abi (#21217) * tests/fuzzers/abi: added abi fuzzer * accounts/abi: fixed issues found by fuzzing * tests/fuzzers/abi: update fuzzers, added repro test * tests/fuzzers/abi: renamed abi_fuzzer to abifuzzer * tests/fuzzers/abi: updated abi fuzzer * tests/fuzzers/abi: updated abi fuzzer * accounts/abi: minor style fix * go.mod: added go-fuzz dependency * tests/fuzzers/abi: updated abi fuzzer * tests/fuzzers/abi: make linter happy * tests/fuzzers/abi: make linter happy * tests/fuzzers/abi: comment out false positives --- accounts/abi/abi_test.go | 4 +- accounts/abi/error.go | 2 +- accounts/abi/pack.go | 23 ++-- accounts/abi/type.go | 2 +- accounts/abi/unpack.go | 5 +- go.mod | 1 + go.sum | 2 + tests/fuzzers/abi/abifuzzer.go | 186 ++++++++++++++++++++++++++++ tests/fuzzers/abi/abifuzzer_test.go | 50 ++++++++ 9 files changed, 261 insertions(+), 14 deletions(-) create mode 100644 tests/fuzzers/abi/abifuzzer.go create mode 100644 tests/fuzzers/abi/abifuzzer_test.go diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 48aa462357..3d07e4cbf5 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -33,7 +33,7 @@ import ( const jsondata = ` [ - { "type" : "function", "name" : "", "stateMutability" : "view" }, + { "type" : "function", "name" : ""}, { "type" : "function", "name" : "balance", "stateMutability" : "view" }, { "type" : "function", "name" : "send", "inputs" : [ { "name" : "amount", "type" : "uint256" } ] }, { "type" : "function", "name" : "test", "inputs" : [ { "name" : "number", "type" : "uint32" } ] }, @@ -88,7 +88,7 @@ var ( ) var methods = map[string]Method{ - "": NewMethod("", "", Function, "view", false, false, nil, nil), + "": NewMethod("", "", Function, "", false, false, nil, nil), "balance": NewMethod("balance", "balance", Function, "view", false, false, nil, nil), "send": NewMethod("send", "send", Function, "", false, false, []Argument{{"amount", Uint256, false}}, nil), "test": NewMethod("test", "test", Function, "", false, false, []Argument{{"number", Uint32, false}}, nil), diff --git a/accounts/abi/error.go b/accounts/abi/error.go index b63a215ad9..f0f71b6c91 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -52,7 +52,7 @@ func sliceTypeCheck(t Type, val reflect.Value) error { } } - if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.GetType().Kind() { + if val.Type().Elem().Kind() != t.Elem.GetType().Kind() { return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), val.Type()) } return nil diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index 58af1446bf..59b8b785ec 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -17,6 +17,8 @@ package abi import ( + "errors" + "fmt" "math/big" "reflect" @@ -33,35 +35,38 @@ func packBytesSlice(bytes []byte, l int) []byte { // packElement packs the given reflect value according to the abi specification in // t. -func packElement(t Type, reflectValue reflect.Value) []byte { +func packElement(t Type, reflectValue reflect.Value) ([]byte, error) { switch t.T { case IntTy, UintTy: - return packNum(reflectValue) + return packNum(reflectValue), nil case StringTy: - return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len()) + return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len()), nil case AddressTy: if reflectValue.Kind() == reflect.Array { reflectValue = mustArrayToByteSlice(reflectValue) } - return common.LeftPadBytes(reflectValue.Bytes(), 32) + return common.LeftPadBytes(reflectValue.Bytes(), 32), nil case BoolTy: if reflectValue.Bool() { - return math.PaddedBigBytes(common.Big1, 32) + return math.PaddedBigBytes(common.Big1, 32), nil } - return math.PaddedBigBytes(common.Big0, 32) + return math.PaddedBigBytes(common.Big0, 32), nil case BytesTy: if reflectValue.Kind() == reflect.Array { reflectValue = mustArrayToByteSlice(reflectValue) } - return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()) + if reflectValue.Type() != reflect.TypeOf([]byte{}) { + return []byte{}, errors.New("Bytes type is neither slice nor array") + } + return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()), nil case FixedBytesTy, FunctionTy: if reflectValue.Kind() == reflect.Array { reflectValue = mustArrayToByteSlice(reflectValue) } - return common.RightPadBytes(reflectValue.Bytes(), 32) + return common.RightPadBytes(reflectValue.Bytes(), 32), nil default: - panic("abi: fatal error") + return []byte{}, fmt.Errorf("Could not pack element, unknown type: %v", t.T) } } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 5b6d580e4b..83b553e6bf 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -345,7 +345,7 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { return append(ret, tail...), nil default: - return packElement(t, v), nil + return packElement(t, v) } } diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 15da1827ad..26e7ea1fe6 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -225,7 +225,10 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { return forEachUnpack(t, output[begin:], 0, length) case ArrayTy: if isDynamicType(*t.Elem) { - offset := int64(binary.BigEndian.Uint64(returnOutput[len(returnOutput)-8:])) + offset := binary.BigEndian.Uint64(returnOutput[len(returnOutput)-8:]) + if offset > uint64(len(output)) { + return nil, fmt.Errorf("abi: toGoType offset greater than output length: offset: %d, len(output): %d", offset, len(output)) + } return forEachUnpack(t, output[offset:], 0, t.Size) } return forEachUnpack(t, output[index:], 0, t.Size) diff --git a/go.mod b/go.mod index 537a08dcf8..b47ac993d6 100644 --- a/go.mod +++ b/go.mod @@ -51,6 +51,7 @@ require ( github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 github.com/go-yaml/yaml v2.1.0+incompatible + github.com/google/gofuzz v1.2.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/karalabe/usb v0.0.2 diff --git a/go.sum b/go.sum index 414e385db7..56803a319e 100644 --- a/go.sum +++ b/go.sum @@ -89,6 +89,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= diff --git a/tests/fuzzers/abi/abifuzzer.go b/tests/fuzzers/abi/abifuzzer.go new file mode 100644 index 0000000000..5b8986c09b --- /dev/null +++ b/tests/fuzzers/abi/abifuzzer.go @@ -0,0 +1,186 @@ +// Copyright 2020 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 . + +package abi + +import ( + "bytes" + "fmt" + "math/rand" + "reflect" + "strings" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/crypto" + fuzz "github.com/google/gofuzz" +) + +func unpackPack(abi abi.ABI, method string, inputType []interface{}, input []byte) bool { + outptr := reflect.New(reflect.TypeOf(inputType)) + if err := abi.Unpack(outptr.Interface(), method, input); err == nil { + output, err := abi.Pack(method, input) + if err != nil { + // We have some false positives as we can unpack these type successfully, but not pack them + if err.Error() == "abi: cannot use []uint8 as type [0]int8 as argument" || + err.Error() == "abi: cannot use uint8 as type int8 as argument" { + return false + } + panic(err) + } + if !bytes.Equal(input, output[4:]) { + panic(fmt.Sprintf("unpackPack is not equal, \ninput : %x\noutput: %x", input, output[4:])) + } + return true + } + return false +} + +func packUnpack(abi abi.ABI, method string, input []interface{}) bool { + if packed, err := abi.Pack(method, input); err == nil { + outptr := reflect.New(reflect.TypeOf(input)) + err := abi.Unpack(outptr.Interface(), method, packed) + if err != nil { + panic(err) + } + out := outptr.Elem().Interface() + if !reflect.DeepEqual(input, out) { + panic(fmt.Sprintf("unpackPack is not equal, \ninput : %x\noutput: %x", input, out)) + } + return true + } + return false +} + +type args struct { + name string + typ string +} + +func createABI(name string, stateMutability, payable *string, inputs []args) (abi.ABI, error) { + sig := fmt.Sprintf(`[{ "type" : "function", "name" : "%v" `, name) + if stateMutability != nil { + sig += fmt.Sprintf(`, "stateMutability": "%v" `, *stateMutability) + } + if payable != nil { + sig += fmt.Sprintf(`, "payable": %v `, *payable) + } + if len(inputs) > 0 { + sig += `, "inputs" : [ {` + for i, inp := range inputs { + sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ) + if i+1 < len(inputs) { + sig += "," + } + } + sig += "} ]" + sig += `, "outputs" : [ {` + for i, inp := range inputs { + sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ) + if i+1 < len(inputs) { + sig += "," + } + } + sig += "} ]" + } + sig += `}]` + + return abi.JSON(strings.NewReader(sig)) +} + +func fillStruct(structs []interface{}, data []byte) { + if structs != nil && len(data) != 0 { + fuzz.NewFromGoFuzz(data).Fuzz(&structs) + } +} + +func createStructs(args []args) []interface{} { + structs := make([]interface{}, len(args)) + for i, arg := range args { + t, err := abi.NewType(arg.typ, "", nil) + if err != nil { + panic(err) + } + structs[i] = reflect.New(t.GetType()).Elem() + } + return structs +} + +func runFuzzer(input []byte) int { + good := false + + names := []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"} + stateMut := []string{"", "pure", "view", "payable"} + stateMutabilites := []*string{nil, &stateMut[0], &stateMut[1], &stateMut[2], &stateMut[3]} + pays := []string{"true", "false"} + payables := []*string{nil, &pays[0], &pays[1]} + varNames := []string{"a", "b", "c", "d", "e", "f", "g"} + varNames = append(varNames, names...) + varTypes := []string{"bool", "address", "bytes", "string", + "uint8", "int8", "uint8", "int8", "uint16", "int16", + "uint24", "int24", "uint32", "int32", "uint40", "int40", "uint48", "int48", "uint56", "int56", + "uint64", "int64", "uint72", "int72", "uint80", "int80", "uint88", "int88", "uint96", "int96", + "uint104", "int104", "uint112", "int112", "uint120", "int120", "uint128", "int128", "uint136", "int136", + "uint144", "int144", "uint152", "int152", "uint160", "int160", "uint168", "int168", "uint176", "int176", + "uint184", "int184", "uint192", "int192", "uint200", "int200", "uint208", "int208", "uint216", "int216", + "uint224", "int224", "uint232", "int232", "uint240", "int240", "uint248", "int248", "uint256", "int256", + "bytes1", "bytes2", "bytes3", "bytes4", "bytes5", "bytes6", "bytes7", "bytes8", "bytes9", "bytes10", "bytes11", + "bytes12", "bytes13", "bytes14", "bytes15", "bytes16", "bytes17", "bytes18", "bytes19", "bytes20", "bytes21", + "bytes22", "bytes23", "bytes24", "bytes25", "bytes26", "bytes27", "bytes28", "bytes29", "bytes30", "bytes31", + "bytes32", "bytes"} + rnd := rand.New(rand.NewSource(123456)) + if len(input) > 0 { + kec := crypto.Keccak256(input) + rnd = rand.New(rand.NewSource(int64(kec[0]))) + } + name := names[rnd.Intn(len(names))] + stateM := stateMutabilites[rnd.Intn(len(stateMutabilites))] + payable := payables[rnd.Intn(len(payables))] + maxLen := 5 + for k := 1; k < maxLen; k++ { + var arg []args + for i := k; i > 0; i-- { + argName := varNames[i] + argTyp := varTypes[rnd.Int31n(int32(len(varTypes)))] + if rnd.Int31n(10) == 0 { + argTyp += "[]" + } else if rnd.Int31n(10) == 0 { + arrayArgs := rnd.Int31n(30) + 1 + argTyp += fmt.Sprintf("[%d]", arrayArgs) + } + arg = append(arg, args{ + name: argName, + typ: argTyp, + }) + } + abi, err := createABI(name, stateM, payable, arg) + if err != nil { + continue + } + structs := createStructs(arg) + b := unpackPack(abi, name, structs, input) + fillStruct(structs, input) + c := packUnpack(abi, name, structs) + good = good || b || c + } + if good { + return 1 + } + return 0 +} + +func Fuzz(input []byte) int { + return runFuzzer(input) +} diff --git a/tests/fuzzers/abi/abifuzzer_test.go b/tests/fuzzers/abi/abifuzzer_test.go new file mode 100644 index 0000000000..c72577e9ee --- /dev/null +++ b/tests/fuzzers/abi/abifuzzer_test.go @@ -0,0 +1,50 @@ +// Copyright 2020 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 . + +package abi + +import ( + "testing" +) + +// TestReplicate can be used to replicate crashers from the fuzzing tests. +// Just replace testString with the data in .quoted +func TestReplicate(t *testing.T) { + testString := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00000000000" + + "00000000000000000000" + + "00000000000000000000" + + "00000001" + + data := []byte(testString) + runFuzzer(data) +} + +// TestGenerateCorpus can be used to add corpus for the fuzzer. +// Just replace corpusHex with the hexEncoded output you want to add to the fuzzer. +func TestGenerateCorpus(t *testing.T) { + /* + corpusHex := "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + data := common.FromHex(corpusHex) + checksum := sha1.Sum(data) + outf := fmt.Sprintf("corpus/%x", checksum) + if err := ioutil.WriteFile(outf, data, 0777); err != nil { + panic(err) + } + */ +} From 22df50c77ab90ef8f061e7b7f9f5ab7487f83495 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 126/280] accounts/abi: improve documentation and names (#21540) * accounts: abi/bid/backends; cleaned doc errors, camelCase refactors and anonymous variable assignments * acounts/abi/bind: doc errors, anonymous parameter assignments * accounts/abi: doc edits, camelCase refactors * accounts/abi/bind: review fix * reverted name changes * name revert Co-authored-by: Osoro Bironga --- accounts/abi/abi.go | 10 +++++----- accounts/abi/abi_test.go | 2 +- accounts/abi/argument.go | 18 +++++++++--------- accounts/abi/bind/auth.go | 2 +- accounts/abi/bind/backend.go | 6 +++--- accounts/abi/bind/base.go | 2 +- accounts/abi/bind/bind.go | 18 +++++++++--------- accounts/abi/bind/template.go | 11 ++++++----- accounts/abi/event.go | 2 +- accounts/abi/event_test.go | 2 +- accounts/abi/method.go | 4 ++-- accounts/abi/pack.go | 5 ++--- accounts/abi/reflect.go | 2 +- accounts/abi/topics.go | 4 ++-- accounts/abi/type.go | 4 ++-- accounts/abi/unpack.go | 17 +++++++++-------- 16 files changed, 55 insertions(+), 54 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 712bd58348..09f30edee9 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -80,7 +80,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { return append(method.ID, arguments...), nil } -// Unpack output in v according to the abi specification +// Unpack output in v according to the abi specification. func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event @@ -96,7 +96,7 @@ func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { return fmt.Errorf("abi: could not locate named method or event") } -// UnpackIntoMap unpacks a log into the provided map[string]interface{} +// UnpackIntoMap unpacks a log into the provided map[string]interface{}. func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) { // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event @@ -112,7 +112,7 @@ func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) return errors.New("abi: could not locate named method or event") } -// UnmarshalJSON implements json.Unmarshaler interface +// UnmarshalJSON implements json.Unmarshaler interface. func (abi *ABI) UnmarshalJSON(data []byte) error { var fields []struct { Type string @@ -201,8 +201,8 @@ func (abi *ABI) overloadedEventName(rawName string) string { return name } -// MethodById looks up a method by the 4-byte id -// returns nil if none found +// MethodById looks up a method by the 4-byte id, +// returns nil if none found. func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { if len(sigdata) < 4 { return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata)) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 3d07e4cbf5..d13aa7fc60 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1127,7 +1127,7 @@ func TestDoubleDuplicateEventNames(t *testing.T) { } // TestUnnamedEventParam checks that an event with unnamed parameters is -// correctly handled +// correctly handled. // The test runs the abi of the following contract. // contract TestEvent { // event send(uint256, uint256); diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 81151ef0e0..aaef3bd41c 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -41,7 +41,7 @@ type ArgumentMarshaling struct { Indexed bool } -// UnmarshalJSON implements json.Unmarshaler interface +// UnmarshalJSON implements json.Unmarshaler interface. func (argument *Argument) UnmarshalJSON(data []byte) error { var arg ArgumentMarshaling err := json.Unmarshal(data, &arg) @@ -59,7 +59,7 @@ func (argument *Argument) UnmarshalJSON(data []byte) error { return nil } -// NonIndexed returns the arguments with indexed arguments filtered out +// NonIndexed returns the arguments with indexed arguments filtered out. func (arguments Arguments) NonIndexed() Arguments { var ret []Argument for _, arg := range arguments { @@ -70,12 +70,12 @@ func (arguments Arguments) NonIndexed() Arguments { return ret } -// isTuple returns true for non-atomic constructs, like (uint,uint) or uint[] +// isTuple returns true for non-atomic constructs, like (uint,uint) or uint[]. func (arguments Arguments) isTuple() bool { return len(arguments) > 1 } -// Unpack performs the operation hexdata -> Go format +// Unpack performs the operation hexdata -> Go format. func (arguments Arguments) Unpack(v interface{}, data []byte) error { if len(data) == 0 { if len(arguments) != 0 { @@ -100,7 +100,7 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error { return arguments.unpackAtomic(v, marshalledValues[0]) } -// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value +// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value. func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { // Make sure map is not nil if v == nil { @@ -122,7 +122,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) return nil } -// unpackAtomic unpacks ( hexdata -> go ) a single value +// unpackAtomic unpacks ( hexdata -> go ) a single value. func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) @@ -207,13 +207,13 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { return retval, nil } -// PackValues performs the operation Go format -> Hexdata -// It is the semantic opposite of UnpackValues +// PackValues performs the operation Go format -> Hexdata. +// It is the semantic opposite of UnpackValues. func (arguments Arguments) PackValues(args []interface{}) ([]byte, error) { return arguments.Pack(args...) } -// Pack performs the operation Go format -> Hexdata +// Pack performs the operation Go format -> Hexdata. func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) { // Make sure arguments match up and pack them abiArgs := arguments diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 6051aebe58..22ae6a218f 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -54,7 +54,7 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { } // NewKeyStoreTransactor is a utility method to easily create a transaction signer from -// an decrypted key from a keystore +// a decrypted key from a keystore. func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { signer := types.HomesteadSigner{} return &TransactOpts{ diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 25ac008c03..b067b7da2a 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -41,7 +41,7 @@ var ( ErrNoCodeAfterDeploy = errors.New("no contract code after deployment") ) -// ContractCaller defines the methods needed to allow operating with contract on a read +// ContractCaller defines the methods needed to allow operating with a contract on a read // only basis. type ContractCaller interface { // CodeAt returns the code of the given account. This is needed to differentiate @@ -64,8 +64,8 @@ type PendingContractCaller interface { PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error) } -// ContractTransactor defines the methods needed to allow operating with contract -// on a write only basis. Beside the transacting method, the remainder are helpers +// ContractTransactor defines the methods needed to allow operating with a contract +// on a write only basis. Besides the transacting method, the remainder are helpers // used when the user does not provide some needed values, but rather leaves it up // to the transactor to decide. type ContractTransactor interface { diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index ee66ae5c86..9961b22cbf 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -185,7 +185,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in } // RawTransact initiates a transaction with the given raw calldata as the input. -// It's usually used to initiates transaction for invoking **Fallback** function. +// It's usually used to initiate transactions for invoking **Fallback** function. func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) { // todo(rjl493456442) check the method is payable or not, // reject invalid transaction at the first place diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 53e278274b..0d2a0cc0a5 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -49,7 +49,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // contracts is the map of each individual contract requested binding contracts = make(map[string]*tmplContract) - // structs is the map of all reclared structs shared by passed contracts. + // structs is the map of all redeclared structs shared by passed contracts. structs = make(map[string]*tmplStruct) // isLib is the map used to flag each encountered library as such @@ -77,10 +77,10 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] fallback *tmplMethod receive *tmplMethod - // identifiers are used to detect duplicated identifier of function - // and event. For all calls, transacts and events, abigen will generate + // identifiers are used to detect duplicated identifiers of functions + // and events. For all calls, transacts and events, abigen will generate // corresponding bindings. However we have to ensure there is no - // identifier coliision in the bindings of these categories. + // identifier collisions in the bindings of these categories. callIdentifiers = make(map[string]bool) transactIdentifiers = make(map[string]bool) eventIdentifiers = make(map[string]bool) @@ -238,7 +238,7 @@ var bindType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) stri LangGo: bindTypeGo, } -// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go one. +// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go ones. func bindBasicTypeGo(kind abi.Type) string { switch kind.T { case abi.AddressTy: @@ -285,7 +285,7 @@ var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) } // bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same -// funcionality as for simple types, but dynamic types get converted to hashes. +// functionality as for simple types, but dynamic types get converted to hashes. func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { bound := bindTypeGo(kind, structs) @@ -313,7 +313,7 @@ var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { switch kind.T { case abi.TupleTy: - // We compose raw struct name and canonical parameter expression + // We compose a raw struct name and a canonical parameter expression // together here. The reason is before solidity v0.5.11, kind.TupleRawName // is empty, so we use canonical parameter expression to distinguish // different struct definition. From the consideration of backward @@ -347,7 +347,7 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { } // namedType is a set of functions that transform language specific types to -// named versions that my be used inside method names. +// named versions that may be used inside method names. var namedType = map[Lang]func(string, abi.Type) string{ LangGo: func(string, abi.Type) string { panic("this shouldn't be needed") }, } @@ -362,7 +362,7 @@ func alias(aliases map[string]string, n string) string { } // methodNormalizer is a name transformer that modifies Solidity method names to -// conform to target language naming concentions. +// conform to target language naming conventions. var methodNormalizer = map[Lang]func(string) string{ LangGo: abi.ToCamelCase, } diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 49c877d4a4..13ead915b9 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -30,7 +30,7 @@ type tmplData struct { type tmplContract struct { Type string // Type name of the main contract binding InputABI string // JSON ABI used as the input to generate the binding from - InputBin string // Optional EVM bytecode used to denetare deploy code from + InputBin string // Optional EVM bytecode used to generate deploy code from FuncSigs map[string]string // Optional map: string signature -> 4-byte signature Constructor abi.Method // Contract constructor for deploy parametrization Calls map[string]*tmplMethod // Contract calls that only read state data @@ -50,7 +50,8 @@ type tmplMethod struct { Structured bool // Whether the returns should be accumulated into a struct } -// tmplEvent is a wrapper around an a +// tmplEvent is a wrapper around an abi.Event that contains a few preprocessed +// and cached data fields. type tmplEvent struct { Original abi.Event // Original event as parsed by the abi package Normalized abi.Event // Normalized version of the parsed fields @@ -64,7 +65,7 @@ type tmplField struct { SolKind abi.Type // Raw abi type information } -// tmplStruct is a wrapper around an abi.tuple contains an auto-generated +// tmplStruct is a wrapper around an abi.tuple and contains an auto-generated // struct name. type tmplStruct struct { Name string // Auto-generated struct name(before solidity v0.5.11) or raw name. @@ -77,8 +78,8 @@ var tmplSource = map[Lang]string{ LangGo: tmplSourceGo, } -// tmplSourceGo is the Go source template use to generate the contract binding -// based on. +// tmplSourceGo is the Go source template that the generated Go contract binding +// is based on. const tmplSourceGo = ` // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. diff --git a/accounts/abi/event.go b/accounts/abi/event.go index db01a0f6bf..1eb53d9e91 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -32,7 +32,7 @@ type Event struct { // the raw name and a suffix will be added in the case of a event overload. // // e.g. - // There are two events have same name: + // These are two events that have the same name: // * foo(int,int) // * foo(uint,uint) // The event name of the first one wll be resolved as foo while the second one diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 836b3fadcf..32d6d05609 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -371,7 +371,7 @@ func TestEventUnpackIndexed(t *testing.T) { require.Equal(t, uint8(8), rst.Value2) } -// TestEventIndexedWithArrayUnpack verifies that decoder will not overlow when static array is indexed input. +// TestEventIndexedWithArrayUnpack verifies that decoder will not overflow when static array is indexed input. func TestEventIndexedWithArrayUnpack(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]` type testStruct struct { diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 3e6573ad5c..c67a8a1e78 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -45,7 +45,7 @@ const ( // If the method is `Const` no transaction needs to be created for this // particular Method call. It can easily be simulated using a local VM. // For example a `Balance()` method only needs to retrieve something -// from the storage and therefore requires no Tx to be send to the +// from the storage and therefore requires no Tx to be sent to the // network. A method such as `Transact` does require a Tx and thus will // be flagged `false`. // Input specifies the required input parameters for this gives method. @@ -54,7 +54,7 @@ type Method struct { // the raw name and a suffix will be added in the case of a function overload. // // e.g. - // There are two functions have same name: + // These are two functions that have the same name: // * foo(int,int) // * foo(uint,uint) // The method name of the first one will be resolved as foo while the second one diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index 59b8b785ec..42b314c734 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -27,7 +27,7 @@ import ( ) // packBytesSlice packs the given bytes as [L, V] as the canonical representation -// bytes slice +// bytes slice. func packBytesSlice(bytes []byte, l int) []byte { len := packNum(reflect.ValueOf(l)) return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...) @@ -70,7 +70,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) { } } -// packNum packs the given number (using the reflect value) and will cast it to appropriate number representation +// packNum packs the given number (using the reflect value) and will cast it to appropriate number representation. func packNum(value reflect.Value) []byte { switch kind := value.Kind(); kind { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: @@ -82,5 +82,4 @@ func packNum(value reflect.Value) []byte { default: panic("abi: fatal error") } - } diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 7892c730e3..34a63f44d6 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -61,7 +61,7 @@ func reflectIntType(unsigned bool, size int) reflect.Type { return reflect.TypeOf(&big.Int{}) } -// mustArrayToBytesSlice creates a new byte slice with the exact same size as value +// mustArrayToByteSlice creates a new byte slice with the exact same size as value // and copies the bytes in value to the new slice. func mustArrayToByteSlice(value reflect.Value) reflect.Value { slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len()) diff --git a/accounts/abi/topics.go b/accounts/abi/topics.go index a46968b385..119ef06d24 100644 --- a/accounts/abi/topics.go +++ b/accounts/abi/topics.go @@ -102,7 +102,7 @@ func genIntType(rule int64, size uint) []byte { var topic [common.HashLength]byte if rule < 0 { // if a rule is negative, we need to put it into two's complement. - // extended to common.Hashlength bytes. + // extended to common.HashLength bytes. topic = [common.HashLength]byte{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} } for i := uint(0); i < size; i++ { @@ -120,7 +120,7 @@ func ParseTopics(out interface{}, fields Arguments, topics []common.Hash) error }) } -// ParseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs +// ParseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs. func ParseTopicsIntoMap(out map[string]interface{}, fields Arguments, topics []common.Hash) error { return parseTopicWithSetter(fields, topics, func(arg Argument, reconstr interface{}) { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 83b553e6bf..95b985f303 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -44,7 +44,7 @@ const ( FunctionTy ) -// Type is the reflection of the supported argument type +// Type is the reflection of the supported argument type. type Type struct { Elem *Type Size int @@ -263,7 +263,7 @@ func overloadedArgName(rawName string, names map[string]string) (string, error) return fieldName, nil } -// String implements Stringer +// String implements Stringer. func (t Type) String() (out string) { return t.stringKind } diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 26e7ea1fe6..4bafd5b6df 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -27,13 +27,13 @@ import ( ) var ( - // MaxUint256 is the maximum value that can be represented by a uint256 + // MaxUint256 is the maximum value that can be represented by a uint256. MaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 256), common.Big1) - // MaxInt256 is the maximum value that can be represented by a int256 + // MaxInt256 is the maximum value that can be represented by a int256. MaxInt256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 255), common.Big1) ) -// ReadInteger reads the integer based on its kind and returns the appropriate value +// ReadInteger reads the integer based on its kind and returns the appropriate value. func ReadInteger(typ Type, b []byte) interface{} { if typ.T == UintTy { switch typ.Size { @@ -74,7 +74,7 @@ func ReadInteger(typ Type, b []byte) interface{} { } } -// reads a bool +// readBool reads a bool. func readBool(word []byte) (bool, error) { for _, b := range word[:31] { if b != 0 { @@ -92,7 +92,8 @@ func readBool(word []byte) (bool, error) { } // A function type is simply the address with the function selection signature at the end. -// This enforces that standard by always presenting it as a 24-array (address + sig = 24 bytes) +// +// readFunctionType enforces that standard by always presenting it as a 24-array (address + sig = 24 bytes) func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) { if t.T != FunctionTy { return [24]byte{}, errors.New("abi: invalid type in call to make function type byte array") @@ -105,7 +106,7 @@ func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) { return } -// ReadFixedBytes uses reflection to create a fixed array to be read from +// ReadFixedBytes uses reflection to create a fixed array to be read from. func ReadFixedBytes(t Type, word []byte) (interface{}, error) { if t.T != FixedBytesTy { return nil, errors.New("abi: invalid type in call to make fixed byte array") @@ -118,7 +119,7 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) { } -// iteratively unpack elements +// forEachUnpack iteratively unpack elements. func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) { if size < 0 { return nil, fmt.Errorf("cannot marshal input to array, size is negative (%d)", size) @@ -253,7 +254,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { } } -// interprets a 32 byte slice as an offset and then determines which indice to look to decode the type. +// lengthPrefixPointsTo interprets a 32 byte slice as an offset and then determines which indices to look to decode the type. func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err error) { bigOffsetEnd := big.NewInt(0).SetBytes(output[index : index+32]) bigOffsetEnd.Add(bigOffsetEnd, common.Big32) From b0063d39b98b8da449c894f322530ca82947e1ca Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 127/280] accounts/abi: ABI explicit difference between Unpack and UnpackIntoInterface (#21091) * accounts/abi: refactored abi.Unpack * accounts/abi/bind: fixed error * accounts/abi/bind: modified template * accounts/abi/bind: added ToStruct for conversion * accounts/abi: reenabled tests * accounts/abi: fixed tests * accounts/abi: fixed tests for packing/unpacking * accounts/abi: fixed tests * accounts/abi: added more logic to ToStruct * accounts/abi/bind: fixed template * accounts/abi/bind: fixed ToStruct conversion * accounts/abi/: removed unused code * accounts/abi: updated template * accounts/abi: refactored unused code * contracts/checkpointoracle: updated contracts to sol ^0.6.0 * accounts/abi: refactored reflection logic * accounts/abi: less code duplication in Unpack* * accounts/abi: fixed rebasing bug * fix a few typos in comments * rebase on master Co-authored-by: Guillaume Ballet --- XDCx/token.go | 2 +- accounts/abi/abi.go | 60 ++++-- accounts/abi/abi_test.go | 17 +- accounts/abi/argument.go | 54 +++--- accounts/abi/bind/base.go | 15 +- accounts/abi/bind/base_test.go | 10 +- accounts/abi/bind/bind_test.go | 4 +- accounts/abi/bind/template.go | 34 ++-- accounts/abi/event_test.go | 22 +-- accounts/abi/pack_test.go | 13 +- accounts/abi/packing_test.go | 50 ++--- accounts/abi/reflect.go | 26 +++ accounts/abi/reflect_test.go | 70 +++++++ accounts/abi/unpack_test.go | 60 +++--- .../XDCx/contract/LendingRegistration.go | 68 +++++-- contracts/XDCx/contract/Registration.go | 56 ++++-- contracts/XDCx/contract/TRC21.go | 180 +++++++++++++----- contracts/XDCx/contract/TRC21Issuer.go | 24 ++- contracts/XDCx/contract/XDCXListing.go | 12 +- contracts/blocksigner/contract/blocksigner.go | 16 +- .../multisigwallet/contract/multisigwallet.go | 56 ++++-- contracts/randomize/contract/randomize.go | 16 +- contracts/tests/contract/Inherited.go | 12 +- contracts/trc21issuer/contract/TRC21.go | 88 ++++++--- contracts/trc21issuer/contract/TRC21Issuer.go | 24 ++- contracts/validator/contract/validator.go | 108 ++++++++--- core/token_validator.go | 2 +- tests/fuzzers/abi/abifuzzer.go | 4 +- 28 files changed, 747 insertions(+), 356 deletions(-) diff --git a/XDCx/token.go b/XDCx/token.go index c44dbe7e29..6596596930 100644 --- a/XDCx/token.go +++ b/XDCx/token.go @@ -36,7 +36,7 @@ func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractA return nil, err } var unpackResult interface{} - err = abi.Unpack(&unpackResult, method, result) + err = abi.UnpackIntoInterface(&unpackResult, method, result) if err != nil { return nil, err } diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 09f30edee9..574829b328 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -80,36 +80,56 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { return append(method.ID, arguments...), nil } -// Unpack output in v according to the abi specification. -func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) { +func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { // since there can't be naming collisions with contracts and events, // we need to decide whether we're calling a method or an event + var args Arguments if method, ok := abi.Methods[name]; ok { if len(data)%32 != 0 { - return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data) + return nil, fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data) } - return method.Outputs.Unpack(v, data) + args = method.Outputs } if event, ok := abi.Events[name]; ok { - return event.Inputs.Unpack(v, data) + args = event.Inputs } - return fmt.Errorf("abi: could not locate named method or event") + if args == nil { + return nil, errors.New("abi: could not locate named method or event") + } + return args, nil +} + +// Unpack unpacks the output according to the abi specification. +func (abi ABI) Unpack(name string, data []byte) ([]interface{}, error) { + args, err := abi.getArguments(name, data) + if err != nil { + return nil, err + } + return args.Unpack(data) +} + +// UnpackIntoInterface unpacks the output in v according to the abi specification. +// It performs an additional copy. Please only use, if you want to unpack into a +// structure that does not strictly conform to the abi structure (e.g. has additional arguments) +func (abi ABI) UnpackIntoInterface(v interface{}, name string, data []byte) error { + args, err := abi.getArguments(name, data) + if err != nil { + return err + } + unpacked, err := args.Unpack(data) + if err != nil { + return err + } + return args.Copy(v, unpacked) } // UnpackIntoMap unpacks a log into the provided map[string]interface{}. func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) { - // since there can't be naming collisions with contracts and events, - // we need to decide whether we're calling a method or an event - if method, ok := abi.Methods[name]; ok { - if len(data)%32 != 0 { - return fmt.Errorf("abi: improperly formatted output") - } - return method.Outputs.UnpackIntoMap(v, data) + args, err := abi.getArguments(name, data) + if err != nil { + return err } - if event, ok := abi.Events[name]; ok { - return event.Inputs.UnpackIntoMap(v, data) - } - return errors.New("abi: could not locate named method or event") + return args.UnpackIntoMap(v, data) } // UnmarshalJSON implements json.Unmarshaler interface. @@ -250,10 +270,10 @@ func UnpackRevert(data []byte) (string, error) { if !bytes.Equal(data[:4], revertSelector) { return "", errors.New("invalid data for unpacking") } - var reason string typ, _ := NewType("string", "", nil) - if err := (Arguments{{Type: typ}}).Unpack(&reason, data[4:]); err != nil { + unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:]) + if err != nil { return "", err } - return reason, nil + return unpacked[0].(string), nil } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index d13aa7fc60..4b8faf3ace 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -181,18 +181,15 @@ func TestConstructor(t *testing.T) { if err != nil { t.Error(err) } - v := struct { - A *big.Int - B *big.Int - }{new(big.Int), new(big.Int)} - //abi.Unpack(&v, "", packed) - if err := abi.Constructor.Inputs.Unpack(&v, packed); err != nil { + unpacked, err := abi.Constructor.Inputs.Unpack(packed) + if err != nil { t.Error(err) } - if !reflect.DeepEqual(v.A, big.NewInt(1)) { + + if !reflect.DeepEqual(unpacked[0], big.NewInt(1)) { t.Error("Unable to pack/unpack from constructor") } - if !reflect.DeepEqual(v.B, big.NewInt(2)) { + if !reflect.DeepEqual(unpacked[1], big.NewInt(2)) { t.Error("Unable to pack/unpack from constructor") } } @@ -747,7 +744,7 @@ func TestUnpackEvent(t *testing.T) { } var ev ReceivedEvent - err = abi.Unpack(&ev, "received", data) + err = abi.UnpackIntoInterface(&ev, "received", data) if err != nil { t.Error(err) } @@ -756,7 +753,7 @@ func TestUnpackEvent(t *testing.T) { Sender common.Address } var receivedAddrEv ReceivedAddrEvent - err = abi.Unpack(&receivedAddrEv, "receivedAddr", data) + err = abi.UnpackIntoInterface(&receivedAddrEv, "receivedAddr", data) if err != nil { t.Error(err) } diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index aaef3bd41c..e6d5245596 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -76,28 +76,20 @@ func (arguments Arguments) isTuple() bool { } // Unpack performs the operation hexdata -> Go format. -func (arguments Arguments) Unpack(v interface{}, data []byte) error { +func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { if len(data) == 0 { if len(arguments) != 0 { - return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") + return nil, fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") } - return nil // Nothing to unmarshal, return + // Nothing to unmarshal, return default variables + nonIndexedArgs := arguments.NonIndexed() + defaultVars := make([]interface{}, len(nonIndexedArgs)) + for index, arg := range nonIndexedArgs { + defaultVars[index] = reflect.New(arg.Type.GetType()) + } + return defaultVars, nil } - // make sure the passed value is arguments pointer - if reflect.Ptr != reflect.ValueOf(v).Kind() { - return fmt.Errorf("abi: Unpack(non-pointer %T)", v) - } - marshalledValues, err := arguments.UnpackValues(data) - if err != nil { - return err - } - if len(marshalledValues) == 0 { - return fmt.Errorf("abi: Unpack(no-values unmarshalled %T)", v) - } - if arguments.isTuple() { - return arguments.unpackTuple(v, marshalledValues) - } - return arguments.unpackAtomic(v, marshalledValues[0]) + return arguments.UnpackValues(data) } // UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value. @@ -122,8 +114,26 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) return nil } -// unpackAtomic unpacks ( hexdata -> go ) a single value. -func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error { +// Copy performs the operation go format -> provided struct. +func (arguments Arguments) Copy(v interface{}, values []interface{}) error { + // make sure the passed value is arguments pointer + if reflect.Ptr != reflect.ValueOf(v).Kind() { + return fmt.Errorf("abi: Unpack(non-pointer %T)", v) + } + if len(values) == 0 { + if len(arguments) != 0 { + return fmt.Errorf("abi: attempting to copy no values while %d arguments are expected", len(arguments)) + } + return nil // Nothing to copy, return + } + if arguments.isTuple() { + return arguments.copyTuple(v, values) + } + return arguments.copyAtomic(v, values[0]) +} + +// unpackAtomic unpacks ( hexdata -> go ) a single value +func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error { dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) @@ -133,8 +143,8 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interfac return set(dst, src) } -// unpackTuple unpacks ( hexdata -> go ) a batch of values. -func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error { +// copyTuple copies a batch of values from marshalledValues to v. +func (arguments Arguments) copyTuple(v interface{}, marshalledValues []interface{}) error { value := reflect.ValueOf(v).Elem() nonIndexedArgs := arguments.NonIndexed() diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 9961b22cbf..4ad422389e 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -125,11 +125,14 @@ func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend Co // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, params ...interface{}) error { +func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method string, params ...interface{}) error { // Don't crash on a lazy user if opts == nil { opts = new(CallOpts) } + if results == nil { + results = new([]interface{}) + } // Pack the input, call and unpack the results input, err := c.abi.Pack(method, params...) if err != nil { @@ -166,10 +169,14 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, } } } - if err != nil { + + if len(*results) == 0 { + res, err := c.abi.Unpack(method, output) + *results = res return err } - return c.abi.Unpack(result, method, output) + res := *results + return c.abi.UnpackIntoInterface(res[0], method, output) } // Transact invokes the (paid) contract method with params as input values. @@ -455,7 +462,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) return errors.New("event signature mismatch") } if len(log.Data) > 0 { - if err := c.abi.Unpack(out, event, log.Data); err != nil { + if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil { return err } } diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 538b01a5aa..5bc9eee3fc 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -116,24 +116,22 @@ func TestPassingBlockNumber(t *testing.T) { bc.Call(&bind.CallOpts{}, nil, "something") - bc.Call(&bind.CallOpts{}, nil, "something") - if mc.callContractBlockNumber != nil { - t.Fatalf("CallContract() was passed a block number when it should not have been") + t.Fatal("CallContract() was passed a block number when it should not have been") } if mc.codeAtBlockNumber != nil { - t.Fatalf("CodeAt() was passed a block number when it should not have been") + t.Fatal("CodeAt() was passed a block number when it should not have been") } bc.Call(&bind.CallOpts{Pending: true}, nil, "something") if !mc.pendingCallContractCalled { - t.Fatalf("CallContract() was not passed the block number") + t.Fatal("CallContract() was not passed the block number") } if !mc.pendingCodeAtCalled { - t.Fatalf("CodeAt() was not passed the block number") + t.Fatal("CodeAt() was not passed the block number") } } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index fd6af530d7..bb90a6a8cf 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1648,11 +1648,11 @@ func TestGolangBindings(t *testing.T) { } t.Log("Using config", params.TestXDPoSMockChainConfig) // Create a temporary workspace for the test suite - ws, err := os.MkdirTemp("", "") + ws, err := os.MkdirTemp("", "binding-test") if err != nil { t.Fatalf("failed to create temporary workspace: %v", err) } - defer os.RemoveAll(ws) + // defer os.RemoveAll(ws) pkg := filepath.Join(ws, "bindtest") if err = os.MkdirAll(pkg, 0700); err != nil { diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 13ead915b9..e91b3a75a8 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -260,7 +260,7 @@ var ( // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...) } @@ -279,7 +279,7 @@ var ( // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. - func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { + func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...) } @@ -299,19 +299,23 @@ var ( // // Solidity: {{.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { - {{if .Structured}}ret := new(struct{ - {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}} - {{end}} - }){{else}}var ( - {{range $i, $_ := .Normalized.Outputs}}ret{{$i}} = new({{bindtype .Type $structs}}) - {{end}} - ){{end}} - out := {{if .Structured}}ret{{else}}{{if eq (len .Normalized.Outputs) 1}}ret0{{else}}&[]interface{}{ - {{range $i, $_ := .Normalized.Outputs}}ret{{$i}}, - {{end}} - }{{end}}{{end}} - err := _{{$contract.Type}}.contract.Call(opts, out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - return {{if .Structured}}*ret,{{else}}{{range $i, $_ := .Normalized.Outputs}}*ret{{$i}},{{end}}{{end}} err + var out []interface{} + err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + {{if .Structured}} + outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) + {{range $i, $t := .Normalized.Outputs}} + outstruct.{{.Name}} = out[{{$i}}].({{bindtype .Type $structs}}){{end}} + + return *outstruct, err + {{else}} + if err != nil { + return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err + } + {{range $i, $t := .Normalized.Outputs}} + out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err + {{end}} } // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 32d6d05609..e5ac313742 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -147,10 +147,6 @@ func TestEventString(t *testing.T) { // TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array. func TestEventMultiValueWithArrayUnpack(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` - type testStruct struct { - Value1 [2]uint8 - Value2 uint8 - } abi, err := JSON(strings.NewReader(definition)) require.NoError(t, err) var b bytes.Buffer @@ -158,10 +154,10 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) { for ; i <= 3; i++ { b.Write(packNum(reflect.ValueOf(i))) } - var rst testStruct - require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) - require.Equal(t, [2]uint8{1, 2}, rst.Value1) - require.Equal(t, uint8(3), rst.Value2) + unpacked, err := abi.Unpack("test", b.Bytes()) + require.NoError(t, err) + require.Equal(t, [2]uint8{1, 2}, unpacked[0]) + require.Equal(t, uint8(3), unpacked[1]) } func TestEventTupleUnpack(t *testing.T) { @@ -351,14 +347,14 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass var e Event assert.NoError(json.Unmarshal(jsonEvent, &e), "Should be able to unmarshal event ABI") a := ABI{Events: map[string]Event{"e": e}} - return a.Unpack(dest, "e", data) + return a.UnpackIntoInterface(dest, "e", data) } // TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder. func TestEventUnpackIndexed(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` type testStruct struct { - Value1 uint8 + Value1 uint8 // indexed Value2 uint8 } abi, err := JSON(strings.NewReader(definition)) @@ -366,7 +362,7 @@ func TestEventUnpackIndexed(t *testing.T) { var b bytes.Buffer b.Write(packNum(reflect.ValueOf(uint8(8)))) var rst testStruct - require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) + require.NoError(t, abi.UnpackIntoInterface(&rst, "test", b.Bytes())) require.Equal(t, uint8(0), rst.Value1) require.Equal(t, uint8(8), rst.Value2) } @@ -375,7 +371,7 @@ func TestEventUnpackIndexed(t *testing.T) { func TestEventIndexedWithArrayUnpack(t *testing.T) { definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]` type testStruct struct { - Value1 [2]uint8 + Value1 [2]uint8 // indexed Value2 string } abi, err := JSON(strings.NewReader(definition)) @@ -388,7 +384,7 @@ func TestEventIndexedWithArrayUnpack(t *testing.T) { b.Write(common.RightPadBytes([]byte(stringOut), 32)) var rst testStruct - require.NoError(t, abi.Unpack(&rst, "test", b.Bytes())) + require.NoError(t, abi.UnpackIntoInterface(&rst, "test", b.Bytes())) require.Equal(t, [2]uint8{0, 0}, rst.Value1) require.Equal(t, stringOut, rst.Value2) } diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index e7990ae294..bdb85d9d70 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -44,18 +44,7 @@ func TestPack(t *testing.T) { t.Fatalf("invalid ABI definition %s, %v", inDef, err) } var packed []byte - if reflect.TypeOf(test.unpacked).Kind() != reflect.Struct { - packed, err = inAbi.Pack("method", test.unpacked) - } else { - // if want is a struct we need to use the components. - elem := reflect.ValueOf(test.unpacked) - var values []interface{} - for i := 0; i < elem.NumField(); i++ { - field := elem.Field(i) - values = append(values, field.Interface()) - } - packed, err = inAbi.Pack("method", values...) - } + packed, err = inAbi.Pack("method", test.unpacked) if err != nil { t.Fatalf("test %d (%v) failed: %v", i, test.def, err) diff --git a/accounts/abi/packing_test.go b/accounts/abi/packing_test.go index 5794c97a50..ee3736c0f5 100644 --- a/accounts/abi/packing_test.go +++ b/accounts/abi/packing_test.go @@ -620,7 +620,7 @@ var packUnpackTests = []packUnpackTest{ { def: `[{"type": "bytes32[]"}]`, - unpacked: []common.Hash{{1}, {2}}, + unpacked: [][32]byte{{1}, {2}}, packed: "0000000000000000000000000000000000000000000000000000000000000020" + "0000000000000000000000000000000000000000000000000000000000000002" + "0100000000000000000000000000000000000000000000000000000000000000" + @@ -722,7 +722,7 @@ var packUnpackTests = []packUnpackTest{ }, // struct outputs { - def: `[{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}]`, + def: `[{"components": [{"name":"int1","type":"int256"},{"name":"int2","type":"int256"}], "type":"tuple"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002", unpacked: struct { @@ -731,28 +731,28 @@ var packUnpackTests = []packUnpackTest{ }{big.NewInt(1), big.NewInt(2)}, }, { - def: `[{"name":"int_one","type":"int256"}]`, + def: `[{"components": [{"name":"int_one","type":"int256"}], "type":"tuple"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001", unpacked: struct { IntOne *big.Int }{big.NewInt(1)}, }, { - def: `[{"name":"int__one","type":"int256"}]`, + def: `[{"components": [{"name":"int__one","type":"int256"}], "type":"tuple"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001", unpacked: struct { IntOne *big.Int }{big.NewInt(1)}, }, { - def: `[{"name":"int_one_","type":"int256"}]`, + def: `[{"components": [{"name":"int_one_","type":"int256"}], "type":"tuple"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001", unpacked: struct { IntOne *big.Int }{big.NewInt(1)}, }, { - def: `[{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}]`, + def: `[{"components": [{"name":"int_one","type":"int256"}, {"name":"intone","type":"int256"}], "type":"tuple"}]`, packed: "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000002", unpacked: struct { @@ -831,11 +831,11 @@ var packUnpackTests = []packUnpackTest{ }, { // static tuple - def: `[{"name":"a","type":"int64"}, + def: `[{"components": [{"name":"a","type":"int64"}, {"name":"b","type":"int256"}, {"name":"c","type":"int256"}, {"name":"d","type":"bool"}, - {"name":"e","type":"bytes32[3][2]"}]`, + {"name":"e","type":"bytes32[3][2]"}], "type":"tuple"}]`, unpacked: struct { A int64 B *big.Int @@ -855,21 +855,22 @@ var packUnpackTests = []packUnpackTest{ "0500000000000000000000000000000000000000000000000000000000000000", // struct[e] array[1][2] }, { - def: `[{"name":"a","type":"string"}, + def: `[{"components": [{"name":"a","type":"string"}, {"name":"b","type":"int64"}, {"name":"c","type":"bytes"}, {"name":"d","type":"string[]"}, {"name":"e","type":"int256[]"}, - {"name":"f","type":"address[]"}]`, + {"name":"f","type":"address[]"}], "type":"tuple"}]`, unpacked: struct { - FieldA string `abi:"a"` // Test whether abi tag works - FieldB int64 `abi:"b"` - C []byte - D []string - E []*big.Int - F []common.Address + A string + B int64 + C []byte + D []string + E []*big.Int + F []common.Address }{"foobar", 1, []byte{1}, []string{"foo", "bar"}, []*big.Int{big.NewInt(1), big.NewInt(-1)}, []common.Address{{1}, {2}}}, - packed: "00000000000000000000000000000000000000000000000000000000000000c0" + // struct[a] offset + packed: "0000000000000000000000000000000000000000000000000000000000000020" + // struct a + "00000000000000000000000000000000000000000000000000000000000000c0" + // struct[a] offset "0000000000000000000000000000000000000000000000000000000000000001" + // struct[b] "0000000000000000000000000000000000000000000000000000000000000100" + // struct[c] offset "0000000000000000000000000000000000000000000000000000000000000140" + // struct[d] offset @@ -894,23 +895,24 @@ var packUnpackTests = []packUnpackTest{ "0000000000000000000000000200000000000000000000000000000000000000", // common.Address{2} }, { - def: `[{"components": [{"name": "a","type": "uint256"}, + def: `[{"components": [{ "type": "tuple","components": [{"name": "a","type": "uint256"}, {"name": "b","type": "uint256[]"}], "name": "a","type": "tuple"}, - {"name": "b","type": "uint256[]"}]`, + {"name": "b","type": "uint256[]"}], "type": "tuple"}]`, unpacked: struct { A struct { - FieldA *big.Int `abi:"a"` - B []*big.Int + A *big.Int + B []*big.Int } B []*big.Int }{ A: struct { - FieldA *big.Int `abi:"a"` // Test whether abi tag works for nested tuple - B []*big.Int + A *big.Int + B []*big.Int }{big.NewInt(1), []*big.Int{big.NewInt(1), big.NewInt(2)}}, B: []*big.Int{big.NewInt(1), big.NewInt(2)}}, - packed: "0000000000000000000000000000000000000000000000000000000000000040" + // a offset + packed: "0000000000000000000000000000000000000000000000000000000000000020" + // struct a + "0000000000000000000000000000000000000000000000000000000000000040" + // a offset "00000000000000000000000000000000000000000000000000000000000000e0" + // b offset "0000000000000000000000000000000000000000000000000000000000000001" + // a.a value "0000000000000000000000000000000000000000000000000000000000000040" + // a.b offset diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 34a63f44d6..4a0274ed35 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -24,6 +24,29 @@ import ( "strings" ) +// ConvertType converts an interface of a runtime type into a interface of the +// given type +// e.g. turn +// var fields []reflect.StructField +// fields = append(fields, reflect.StructField{ +// Name: "X", +// Type: reflect.TypeOf(new(big.Int)), +// Tag: reflect.StructTag("json:\"" + "x" + "\""), +// } +// into +// type TupleT struct { X *big.Int } +func ConvertType(in interface{}, proto interface{}) interface{} { + protoType := reflect.TypeOf(proto) + if reflect.TypeOf(in).ConvertibleTo(protoType) { + return reflect.ValueOf(in).Convert(protoType).Interface() + } + // Use set as a last ditch effort + if err := set(reflect.ValueOf(proto), reflect.ValueOf(in)); err != nil { + panic(err) + } + return proto +} + // indirect recursively dereferences the value until it either gets the value // or finds a big.Int func indirect(v reflect.Value) reflect.Value { @@ -119,6 +142,9 @@ func setSlice(dst, src reflect.Value) error { } func setArray(dst, src reflect.Value) error { + if src.Kind() == reflect.Ptr { + return set(dst, indirect(src)) + } array := reflect.New(dst.Type()).Elem() min := src.Len() if src.Len() > dst.Len() { diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index c425e6e54b..bac4cd9530 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -17,6 +17,7 @@ package abi import ( + "math/big" "reflect" "testing" ) @@ -189,3 +190,72 @@ func TestReflectNameToStruct(t *testing.T) { }) } } + +func TestConvertType(t *testing.T) { + // Test Basic Struct + type T struct { + X *big.Int + Y *big.Int + } + // Create on-the-fly structure + var fields []reflect.StructField + fields = append(fields, reflect.StructField{ + Name: "X", + Type: reflect.TypeOf(new(big.Int)), + Tag: reflect.StructTag("json:\"" + "x" + "\""), + }) + fields = append(fields, reflect.StructField{ + Name: "Y", + Type: reflect.TypeOf(new(big.Int)), + Tag: reflect.StructTag("json:\"" + "y" + "\""), + }) + val := reflect.New(reflect.StructOf(fields)) + val.Elem().Field(0).Set(reflect.ValueOf(big.NewInt(1))) + val.Elem().Field(1).Set(reflect.ValueOf(big.NewInt(2))) + // ConvertType + out := *ConvertType(val.Interface(), new(T)).(*T) + if out.X.Cmp(big.NewInt(1)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out.X, big.NewInt(1)) + } + if out.Y.Cmp(big.NewInt(2)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out.Y, big.NewInt(2)) + } + // Slice Type + val2 := reflect.MakeSlice(reflect.SliceOf(reflect.StructOf(fields)), 2, 2) + val2.Index(0).Field(0).Set(reflect.ValueOf(big.NewInt(1))) + val2.Index(0).Field(1).Set(reflect.ValueOf(big.NewInt(2))) + val2.Index(1).Field(0).Set(reflect.ValueOf(big.NewInt(3))) + val2.Index(1).Field(1).Set(reflect.ValueOf(big.NewInt(4))) + out2 := *ConvertType(val2.Interface(), new([]T)).(*[]T) + if out2[0].X.Cmp(big.NewInt(1)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out2[0].X, big.NewInt(1)) + } + if out2[0].Y.Cmp(big.NewInt(2)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out2[1].Y, big.NewInt(2)) + } + if out2[1].X.Cmp(big.NewInt(3)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out2[0].X, big.NewInt(1)) + } + if out2[1].Y.Cmp(big.NewInt(4)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out2[1].Y, big.NewInt(2)) + } + // Array Type + val3 := reflect.New(reflect.ArrayOf(2, reflect.StructOf(fields))) + val3.Elem().Index(0).Field(0).Set(reflect.ValueOf(big.NewInt(1))) + val3.Elem().Index(0).Field(1).Set(reflect.ValueOf(big.NewInt(2))) + val3.Elem().Index(1).Field(0).Set(reflect.ValueOf(big.NewInt(3))) + val3.Elem().Index(1).Field(1).Set(reflect.ValueOf(big.NewInt(4))) + out3 := *ConvertType(val3.Interface(), new([2]T)).(*[2]T) + if out3[0].X.Cmp(big.NewInt(1)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out3[0].X, big.NewInt(1)) + } + if out3[0].Y.Cmp(big.NewInt(2)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out3[1].Y, big.NewInt(2)) + } + if out3[1].X.Cmp(big.NewInt(3)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out3[0].X, big.NewInt(1)) + } + if out3[1].Y.Cmp(big.NewInt(4)) != 0 { + t.Errorf("ConvertType failed, got %v want %v", out3[1].Y, big.NewInt(2)) + } +} diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index d51031442a..0524d5d3d3 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -44,15 +44,13 @@ func TestUnpack(t *testing.T) { if err != nil { t.Fatalf("invalid hex %s: %v", test.packed, err) } - outptr := reflect.New(reflect.TypeOf(test.unpacked)) - err = abi.Unpack(outptr.Interface(), "method", encb) + out, err := abi.Unpack("method", encb) if err != nil { t.Errorf("test %d (%v) failed: %v", i, test.def, err) return } - out := outptr.Elem().Interface() - if !reflect.DeepEqual(test.unpacked, out) { - t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.unpacked, out) + if !reflect.DeepEqual(test.unpacked, ConvertType(out[0], test.unpacked)) { + t.Errorf("test %d (%v) failed: expected %v, got %v", i, test.def, test.unpacked, out[0]) } }) } @@ -221,7 +219,7 @@ func TestLocalUnpackTests(t *testing.T) { t.Fatalf("invalid hex %s: %v", test.enc, err) } outptr := reflect.New(reflect.TypeOf(test.want)) - err = abi.Unpack(outptr.Interface(), "method", encb) + err = abi.UnpackIntoInterface(outptr.Interface(), "method", encb) if err := test.checkError(err); err != nil { t.Errorf("test %d (%v) failed: %v", i, test.def, err) return @@ -234,7 +232,7 @@ func TestLocalUnpackTests(t *testing.T) { } } -func TestUnpackSetDynamicArrayOutput(t *testing.T) { +func TestUnpackIntoInterfaceSetDynamicArrayOutput(t *testing.T) { abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`)) if err != nil { t.Fatal(err) @@ -249,7 +247,7 @@ func TestUnpackSetDynamicArrayOutput(t *testing.T) { ) // test 32 - err = abi.Unpack(&out32, "testDynamicFixedBytes32", marshalledReturn32) + err = abi.UnpackIntoInterface(&out32, "testDynamicFixedBytes32", marshalledReturn32) if err != nil { t.Fatal(err) } @@ -266,7 +264,7 @@ func TestUnpackSetDynamicArrayOutput(t *testing.T) { } // test 15 - err = abi.Unpack(&out15, "testDynamicFixedBytes32", marshalledReturn15) + err = abi.UnpackIntoInterface(&out15, "testDynamicFixedBytes32", marshalledReturn15) if err != nil { t.Fatal(err) } @@ -367,7 +365,7 @@ func TestMethodMultiReturn(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { require := require.New(t) - err := abi.Unpack(tc.dest, "multi", data) + err := abi.UnpackIntoInterface(tc.dest, "multi", data) if tc.error == "" { require.Nil(err, "Should be able to unpack method outputs.") require.Equal(tc.expected, tc.dest) @@ -390,7 +388,7 @@ func TestMultiReturnWithArray(t *testing.T) { ret1, ret1Exp := new([3]uint64), [3]uint64{9, 9, 9} ret2, ret2Exp := new(uint64), uint64(8) - if err := abi.Unpack(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { + if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { t.Fatal(err) } if !reflect.DeepEqual(*ret1, ret1Exp) { @@ -414,7 +412,7 @@ func TestMultiReturnWithStringArray(t *testing.T) { ret2, ret2Exp := new(common.Address), common.HexToAddress("ab1257528b3782fb40d7ed5f72e624b744dffb2f") ret3, ret3Exp := new([2]string), [2]string{"Ethereum", "Hello, Ethereum!"} ret4, ret4Exp := new(bool), false - if err := abi.Unpack(&[]interface{}{ret1, ret2, ret3, ret4}, "multi", buff.Bytes()); err != nil { + if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2, ret3, ret4}, "multi", buff.Bytes()); err != nil { t.Fatal(err) } if !reflect.DeepEqual(*ret1, ret1Exp) { @@ -452,7 +450,7 @@ func TestMultiReturnWithStringSlice(t *testing.T) { buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000065")) // output[1][1] value ret1, ret1Exp := new([]string), []string{"ethereum", "go-ethereum"} ret2, ret2Exp := new([]*big.Int), []*big.Int{big.NewInt(100), big.NewInt(101)} - if err := abi.Unpack(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { + if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { t.Fatal(err) } if !reflect.DeepEqual(*ret1, ret1Exp) { @@ -492,7 +490,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { {{0x411, 0x412, 0x413}, {0x421, 0x422, 0x423}}, } ret2, ret2Exp := new(uint64), uint64(0x9876) - if err := abi.Unpack(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { + if err := abi.UnpackIntoInterface(&[]interface{}{ret1, ret2}, "multi", buff.Bytes()); err != nil { t.Fatal(err) } if !reflect.DeepEqual(*ret1, ret1Exp) { @@ -531,7 +529,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000000a")) buff.Write(common.Hex2Bytes("0102000000000000000000000000000000000000000000000000000000000000")) - err = abi.Unpack(&mixedBytes, "mixedBytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&mixedBytes, "mixedBytes", buff.Bytes()) if err != nil { t.Error(err) } else { @@ -546,7 +544,7 @@ func TestUnmarshal(t *testing.T) { // marshal int var Int *big.Int - err = abi.Unpack(&Int, "int", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) + err = abi.UnpackIntoInterface(&Int, "int", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) if err != nil { t.Error(err) } @@ -557,7 +555,7 @@ func TestUnmarshal(t *testing.T) { // marshal bool var Bool bool - err = abi.Unpack(&Bool, "bool", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) + err = abi.UnpackIntoInterface(&Bool, "bool", common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001")) if err != nil { t.Error(err) } @@ -574,7 +572,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(bytesOut) var Bytes []byte - err = abi.Unpack(&Bytes, "bytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) if err != nil { t.Error(err) } @@ -590,7 +588,7 @@ func TestUnmarshal(t *testing.T) { bytesOut = common.RightPadBytes([]byte("hello"), 64) buff.Write(bytesOut) - err = abi.Unpack(&Bytes, "bytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) if err != nil { t.Error(err) } @@ -606,7 +604,7 @@ func TestUnmarshal(t *testing.T) { bytesOut = common.RightPadBytes([]byte("hello"), 64) buff.Write(bytesOut) - err = abi.Unpack(&Bytes, "bytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) if err != nil { t.Error(err) } @@ -616,7 +614,7 @@ func TestUnmarshal(t *testing.T) { } // marshal dynamic bytes output empty - err = abi.Unpack(&Bytes, "bytes", nil) + err = abi.UnpackIntoInterface(&Bytes, "bytes", nil) if err == nil { t.Error("expected error") } @@ -627,7 +625,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000005")) buff.Write(common.RightPadBytes([]byte("hello"), 32)) - err = abi.Unpack(&Bytes, "bytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) if err != nil { t.Error(err) } @@ -641,7 +639,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(common.RightPadBytes([]byte("hello"), 32)) var hash common.Hash - err = abi.Unpack(&hash, "fixed", buff.Bytes()) + err = abi.UnpackIntoInterface(&hash, "fixed", buff.Bytes()) if err != nil { t.Error(err) } @@ -654,12 +652,12 @@ func TestUnmarshal(t *testing.T) { // marshal error buff.Reset() buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000020")) - err = abi.Unpack(&Bytes, "bytes", buff.Bytes()) + err = abi.UnpackIntoInterface(&Bytes, "bytes", buff.Bytes()) if err == nil { t.Error("expected error") } - err = abi.Unpack(&Bytes, "multi", make([]byte, 64)) + err = abi.UnpackIntoInterface(&Bytes, "multi", make([]byte, 64)) if err == nil { t.Error("expected error") } @@ -670,7 +668,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000003")) // marshal int array var intArray [3]*big.Int - err = abi.Unpack(&intArray, "intArraySingle", buff.Bytes()) + err = abi.UnpackIntoInterface(&intArray, "intArraySingle", buff.Bytes()) if err != nil { t.Error(err) } @@ -691,7 +689,7 @@ func TestUnmarshal(t *testing.T) { buff.Write(common.Hex2Bytes("0000000000000000000000000100000000000000000000000000000000000000")) var outAddr []common.Address - err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes()) + err = abi.UnpackIntoInterface(&outAddr, "addressSliceSingle", buff.Bytes()) if err != nil { t.Fatal("didn't expect error:", err) } @@ -718,7 +716,7 @@ func TestUnmarshal(t *testing.T) { A []common.Address B []common.Address } - err = abi.Unpack(&outAddrStruct, "addressSliceDouble", buff.Bytes()) + err = abi.UnpackIntoInterface(&outAddrStruct, "addressSliceDouble", buff.Bytes()) if err != nil { t.Fatal("didn't expect error:", err) } @@ -746,7 +744,7 @@ func TestUnmarshal(t *testing.T) { buff.Reset() buff.Write(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000100")) - err = abi.Unpack(&outAddr, "addressSliceSingle", buff.Bytes()) + err = abi.UnpackIntoInterface(&outAddr, "addressSliceSingle", buff.Bytes()) if err == nil { t.Fatal("expected error:", err) } @@ -769,7 +767,7 @@ func TestUnpackTuple(t *testing.T) { B *big.Int }{new(big.Int), new(big.Int)} - err = abi.Unpack(&v, "tuple", buff.Bytes()) + err = abi.UnpackIntoInterface(&v, "tuple", buff.Bytes()) if err != nil { t.Error(err) } else { @@ -841,7 +839,7 @@ func TestUnpackTuple(t *testing.T) { A: big.NewInt(1), } - err = abi.Unpack(&ret, "tuple", buff.Bytes()) + err = abi.UnpackIntoInterface(&ret, "tuple", buff.Bytes()) if err != nil { t.Error(err) } diff --git a/contracts/XDCx/contract/LendingRegistration.go b/contracts/XDCx/contract/LendingRegistration.go index 85001120a1..038af5643c 100644 --- a/contracts/XDCx/contract/LendingRegistration.go +++ b/contracts/XDCx/contract/LendingRegistration.go @@ -140,7 +140,7 @@ func bindLAbstractRegistration(address common.Address, caller bind.ContractCalle // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractRegistration *LAbstractRegistrationRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractRegistration *LAbstractRegistrationRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractRegistration.Contract.LAbstractRegistrationCaller.contract.Call(opts, result, method, params...) } @@ -159,7 +159,7 @@ func (_LAbstractRegistration *LAbstractRegistrationRaw) Transact(opts *bind.Tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractRegistration *LAbstractRegistrationCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractRegistration *LAbstractRegistrationCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractRegistration.Contract.contract.Call(opts, result, method, params...) } @@ -181,7 +181,9 @@ func (_LAbstractRegistration *LAbstractRegistrationCaller) RESIGNREQUESTS(opts * var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _LAbstractRegistration.contract.Call(opts, out, "RESIGN_REQUESTS", arg0) return *ret0, err } @@ -365,7 +367,7 @@ func bindLAbstractXDCXListing(address common.Address, caller bind.ContractCaller // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractXDCXListing.Contract.LAbstractXDCXListingCaller.contract.Call(opts, result, method, params...) } @@ -384,7 +386,7 @@ func (_LAbstractXDCXListing *LAbstractXDCXListingRaw) Transact(opts *bind.Transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractXDCXListing *LAbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractXDCXListing *LAbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractXDCXListing.Contract.contract.Call(opts, result, method, params...) } @@ -406,7 +408,9 @@ func (_LAbstractXDCXListing *LAbstractXDCXListingCaller) GetTokenStatus(opts *bi var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _LAbstractXDCXListing.contract.Call(opts, out, "getTokenStatus", arg0) return *ret0, err } @@ -552,7 +556,7 @@ func bindLAbstractTokenTRC21(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractTokenTRC21.Contract.LAbstractTokenTRC21Caller.contract.Call(opts, result, method, params...) } @@ -571,7 +575,7 @@ func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Raw) Transact(opts *bind.Transact // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_LAbstractTokenTRC21 *LAbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_LAbstractTokenTRC21 *LAbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _LAbstractTokenTRC21.Contract.contract.Call(opts, result, method, params...) } @@ -593,7 +597,9 @@ func (_LAbstractTokenTRC21 *LAbstractTokenTRC21Caller) Issuer(opts *bind.CallOpt var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _LAbstractTokenTRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -739,7 +745,7 @@ func bindLending(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Lending *LendingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Lending *LendingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Lending.Contract.LendingCaller.contract.Call(opts, result, method, params...) } @@ -758,7 +764,7 @@ func (_Lending *LendingRaw) Transact(opts *bind.TransactOpts, method string, par // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Lending *LendingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Lending *LendingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Lending.Contract.contract.Call(opts, result, method, params...) } @@ -780,7 +786,9 @@ func (_Lending *LendingCaller) BASES(opts *bind.CallOpts, arg0 *big.Int) (common var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "BASES", arg0) return *ret0, err } @@ -806,7 +814,9 @@ func (_Lending *LendingCaller) COLLATERALS(opts *bind.CallOpts, arg0 *big.Int) ( var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "COLLATERALS", arg0) return *ret0, err } @@ -838,7 +848,9 @@ func (_Lending *LendingCaller) COLLATERALLIST(opts *bind.CallOpts, arg0 common.A LiquidationRate *big.Int RecallRate *big.Int }) - out := ret + out := &[]interface{}{ + ret, + } err := _Lending.contract.Call(opts, out, "COLLATERAL_LIST", arg0) return *ret, err } @@ -872,7 +884,9 @@ func (_Lending *LendingCaller) ILOCOLLATERALS(opts *bind.CallOpts, arg0 *big.Int var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "ILO_COLLATERALS", arg0) return *ret0, err } @@ -898,7 +912,9 @@ func (_Lending *LendingCaller) LENDINGRELAYERLIST(opts *bind.CallOpts, arg0 comm var ( ret0 = new(uint16) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "LENDINGRELAYER_LIST", arg0) return *ret0, err } @@ -924,7 +940,9 @@ func (_Lending *LendingCaller) MODERATOR(opts *bind.CallOpts) (common.Address, e var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "MODERATOR") return *ret0, err } @@ -950,7 +968,9 @@ func (_Lending *LendingCaller) ORACLEPRICEFEEDER(opts *bind.CallOpts) (common.Ad var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "ORACLE_PRICE_FEEDER") return *ret0, err } @@ -976,7 +996,9 @@ func (_Lending *LendingCaller) Relayer(opts *bind.CallOpts) (common.Address, err var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "Relayer") return *ret0, err } @@ -1002,7 +1024,9 @@ func (_Lending *LendingCaller) TERMS(opts *bind.CallOpts, arg0 *big.Int) (*big.I var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "TERMS", arg0) return *ret0, err } @@ -1028,7 +1052,9 @@ func (_Lending *LendingCaller) XDCXListing(opts *bind.CallOpts) (common.Address, var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _Lending.contract.Call(opts, out, "XDCXListing") return *ret0, err } diff --git a/contracts/XDCx/contract/Registration.go b/contracts/XDCx/contract/Registration.go index ac1fb78889..827cd45574 100644 --- a/contracts/XDCx/contract/Registration.go +++ b/contracts/XDCx/contract/Registration.go @@ -142,7 +142,7 @@ func bindAbstractXDCXListing(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractXDCXListing *AbstractXDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractXDCXListing *AbstractXDCXListingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractXDCXListing.Contract.AbstractXDCXListingCaller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_AbstractXDCXListing *AbstractXDCXListingRaw) Transact(opts *bind.Transact // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractXDCXListing *AbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractXDCXListing *AbstractXDCXListingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractXDCXListing.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_AbstractXDCXListing *AbstractXDCXListingCaller) GetTokenStatus(opts *bind var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _AbstractXDCXListing.contract.Call(opts, out, "getTokenStatus", arg0) return *ret0, err } @@ -329,7 +331,7 @@ func bindRelayerRegistration(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_RelayerRegistration *RelayerRegistrationRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_RelayerRegistration *RelayerRegistrationRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _RelayerRegistration.Contract.RelayerRegistrationCaller.contract.Call(opts, result, method, params...) } @@ -348,7 +350,7 @@ func (_RelayerRegistration *RelayerRegistrationRaw) Transact(opts *bind.Transact // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_RelayerRegistration *RelayerRegistrationCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_RelayerRegistration *RelayerRegistrationCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _RelayerRegistration.Contract.contract.Call(opts, result, method, params...) } @@ -370,7 +372,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) ActiveRelayerCount(opts * var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "ActiveRelayerCount") return *ret0, err } @@ -396,7 +400,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) CONTRACTOWNER(opts *bind. var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "CONTRACT_OWNER") return *ret0, err } @@ -422,7 +428,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) MaximumRelayers(opts *bin var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "MaximumRelayers") return *ret0, err } @@ -448,7 +456,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) MaximumTokenList(opts *bi var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "MaximumTokenList") return *ret0, err } @@ -474,7 +484,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) MinimumDeposit(opts *bind var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "MinimumDeposit") return *ret0, err } @@ -500,7 +512,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERCOINBASES(opts *bi var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_COINBASES", arg0) return *ret0, err } @@ -534,7 +548,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERLIST(opts *bind.Ca Index *big.Int Owner common.Address }) - out := ret + out := &[]interface{}{ + ret, + } err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_LIST", arg0) return *ret, err } @@ -570,7 +586,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) RELAYERONSALELIST(opts *b var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "RELAYER_ON_SALE_LIST", arg0) return *ret0, err } @@ -596,7 +614,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) RESIGNREQUESTS(opts *bind var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "RESIGN_REQUESTS", arg0) return *ret0, err } @@ -622,7 +642,9 @@ func (_RelayerRegistration *RelayerRegistrationCaller) RelayerCount(opts *bind.C var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _RelayerRegistration.contract.Call(opts, out, "RelayerCount") return *ret0, err } @@ -2218,7 +2240,7 @@ func bindSafeMath(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.SafeMathCaller.contract.Call(opts, result, method, params...) } @@ -2237,7 +2259,7 @@ func (_SafeMath *SafeMathRaw) Transact(opts *bind.TransactOpts, method string, p // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.contract.Call(opts, result, method, params...) } diff --git a/contracts/XDCx/contract/TRC21.go b/contracts/XDCx/contract/TRC21.go index 5000083231..68974fe842 100644 --- a/contracts/XDCx/contract/TRC21.go +++ b/contracts/XDCx/contract/TRC21.go @@ -142,7 +142,7 @@ func bindITRC21(address common.Address, caller bind.ContractCaller, transactor b // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ITRC21 *ITRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_ITRC21 *ITRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _ITRC21.Contract.ITRC21Caller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_ITRC21 *ITRC21Raw) Transact(opts *bind.TransactOpts, method string, param // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ITRC21 *ITRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_ITRC21 *ITRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _ITRC21.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_ITRC21 *ITRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -209,7 +211,9 @@ func (_ITRC21 *ITRC21Caller) BalanceOf(opts *bind.CallOpts, who common.Address) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "balanceOf", who) return *ret0, err } @@ -235,7 +239,9 @@ func (_ITRC21 *ITRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) { var ( ret0 = new(uint8) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "decimals") return *ret0, err } @@ -261,7 +267,9 @@ func (_ITRC21 *ITRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (* var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -287,7 +295,9 @@ func (_ITRC21 *ITRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -313,7 +323,9 @@ func (_ITRC21 *ITRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } @@ -957,7 +969,7 @@ func bindMyTRC21(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MyTRC21 *MyTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MyTRC21 *MyTRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MyTRC21.Contract.MyTRC21Caller.contract.Call(opts, result, method, params...) } @@ -976,7 +988,7 @@ func (_MyTRC21 *MyTRC21Raw) Transact(opts *bind.TransactOpts, method string, par // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MyTRC21 *MyTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MyTRC21 *MyTRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MyTRC21.Contract.contract.Call(opts, result, method, params...) } @@ -998,7 +1010,9 @@ func (_MyTRC21 *MyTRC21Caller) DEPOSITFEE(opts *bind.CallOpts) (*big.Int, error) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "DEPOSIT_FEE") return *ret0, err } @@ -1024,7 +1038,9 @@ func (_MyTRC21 *MyTRC21Caller) MAXOWNERCOUNT(opts *bind.CallOpts) (*big.Int, err var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "MAX_OWNER_COUNT") return *ret0, err } @@ -1050,7 +1066,9 @@ func (_MyTRC21 *MyTRC21Caller) WITHDRAWFEE(opts *bind.CallOpts) (*big.Int, error var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "WITHDRAW_FEE") return *ret0, err } @@ -1076,7 +1094,9 @@ func (_MyTRC21 *MyTRC21Caller) Allowance(opts *bind.CallOpts, owner common.Addre var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -1102,7 +1122,9 @@ func (_MyTRC21 *MyTRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Addre var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "balanceOf", owner) return *ret0, err } @@ -1134,7 +1156,9 @@ func (_MyTRC21 *MyTRC21Caller) BurnList(opts *bind.CallOpts, arg0 *big.Int) (str Burner common.Address Data []byte }) - out := ret + out := &[]interface{}{ + ret, + } err := _MyTRC21.contract.Call(opts, out, "burnList", arg0) return *ret, err } @@ -1168,7 +1192,9 @@ func (_MyTRC21 *MyTRC21Caller) Confirmations(opts *bind.CallOpts, arg0 *big.Int, var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "confirmations", arg0, arg1) return *ret0, err } @@ -1194,7 +1220,9 @@ func (_MyTRC21 *MyTRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) { var ( ret0 = new(uint8) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "decimals") return *ret0, err } @@ -1220,7 +1248,9 @@ func (_MyTRC21 *MyTRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -1252,7 +1282,9 @@ func (_MyTRC21 *MyTRC21Caller) GetBurn(opts *bind.CallOpts, burnId *big.Int) (st Value *big.Int Data []byte }) - out := ret + out := &[]interface{}{ + ret, + } err := _MyTRC21.contract.Call(opts, out, "getBurn", burnId) return *ret, err } @@ -1286,7 +1318,9 @@ func (_MyTRC21 *MyTRC21Caller) GetBurnCount(opts *bind.CallOpts) (*big.Int, erro var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getBurnCount") return *ret0, err } @@ -1312,7 +1346,9 @@ func (_MyTRC21 *MyTRC21Caller) GetConfirmationCount(opts *bind.CallOpts, transac var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getConfirmationCount", transactionId) return *ret0, err } @@ -1338,7 +1374,9 @@ func (_MyTRC21 *MyTRC21Caller) GetConfirmations(opts *bind.CallOpts, transaction var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getConfirmations", transactionId) return *ret0, err } @@ -1364,7 +1402,9 @@ func (_MyTRC21 *MyTRC21Caller) GetOwners(opts *bind.CallOpts) ([]common.Address, var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getOwners") return *ret0, err } @@ -1390,7 +1430,9 @@ func (_MyTRC21 *MyTRC21Caller) GetTransactionCount(opts *bind.CallOpts, pending var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getTransactionCount", pending, executed) return *ret0, err } @@ -1416,7 +1458,9 @@ func (_MyTRC21 *MyTRC21Caller) GetTransactionIds(opts *bind.CallOpts, from *big. var ( ret0 = new([]*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "getTransactionIds", from, to, pending, executed) return *ret0, err } @@ -1442,7 +1486,9 @@ func (_MyTRC21 *MyTRC21Caller) IsConfirmed(opts *bind.CallOpts, transactionId *b var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "isConfirmed", transactionId) return *ret0, err } @@ -1468,7 +1514,9 @@ func (_MyTRC21 *MyTRC21Caller) IsOwner(opts *bind.CallOpts, arg0 common.Address) var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "isOwner", arg0) return *ret0, err } @@ -1494,7 +1542,9 @@ func (_MyTRC21 *MyTRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, erro var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -1520,7 +1570,9 @@ func (_MyTRC21 *MyTRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "minFee") return *ret0, err } @@ -1546,7 +1598,9 @@ func (_MyTRC21 *MyTRC21Caller) Name(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "name") return *ret0, err } @@ -1572,7 +1626,9 @@ func (_MyTRC21 *MyTRC21Caller) Owners(opts *bind.CallOpts, arg0 *big.Int) (commo var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "owners", arg0) return *ret0, err } @@ -1598,7 +1654,9 @@ func (_MyTRC21 *MyTRC21Caller) Required(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "required") return *ret0, err } @@ -1624,7 +1682,9 @@ func (_MyTRC21 *MyTRC21Caller) Symbol(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "symbol") return *ret0, err } @@ -1650,7 +1710,9 @@ func (_MyTRC21 *MyTRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } @@ -1676,7 +1738,9 @@ func (_MyTRC21 *MyTRC21Caller) TransactionCount(opts *bind.CallOpts) (*big.Int, var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "transactionCount") return *ret0, err } @@ -1710,7 +1774,9 @@ func (_MyTRC21 *MyTRC21Caller) Transactions(opts *bind.CallOpts, arg0 *big.Int) Data []byte Executed bool }) - out := ret + out := &[]interface{}{ + ret, + } err := _MyTRC21.contract.Call(opts, out, "transactions", arg0) return *ret, err } @@ -3844,7 +3910,7 @@ func bindTRC21(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21 *TRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21 *TRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21.Contract.TRC21Caller.contract.Call(opts, result, method, params...) } @@ -3863,7 +3929,7 @@ func (_TRC21 *TRC21Raw) Transact(opts *bind.TransactOpts, method string, params // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21 *TRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21 *TRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21.Contract.contract.Call(opts, result, method, params...) } @@ -3885,7 +3951,9 @@ func (_TRC21 *TRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address, var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -3911,7 +3979,9 @@ func (_TRC21 *TRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Address) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "balanceOf", owner) return *ret0, err } @@ -3937,7 +4007,9 @@ func (_TRC21 *TRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) { var ( ret0 = new(uint8) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "decimals") return *ret0, err } @@ -3963,7 +4035,9 @@ func (_TRC21 *TRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (*bi var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -3989,7 +4063,9 @@ func (_TRC21 *TRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) { var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -4015,7 +4091,9 @@ func (_TRC21 *TRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "minFee") return *ret0, err } @@ -4041,7 +4119,9 @@ func (_TRC21 *TRC21Caller) Name(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "name") return *ret0, err } @@ -4067,7 +4147,9 @@ func (_TRC21 *TRC21Caller) Symbol(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "symbol") return *ret0, err } @@ -4093,7 +4175,9 @@ func (_TRC21 *TRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } diff --git a/contracts/XDCx/contract/TRC21Issuer.go b/contracts/XDCx/contract/TRC21Issuer.go index 72c7f3a2d8..bc5bf9a296 100644 --- a/contracts/XDCx/contract/TRC21Issuer.go +++ b/contracts/XDCx/contract/TRC21Issuer.go @@ -141,7 +141,7 @@ func bindAbstractTokenTRC21(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractTokenTRC21.Contract.AbstractTokenTRC21Caller.contract.Call(opts, result, method, params...) } @@ -160,7 +160,7 @@ func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Transact(opts *bind.TransactOp // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractTokenTRC21.Contract.contract.Call(opts, result, method, params...) } @@ -182,7 +182,9 @@ func (_AbstractTokenTRC21 *AbstractTokenTRC21Caller) Issuer(opts *bind.CallOpts) var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _AbstractTokenTRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -328,7 +330,7 @@ func bindTRC21Issuer(address common.Address, caller bind.ContractCaller, transac // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21Issuer *TRC21IssuerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21Issuer *TRC21IssuerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21Issuer.Contract.TRC21IssuerCaller.contract.Call(opts, result, method, params...) } @@ -347,7 +349,7 @@ func (_TRC21Issuer *TRC21IssuerRaw) Transact(opts *bind.TransactOpts, method str // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21Issuer *TRC21IssuerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21Issuer *TRC21IssuerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21Issuer.Contract.contract.Call(opts, result, method, params...) } @@ -369,7 +371,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) GetTokenCapacity(opts *bind.CallOpts, tok var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "getTokenCapacity", token) return *ret0, err } @@ -395,7 +399,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) MinCap(opts *bind.CallOpts) (*big.Int, er var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "minCap") return *ret0, err } @@ -421,7 +427,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) Tokens(opts *bind.CallOpts) ([]common.Add var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "tokens") return *ret0, err } diff --git a/contracts/XDCx/contract/XDCXListing.go b/contracts/XDCx/contract/XDCXListing.go index 1b017c7b01..e0a336ab9a 100644 --- a/contracts/XDCx/contract/XDCXListing.go +++ b/contracts/XDCx/contract/XDCXListing.go @@ -139,7 +139,7 @@ func bindXDCXListing(address common.Address, caller bind.ContractCaller, transac // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCXListing *XDCXListingRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCXListing *XDCXListingRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCXListing.Contract.XDCXListingCaller.contract.Call(opts, result, method, params...) } @@ -158,7 +158,7 @@ func (_XDCXListing *XDCXListingRaw) Transact(opts *bind.TransactOpts, method str // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCXListing *XDCXListingCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCXListing *XDCXListingCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCXListing.Contract.contract.Call(opts, result, method, params...) } @@ -180,7 +180,9 @@ func (_XDCXListing *XDCXListingCaller) GetTokenStatus(opts *bind.CallOpts, token var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCXListing.contract.Call(opts, out, "getTokenStatus", token) return *ret0, err } @@ -206,7 +208,9 @@ func (_XDCXListing *XDCXListingCaller) Tokens(opts *bind.CallOpts) ([]common.Add var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCXListing.contract.Call(opts, out, "tokens") return *ret0, err } diff --git a/contracts/blocksigner/contract/blocksigner.go b/contracts/blocksigner/contract/blocksigner.go index 4a5b8d15d6..4434d232bf 100644 --- a/contracts/blocksigner/contract/blocksigner.go +++ b/contracts/blocksigner/contract/blocksigner.go @@ -142,7 +142,7 @@ func bindBlockSigner(address common.Address, caller bind.ContractCaller, transac // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_BlockSigner *BlockSignerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_BlockSigner *BlockSignerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _BlockSigner.Contract.BlockSignerCaller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_BlockSigner *BlockSignerRaw) Transact(opts *bind.TransactOpts, method str // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_BlockSigner *BlockSignerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_BlockSigner *BlockSignerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _BlockSigner.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_BlockSigner *BlockSignerCaller) EpochNumber(opts *bind.CallOpts) (*big.In var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _BlockSigner.contract.Call(opts, out, "epochNumber") return *ret0, err } @@ -209,7 +211,9 @@ func (_BlockSigner *BlockSignerCaller) GetSigners(opts *bind.CallOpts, _blockHas var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _BlockSigner.contract.Call(opts, out, "getSigners", _blockHash) return *ret0, err } @@ -500,7 +504,7 @@ func bindSafeMath(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.SafeMathCaller.contract.Call(opts, result, method, params...) } @@ -519,7 +523,7 @@ func (_SafeMath *SafeMathRaw) Transact(opts *bind.TransactOpts, method string, p // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.contract.Call(opts, result, method, params...) } diff --git a/contracts/multisigwallet/contract/multisigwallet.go b/contracts/multisigwallet/contract/multisigwallet.go index f73bc09424..6be6bda9f8 100644 --- a/contracts/multisigwallet/contract/multisigwallet.go +++ b/contracts/multisigwallet/contract/multisigwallet.go @@ -142,7 +142,7 @@ func bindMultiSigWallet(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MultiSigWallet *MultiSigWalletRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MultiSigWallet *MultiSigWalletRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MultiSigWallet.Contract.MultiSigWalletCaller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_MultiSigWallet *MultiSigWalletRaw) Transact(opts *bind.TransactOpts, meth // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MultiSigWallet *MultiSigWalletCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MultiSigWallet *MultiSigWalletCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MultiSigWallet.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) MAXOWNERCOUNT(opts *bind.CallOpts) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "MAX_OWNER_COUNT") return *ret0, err } @@ -209,7 +211,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) Confirmations(opts *bind.CallOpts, var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "confirmations", arg0, arg1) return *ret0, err } @@ -235,7 +239,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) GetConfirmationCount(opts *bind.Cal var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "getConfirmationCount", transactionId) return *ret0, err } @@ -261,7 +267,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) GetConfirmations(opts *bind.CallOpt var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "getConfirmations", transactionId) return *ret0, err } @@ -287,7 +295,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) GetOwners(opts *bind.CallOpts) ([]c var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "getOwners") return *ret0, err } @@ -313,7 +323,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) GetTransactionCount(opts *bind.Call var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "getTransactionCount", pending, executed) return *ret0, err } @@ -339,7 +351,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) GetTransactionIds(opts *bind.CallOp var ( ret0 = new([]*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "getTransactionIds", from, to, pending, executed) return *ret0, err } @@ -365,7 +379,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) IsConfirmed(opts *bind.CallOpts, tr var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "isConfirmed", transactionId) return *ret0, err } @@ -391,7 +407,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) IsOwner(opts *bind.CallOpts, arg0 c var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "isOwner", arg0) return *ret0, err } @@ -417,7 +435,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) Owners(opts *bind.CallOpts, arg0 *b var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "owners", arg0) return *ret0, err } @@ -443,7 +463,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) Required(opts *bind.CallOpts) (*big var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "required") return *ret0, err } @@ -469,7 +491,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) TransactionCount(opts *bind.CallOpt var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MultiSigWallet.contract.Call(opts, out, "transactionCount") return *ret0, err } @@ -503,7 +527,9 @@ func (_MultiSigWallet *MultiSigWalletCaller) Transactions(opts *bind.CallOpts, a Data []byte Executed bool }) - out := ret + out := &[]interface{}{ + ret, + } err := _MultiSigWallet.contract.Call(opts, out, "transactions", arg0) return *ret, err } diff --git a/contracts/randomize/contract/randomize.go b/contracts/randomize/contract/randomize.go index 92c3f71c35..d3d9288a7c 100644 --- a/contracts/randomize/contract/randomize.go +++ b/contracts/randomize/contract/randomize.go @@ -139,7 +139,7 @@ func bindSafeMath(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.SafeMathCaller.contract.Call(opts, result, method, params...) } @@ -158,7 +158,7 @@ func (_SafeMath *SafeMathRaw) Transact(opts *bind.TransactOpts, method string, p // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.contract.Call(opts, result, method, params...) } @@ -300,7 +300,7 @@ func bindXDCRandomize(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCRandomize *XDCRandomizeRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCRandomize *XDCRandomizeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCRandomize.Contract.XDCRandomizeCaller.contract.Call(opts, result, method, params...) } @@ -319,7 +319,7 @@ func (_XDCRandomize *XDCRandomizeRaw) Transact(opts *bind.TransactOpts, method s // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCRandomize *XDCRandomizeCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCRandomize *XDCRandomizeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCRandomize.Contract.contract.Call(opts, result, method, params...) } @@ -341,7 +341,9 @@ func (_XDCRandomize *XDCRandomizeCaller) GetOpening(opts *bind.CallOpts, _valida var ( ret0 = new([32]byte) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCRandomize.contract.Call(opts, out, "getOpening", _validator) return *ret0, err } @@ -367,7 +369,9 @@ func (_XDCRandomize *XDCRandomizeCaller) GetSecret(opts *bind.CallOpts, _validat var ( ret0 = new([][32]byte) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCRandomize.contract.Call(opts, out, "getSecret", _validator) return *ret0, err } diff --git a/contracts/tests/contract/Inherited.go b/contracts/tests/contract/Inherited.go index 71b3929ed2..84a37e6c0b 100644 --- a/contracts/tests/contract/Inherited.go +++ b/contracts/tests/contract/Inherited.go @@ -139,7 +139,7 @@ func bindBase1(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Base1 *Base1Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Base1 *Base1Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Base1.Contract.Base1Caller.contract.Call(opts, result, method, params...) } @@ -158,7 +158,7 @@ func (_Base1 *Base1Raw) Transact(opts *bind.TransactOpts, method string, params // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Base1 *Base1CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Base1 *Base1CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Base1.Contract.contract.Call(opts, result, method, params...) } @@ -321,7 +321,7 @@ func bindBase2(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Base2 *Base2Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Base2 *Base2Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Base2.Contract.Base2Caller.contract.Call(opts, result, method, params...) } @@ -340,7 +340,7 @@ func (_Base2 *Base2Raw) Transact(opts *bind.TransactOpts, method string, params // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Base2 *Base2CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Base2 *Base2CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Base2.Contract.contract.Call(opts, result, method, params...) } @@ -503,7 +503,7 @@ func bindInherited(address common.Address, caller bind.ContractCaller, transacto // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Inherited *InheritedRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Inherited *InheritedRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Inherited.Contract.InheritedCaller.contract.Call(opts, result, method, params...) } @@ -522,7 +522,7 @@ func (_Inherited *InheritedRaw) Transact(opts *bind.TransactOpts, method string, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Inherited *InheritedCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_Inherited *InheritedCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _Inherited.Contract.contract.Call(opts, result, method, params...) } diff --git a/contracts/trc21issuer/contract/TRC21.go b/contracts/trc21issuer/contract/TRC21.go index f24bb3c3a5..0740d67c76 100644 --- a/contracts/trc21issuer/contract/TRC21.go +++ b/contracts/trc21issuer/contract/TRC21.go @@ -142,7 +142,7 @@ func bindITRC21(address common.Address, caller bind.ContractCaller, transactor b // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ITRC21 *ITRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_ITRC21 *ITRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _ITRC21.Contract.ITRC21Caller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_ITRC21 *ITRC21Raw) Transact(opts *bind.TransactOpts, method string, param // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ITRC21 *ITRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_ITRC21 *ITRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _ITRC21.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_ITRC21 *ITRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -209,7 +211,9 @@ func (_ITRC21 *ITRC21Caller) BalanceOf(opts *bind.CallOpts, who common.Address) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "balanceOf", who) return *ret0, err } @@ -235,7 +239,9 @@ func (_ITRC21 *ITRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (* var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -261,7 +267,9 @@ func (_ITRC21 *ITRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _ITRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } @@ -905,7 +913,7 @@ func bindMyTRC21(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MyTRC21 *MyTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MyTRC21 *MyTRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MyTRC21.Contract.MyTRC21Caller.contract.Call(opts, result, method, params...) } @@ -924,7 +932,7 @@ func (_MyTRC21 *MyTRC21Raw) Transact(opts *bind.TransactOpts, method string, par // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MyTRC21 *MyTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_MyTRC21 *MyTRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _MyTRC21.Contract.contract.Call(opts, result, method, params...) } @@ -946,7 +954,9 @@ func (_MyTRC21 *MyTRC21Caller) Allowance(opts *bind.CallOpts, owner common.Addre var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -972,7 +982,9 @@ func (_MyTRC21 *MyTRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Addre var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "balanceOf", owner) return *ret0, err } @@ -998,7 +1010,9 @@ func (_MyTRC21 *MyTRC21Caller) Decimals(opts *bind.CallOpts) (uint8, error) { var ( ret0 = new(uint8) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "decimals") return *ret0, err } @@ -1024,7 +1038,9 @@ func (_MyTRC21 *MyTRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -1050,7 +1066,9 @@ func (_MyTRC21 *MyTRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, erro var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -1076,7 +1094,9 @@ func (_MyTRC21 *MyTRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "minFee") return *ret0, err } @@ -1102,7 +1122,9 @@ func (_MyTRC21 *MyTRC21Caller) Name(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "name") return *ret0, err } @@ -1128,7 +1150,9 @@ func (_MyTRC21 *MyTRC21Caller) Symbol(opts *bind.CallOpts) (string, error) { var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "symbol") return *ret0, err } @@ -1154,7 +1178,9 @@ func (_MyTRC21 *MyTRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _MyTRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } @@ -1798,7 +1824,7 @@ func bindTRC21(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21 *TRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21 *TRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21.Contract.TRC21Caller.contract.Call(opts, result, method, params...) } @@ -1817,7 +1843,7 @@ func (_TRC21 *TRC21Raw) Transact(opts *bind.TransactOpts, method string, params // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21 *TRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21 *TRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21.Contract.contract.Call(opts, result, method, params...) } @@ -1839,7 +1865,9 @@ func (_TRC21 *TRC21Caller) Allowance(opts *bind.CallOpts, owner common.Address, var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "allowance", owner, spender) return *ret0, err } @@ -1865,7 +1893,9 @@ func (_TRC21 *TRC21Caller) BalanceOf(opts *bind.CallOpts, owner common.Address) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "balanceOf", owner) return *ret0, err } @@ -1891,7 +1921,9 @@ func (_TRC21 *TRC21Caller) EstimateFee(opts *bind.CallOpts, value *big.Int) (*bi var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "estimateFee", value) return *ret0, err } @@ -1917,7 +1949,9 @@ func (_TRC21 *TRC21Caller) Issuer(opts *bind.CallOpts) (common.Address, error) { var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -1943,7 +1977,9 @@ func (_TRC21 *TRC21Caller) MinFee(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "minFee") return *ret0, err } @@ -1969,7 +2005,9 @@ func (_TRC21 *TRC21Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21.contract.Call(opts, out, "totalSupply") return *ret0, err } diff --git a/contracts/trc21issuer/contract/TRC21Issuer.go b/contracts/trc21issuer/contract/TRC21Issuer.go index b5e584a5df..aa618bb2fd 100644 --- a/contracts/trc21issuer/contract/TRC21Issuer.go +++ b/contracts/trc21issuer/contract/TRC21Issuer.go @@ -142,7 +142,7 @@ func bindAbstractTokenTRC21(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractTokenTRC21.Contract.AbstractTokenTRC21Caller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_AbstractTokenTRC21 *AbstractTokenTRC21Raw) Transact(opts *bind.TransactOp // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_AbstractTokenTRC21 *AbstractTokenTRC21CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _AbstractTokenTRC21.Contract.contract.Call(opts, result, method, params...) } @@ -183,7 +183,9 @@ func (_AbstractTokenTRC21 *AbstractTokenTRC21Caller) Issuer(opts *bind.CallOpts) var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _AbstractTokenTRC21.contract.Call(opts, out, "issuer") return *ret0, err } @@ -329,7 +331,7 @@ func bindTRC21Issuer(address common.Address, caller bind.ContractCaller, transac // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21Issuer *TRC21IssuerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21Issuer *TRC21IssuerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21Issuer.Contract.TRC21IssuerCaller.contract.Call(opts, result, method, params...) } @@ -348,7 +350,7 @@ func (_TRC21Issuer *TRC21IssuerRaw) Transact(opts *bind.TransactOpts, method str // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TRC21Issuer *TRC21IssuerCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_TRC21Issuer *TRC21IssuerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _TRC21Issuer.Contract.contract.Call(opts, result, method, params...) } @@ -370,7 +372,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) GetTokenCapacity(opts *bind.CallOpts, tok var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "getTokenCapacity", token) return *ret0, err } @@ -396,7 +400,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) MinCap(opts *bind.CallOpts) (*big.Int, er var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "minCap") return *ret0, err } @@ -422,7 +428,9 @@ func (_TRC21Issuer *TRC21IssuerCaller) Tokens(opts *bind.CallOpts) ([]common.Add var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _TRC21Issuer.contract.Call(opts, out, "tokens") return *ret0, err } diff --git a/contracts/validator/contract/validator.go b/contracts/validator/contract/validator.go index f010a03678..627320476a 100644 --- a/contracts/validator/contract/validator.go +++ b/contracts/validator/contract/validator.go @@ -142,7 +142,7 @@ func bindSafeMath(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.SafeMathCaller.contract.Call(opts, result, method, params...) } @@ -161,7 +161,7 @@ func (_SafeMath *SafeMathRaw) Transact(opts *bind.TransactOpts, method string, p // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_SafeMath *SafeMathCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _SafeMath.Contract.contract.Call(opts, result, method, params...) } @@ -303,7 +303,7 @@ func bindXDCValidator(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCValidator *XDCValidatorRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCValidator *XDCValidatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCValidator.Contract.XDCValidatorCaller.contract.Call(opts, result, method, params...) } @@ -322,7 +322,7 @@ func (_XDCValidator *XDCValidatorRaw) Transact(opts *bind.TransactOpts, method s // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_XDCValidator *XDCValidatorCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error { +func (_XDCValidator *XDCValidatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { return _XDCValidator.Contract.contract.Call(opts, result, method, params...) } @@ -344,7 +344,9 @@ func (_XDCValidator *XDCValidatorCaller) KYCString(opts *bind.CallOpts, arg0 com var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "KYCString", arg0, arg1) return *ret0, err } @@ -370,7 +372,9 @@ func (_XDCValidator *XDCValidatorCaller) CandidateCount(opts *bind.CallOpts) (*b var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "candidateCount") return *ret0, err } @@ -396,7 +400,9 @@ func (_XDCValidator *XDCValidatorCaller) CandidateWithdrawDelay(opts *bind.CallO var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "candidateWithdrawDelay") return *ret0, err } @@ -422,7 +428,9 @@ func (_XDCValidator *XDCValidatorCaller) Candidates(opts *bind.CallOpts, arg0 *b var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "candidates", arg0) return *ret0, err } @@ -448,7 +456,9 @@ func (_XDCValidator *XDCValidatorCaller) GetCandidateCap(opts *bind.CallOpts, _c var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getCandidateCap", _candidate) return *ret0, err } @@ -474,7 +484,9 @@ func (_XDCValidator *XDCValidatorCaller) GetCandidateOwner(opts *bind.CallOpts, var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getCandidateOwner", _candidate) return *ret0, err } @@ -500,7 +512,9 @@ func (_XDCValidator *XDCValidatorCaller) GetCandidates(opts *bind.CallOpts) ([]c var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getCandidates") return *ret0, err } @@ -526,7 +540,9 @@ func (_XDCValidator *XDCValidatorCaller) GetHashCount(opts *bind.CallOpts, _addr var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getHashCount", _address) return *ret0, err } @@ -552,7 +568,9 @@ func (_XDCValidator *XDCValidatorCaller) GetLatestKYC(opts *bind.CallOpts, _addr var ( ret0 = new(string) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getLatestKYC", _address) return *ret0, err } @@ -578,7 +596,9 @@ func (_XDCValidator *XDCValidatorCaller) GetOwnerCount(opts *bind.CallOpts) (*bi var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getOwnerCount") return *ret0, err } @@ -604,7 +624,9 @@ func (_XDCValidator *XDCValidatorCaller) GetVoterCap(opts *bind.CallOpts, _candi var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getVoterCap", _candidate, _voter) return *ret0, err } @@ -630,7 +652,9 @@ func (_XDCValidator *XDCValidatorCaller) GetVoters(opts *bind.CallOpts, _candida var ( ret0 = new([]common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getVoters", _candidate) return *ret0, err } @@ -656,7 +680,9 @@ func (_XDCValidator *XDCValidatorCaller) GetWithdrawBlockNumbers(opts *bind.Call var ( ret0 = new([]*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getWithdrawBlockNumbers") return *ret0, err } @@ -682,7 +708,9 @@ func (_XDCValidator *XDCValidatorCaller) GetWithdrawCap(opts *bind.CallOpts, _bl var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "getWithdrawCap", _blockNumber) return *ret0, err } @@ -708,7 +736,9 @@ func (_XDCValidator *XDCValidatorCaller) HasVotedInvalid(opts *bind.CallOpts, ar var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "hasVotedInvalid", arg0, arg1) return *ret0, err } @@ -734,7 +764,9 @@ func (_XDCValidator *XDCValidatorCaller) InvalidKYCCount(opts *bind.CallOpts, ar var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "invalidKYCCount", arg0) return *ret0, err } @@ -760,7 +792,9 @@ func (_XDCValidator *XDCValidatorCaller) InvalidPercent(opts *bind.CallOpts, _in var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "invalidPercent", _invalidCandidate) return *ret0, err } @@ -786,7 +820,9 @@ func (_XDCValidator *XDCValidatorCaller) IsCandidate(opts *bind.CallOpts, _candi var ( ret0 = new(bool) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "isCandidate", _candidate) return *ret0, err } @@ -812,7 +848,9 @@ func (_XDCValidator *XDCValidatorCaller) MaxValidatorNumber(opts *bind.CallOpts) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "maxValidatorNumber") return *ret0, err } @@ -838,7 +876,9 @@ func (_XDCValidator *XDCValidatorCaller) MinCandidateCap(opts *bind.CallOpts) (* var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "minCandidateCap") return *ret0, err } @@ -864,7 +904,9 @@ func (_XDCValidator *XDCValidatorCaller) MinVoterCap(opts *bind.CallOpts) (*big. var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "minVoterCap") return *ret0, err } @@ -890,7 +932,9 @@ func (_XDCValidator *XDCValidatorCaller) OwnerCount(opts *bind.CallOpts) (*big.I var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "ownerCount") return *ret0, err } @@ -916,7 +960,9 @@ func (_XDCValidator *XDCValidatorCaller) OwnerToCandidate(opts *bind.CallOpts, a var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "ownerToCandidate", arg0, arg1) return *ret0, err } @@ -942,7 +988,9 @@ func (_XDCValidator *XDCValidatorCaller) Owners(opts *bind.CallOpts, arg0 *big.I var ( ret0 = new(common.Address) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "owners", arg0) return *ret0, err } @@ -968,7 +1016,9 @@ func (_XDCValidator *XDCValidatorCaller) VoterWithdrawDelay(opts *bind.CallOpts) var ( ret0 = new(*big.Int) ) - out := ret0 + out := &[]interface{}{ + ret0, + } err := _XDCValidator.contract.Call(opts, out, "voterWithdrawDelay") return *ret0, err } diff --git a/core/token_validator.go b/core/token_validator.go index 070a3342ce..86d2b9ddc5 100644 --- a/core/token_validator.go +++ b/core/token_validator.go @@ -83,7 +83,7 @@ func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractA return nil, err } var unpackResult interface{} - err = abi.Unpack(&unpackResult, method, result) + err = abi.UnpackIntoInterface(&unpackResult, method, result) if err != nil { return nil, err } diff --git a/tests/fuzzers/abi/abifuzzer.go b/tests/fuzzers/abi/abifuzzer.go index 5b8986c09b..6e0c0139af 100644 --- a/tests/fuzzers/abi/abifuzzer.go +++ b/tests/fuzzers/abi/abifuzzer.go @@ -30,7 +30,7 @@ import ( func unpackPack(abi abi.ABI, method string, inputType []interface{}, input []byte) bool { outptr := reflect.New(reflect.TypeOf(inputType)) - if err := abi.Unpack(outptr.Interface(), method, input); err == nil { + if err := abi.UnpackIntoInterface(outptr.Interface(), method, input); err == nil { output, err := abi.Pack(method, input) if err != nil { // We have some false positives as we can unpack these type successfully, but not pack them @@ -51,7 +51,7 @@ func unpackPack(abi abi.ABI, method string, inputType []interface{}, input []byt func packUnpack(abi abi.ABI, method string, input []interface{}) bool { if packed, err := abi.Pack(method, input); err == nil { outptr := reflect.New(reflect.TypeOf(input)) - err := abi.Unpack(outptr.Interface(), method, packed) + err := abi.UnpackIntoInterface(outptr.Interface(), method, packed) if err != nil { panic(err) } From 5b48621c366e1224ae12a342b58dfe1ee3c5ff49 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 128/280] accouts, core: fix some comments (#21617) --- accounts/accounts.go | 2 +- accounts/scwallet/wallet.go | 2 +- accounts/usbwallet/wallet.go | 2 +- core/state/state_object.go | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 5fdf271ae0..18dc3c49d4 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -88,7 +88,7 @@ type Wallet interface { // to discover non zero accounts and automatically add them to list of tracked // accounts. // - // Note, self derivaton will increment the last component of the specified path + // Note, self derivation will increment the last component of the specified path // opposed to decending into a child path to allow discovering accounts starting // from non zero components. // diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 8dfabcd6c3..17c089474a 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -637,7 +637,7 @@ func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun // to discover non zero accounts and automatically add them to list of tracked // accounts. // -// Note, self derivaton will increment the last component of the specified path +// Note, self derivation will increment the last component of the specified path // opposed to decending into a child path to allow discovering accounts starting // from non zero components. // diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 7cb512e21c..d0d219fe54 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -493,7 +493,7 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun // to discover non zero accounts and automatically add them to list of tracked // accounts. // -// Note, self derivaton will increment the last component of the specified path +// Note, self derivation will increment the last component of the specified path // opposed to decending into a child path to allow discovering accounts starting // from non zero components. // diff --git a/core/state/state_object.go b/core/state/state_object.go index 7eda5c4d4d..d49ae247ce 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -174,7 +174,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has if s.fakeStorage != nil { return s.fakeStorage[key] } - // Track the amount of time wasted on reading the storge trie + // Track the amount of time wasted on reading the storage trie defer func(start time.Time) { s.db.StorageReads += time.Since(start) }(time.Now()) value := common.Hash{} // Load from DB in case it is missing. @@ -272,7 +272,7 @@ func (s *stateObject) setState(key, value common.Hash) { // updateTrie writes cached storage modifications into the object's storage trie. func (s *stateObject) updateTrie(db Database) Trie { - // Track the amount of time wasted on updating the storge trie + // Track the amount of time wasted on updating the storage trie defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) tr := s.getTrie(db) for key, value := range s.dirtyStorage { @@ -292,7 +292,7 @@ func (s *stateObject) updateTrie(db Database) Trie { func (s *stateObject) updateRoot(db Database) { s.updateTrie(db) - // Track the amount of time wasted on hashing the storge trie + // Track the amount of time wasted on hashing the storage trie defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now()) s.data.Root = s.trie.Hash() @@ -305,7 +305,7 @@ func (s *stateObject) CommitTrie(db Database) error { if s.dbErr != nil { return s.dbErr } - // Track the amount of time wasted on committing the storge trie + // Track the amount of time wasted on committing the storage trie defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) root, err := s.trie.Commit(nil) From d8c9ad3c9f3c868ec35a458bb19b0e29bd189541 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 129/280] all: replace RWMutex with Mutex in places where RLock is not used (#21622) --- accounts/keystore/file_cache.go | 2 +- core/chain_indexer.go | 2 +- eth/downloader/downloader.go | 2 +- les/txrelay.go | 2 +- miner/unconfirmed.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index 08a4ca1c59..cd1306d32a 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -31,7 +31,7 @@ import ( type fileCache struct { all mapset.Set // Set of all files from the keystore folder lastMod time.Time // Last time instance when a file was modified - mu sync.RWMutex + mu sync.Mutex } // scan performs a new scan on the given directory, compares against the already diff --git a/core/chain_indexer.go b/core/chain_indexer.go index d089bc2082..d497d760f6 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -86,7 +86,7 @@ type ChainIndexer struct { throttling time.Duration // Disk throttling to prevent a heavy upgrade from hogging resources log log.Logger - lock sync.RWMutex + lock sync.Mutex } // NewChainIndexer creates a new chain indexer to do background processing on diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 9f25fc905f..9276392e78 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -145,7 +145,7 @@ type Downloader struct { cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers quitCh chan struct{} // Quit channel to signal termination - quitLock sync.RWMutex // Lock to prevent double closes + quitLock sync.Mutex // Lock to prevent double closes // Testing hooks syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run diff --git a/les/txrelay.go b/les/txrelay.go index b5488a8ad5..cda4de6f0e 100644 --- a/les/txrelay.go +++ b/les/txrelay.go @@ -34,7 +34,7 @@ type LesTxRelay struct { ps *peerSet peerList []*peer peerStartPos int - lock sync.RWMutex + lock sync.Mutex reqDist *requestDistributor } diff --git a/miner/unconfirmed.go b/miner/unconfirmed.go index 49bc2dfc16..f5fdf019e7 100644 --- a/miner/unconfirmed.go +++ b/miner/unconfirmed.go @@ -47,7 +47,7 @@ type unconfirmedBlocks struct { chain headerRetriever // Blockchain to verify canonical status through depth uint // Depth after which to discard previous blocks blocks *ring.Ring // Block infos to allow canonical chain cross checks - lock sync.RWMutex // Protects the fields from concurrent access + lock sync.Mutex // Protects the fields from concurrent access } // newUnconfirmedBlocks returns new data structure to track currently unconfirmed blocks. From d02ba1db818fc163c65171d8f260e1dec221bfda Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 130/280] accounts/keystore: fix flaky test (#21703) * accounts/keystore: add timeout to test to prevent failure on travis The TestWalletNotifications test sporadically fails on travis. This is because we shutdown the event collection before all events are received. Adding a small timeout (10 milliseconds) allows the collector to be scheduled and to consume all pending events before we shut it down. * accounts/keystore: added newlines back in * accounts/keystore: properly fix the walletNotifications test --- accounts/keystore/keystore_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 2e139cad0f..75af63ff77 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -335,7 +335,9 @@ func TestWalletNotifications(t *testing.T) { // Shut down the event collector and check events. sub.Unsubscribe() - <-updates + for ev := range updates { + events = append(events, walletEvent{ev, ev.Wallet.Accounts()[0]}) + } checkAccounts(t, live, ks.Wallets()) checkEvents(t, wantEvents, events) } From 39464059834d7c697f8aa65a3dc8942a1aa238d6 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 131/280] accounts/usbwallet: fix ledger version check (#21733) The version check logic did not take into account the second digit (i.e. the '4' in v1.4.0) - this one line patch corrects this. --- accounts/usbwallet/ledger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 818ed4cbef..b1d5ea7603 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -162,7 +162,7 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return common.Address{}, nil, accounts.ErrWalletClosed } // Ensure the wallet is capable of signing the given transaction - if chainID != nil && w.version[0] <= 1 && w.version[2] <= 2 { + if chainID != nil && w.version[0] <= 1 && w.version[1] <= 0 && w.version[2] <= 2 { //lint:ignore ST1005 brand name displayed on the console return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2]) } From c7efbcd9fd7d10cd2e218669b3210e54996f0123 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 132/280] accounts/abi/bind: restore error functionality (#21743) --- accounts/abi/bind/base.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 4ad422389e..eac659e7d4 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -160,7 +160,10 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri } } else { output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) - if err == nil && len(output) == 0 { + if err != nil { + return err + } + if len(output) == 0 { // Make sure we have a contract to operate on, and bail out otherwise. if code, err = c.caller.CodeAt(ctx, c.address, opts.BlockNumber); err != nil { return err From 7f2ae32933feb62658c66fa723f3ba2d58379c44 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 133/280] accounts/abi: template: set events Raw field in Parse methods (#21807) --- accounts/abi/bind/template.go | 1 + 1 file changed, 1 insertion(+) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index e91b3a75a8..6deab685c4 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -540,6 +540,7 @@ var ( if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { return nil, err } + event.Raw = log return event, nil } From 25284155d8918b3dd5b1dc09ee2b9b3d3126b00d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:11 +0800 Subject: [PATCH 134/280] accounts: remove redundant conversions and import names (#21903) --- accounts/abi/reflect_test.go | 4 ++-- accounts/abi/type_test.go | 2 +- accounts/keystore/passphrase.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index bac4cd9530..cf13a79da8 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -202,12 +202,12 @@ func TestConvertType(t *testing.T) { fields = append(fields, reflect.StructField{ Name: "X", Type: reflect.TypeOf(new(big.Int)), - Tag: reflect.StructTag("json:\"" + "x" + "\""), + Tag: "json:\"" + "x" + "\"", }) fields = append(fields, reflect.StructField{ Name: "Y", Type: reflect.TypeOf(new(big.Int)), - Tag: reflect.StructTag("json:\"" + "y" + "\""), + Tag: "json:\"" + "y" + "\"", }) val := reflect.New(reflect.StructOf(fields)) val.Elem().Field(0).Set(reflect.ValueOf(big.NewInt(1))) diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index 504e938ec1..e6b08b4878 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -255,7 +255,7 @@ func TestTypeCheck(t *testing.T) { {"bytes", nil, [2]byte{0, 1}, "abi: cannot use array as type slice as argument"}, {"bytes", nil, common.Hash{1}, "abi: cannot use array as type slice as argument"}, {"string", nil, "hello world", ""}, - {"string", nil, string(""), ""}, + {"string", nil, "", ""}, {"string", nil, []byte{}, "abi: cannot use slice as type string as argument"}, {"bytes32[]", nil, [][32]byte{{}}, ""}, {"function", nil, [24]byte{}, ""}, diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index ae0d2c1dd2..f791da227a 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -228,7 +228,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { key := crypto.ToECDSAUnsafe(keyBytes) return &Key{ - Id: uuid.UUID(keyId), + Id: keyId, Address: crypto.PubkeyToAddress(key.PublicKey), PrivateKey: key, }, nil From ddea01dc9cc35d1599ce8a5c41d0ada65334a8a9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 135/280] accounts: fix Ledger Live account derivation path (clef) (#21757) * signer/core/api: fix derivation of ledger live accounts For ledger hardware wallets, change account iteration as follows: - ledger legacy: m/44'/60'/0'/X; for 0<=X<5 - ledger live: m/44'/60'/0'/0/X; for 0<=X<5 - ledger legacy: m/44'/60'/0'/X; for 0<=X<10 - ledger live: m/44'/60'/X'/0/0; for 0<=X<10 Non-ledger derivation is unchanged and remains as: - non-ledger: m/44'/60'/0'/0/X; for 0<=X<10 * signer/core/api: derive ten default paths for all hardware wallets, plus ten legacy and ten live paths for ledger wallets * signer/core/api: as .../0'/0/0 already included by default paths, do not include it again with ledger live paths * accounts, signer: implement path iterators for hd wallets Co-authored-by: Martin Holst Swende --- accounts/hd.go | 28 ++++++++++++++++++++++++++++ accounts/hd_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/accounts/hd.go b/accounts/hd.go index 7727d1a851..e4fb0543de 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -150,3 +150,31 @@ func (path *DerivationPath) UnmarshalJSON(b []byte) error { *path, err = ParseDerivationPath(dp) return err } + +// DefaultIterator creates a BIP-32 path iterator, which progresses by increasing the last component: +// i.e. m/44'/60'/0'/0/0, m/44'/60'/0'/0/1, m/44'/60'/0'/0/2, ... m/44'/60'/0'/0/N. +func DefaultIterator(base DerivationPath) func() DerivationPath { + path := make(DerivationPath, len(base)) + copy(path[:], base[:]) + // Set it back by one, so the first call gives the first result + path[len(path)-1]-- + return func() DerivationPath { + path[len(path)-1]++ + return path + } +} + +// LedgerLiveIterator creates a bip44 path iterator for Ledger Live. +// Ledger Live increments the third component rather than the fifth component +// i.e. m/44'/60'/0'/0/0, m/44'/60'/1'/0/0, m/44'/60'/2'/0/0, ... m/44'/60'/N'/0/0. +func LedgerLiveIterator(base DerivationPath) func() DerivationPath { + path := make(DerivationPath, len(base)) + copy(path[:], base[:]) + // Set it back by one, so the first call gives the first result + path[2]-- + return func() DerivationPath { + // ledgerLivePathIterator iterates on the third component + path[2]++ + return path + } +} diff --git a/accounts/hd_test.go b/accounts/hd_test.go index 3156a487ee..0743bbe666 100644 --- a/accounts/hd_test.go +++ b/accounts/hd_test.go @@ -17,6 +17,7 @@ package accounts import ( + "fmt" "reflect" "testing" ) @@ -77,3 +78,41 @@ func TestHDPathParsing(t *testing.T) { } } } + +func testDerive(t *testing.T, next func() DerivationPath, expected []string) { + t.Helper() + for i, want := range expected { + if have := next(); fmt.Sprintf("%v", have) != want { + t.Errorf("step %d, have %v, want %v", i, have, want) + } + } +} + +func TestHdPathIteration(t *testing.T) { + testDerive(t, DefaultIterator(DefaultBaseDerivationPath), + []string{ + "m/44'/60'/0'/0/0", "m/44'/60'/0'/0/1", + "m/44'/60'/0'/0/2", "m/44'/60'/0'/0/3", + "m/44'/60'/0'/0/4", "m/44'/60'/0'/0/5", + "m/44'/60'/0'/0/6", "m/44'/60'/0'/0/7", + "m/44'/60'/0'/0/8", "m/44'/60'/0'/0/9", + }) + + testDerive(t, DefaultIterator(LegacyLedgerBaseDerivationPath), + []string{ + "m/44'/60'/0'/0", "m/44'/60'/0'/1", + "m/44'/60'/0'/2", "m/44'/60'/0'/3", + "m/44'/60'/0'/4", "m/44'/60'/0'/5", + "m/44'/60'/0'/6", "m/44'/60'/0'/7", + "m/44'/60'/0'/8", "m/44'/60'/0'/9", + }) + + testDerive(t, LedgerLiveIterator(DefaultBaseDerivationPath), + []string{ + "m/44'/60'/0'/0/0", "m/44'/60'/1'/0/0", + "m/44'/60'/2'/0/0", "m/44'/60'/3'/0/0", + "m/44'/60'/4'/0/0", "m/44'/60'/5'/0/0", + "m/44'/60'/6'/0/0", "m/44'/60'/7'/0/0", + "m/44'/60'/8'/0/0", "m/44'/60'/9'/0/0", + }) +} From 05e9dc0def8b28a5b1820a6184065c4596d13087 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 136/280] accounts/keystore: add missing function doc for SignText (#21914) Co-authored-by: Pascal Dierich --- accounts/keystore/wallet.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go index 18ba31701b..a3c84ba284 100644 --- a/accounts/keystore/wallet.go +++ b/accounts/keystore/wallet.go @@ -58,7 +58,7 @@ func (w *keystoreWallet) Open(passphrase string) error { return nil } func (w *keystoreWallet) Close() error { return nil } // Accounts implements accounts.Wallet, returning an account list consisting of -// a single account that the plain kestore wallet contains. +// a single account that the plain keystore wallet contains. func (w *keystoreWallet) Accounts() []accounts.Account { return []accounts.Account{w.account} } @@ -93,12 +93,12 @@ func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte return w.keystore.SignHash(account, hash) } -// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed +// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed. func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { return w.SignHash(account, crypto.Keccak256(data)) } -// SignDataWithPassphrase signs keccak256(data). The mimetype parameter describes the type of data being signed +// SignDataWithPassphrase signs keccak256(data). The mimetype parameter describes the type of data being signed. func (w *keystoreWallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { // Make sure the requested account is contained within if !w.Contains(account) { @@ -108,12 +108,14 @@ func (w *keystoreWallet) SignDataWithPassphrase(account accounts.Account, passph return w.keystore.SignHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) } +// SignText implements accounts.Wallet, attempting to sign the hash of +// the given text with the given account. func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { return w.SignHash(account, accounts.TextHash(text)) } // SignTextWithPassphrase implements accounts.Wallet, attempting to sign the -// given hash with the given account using passphrase as extra authentication. +// hash of the given text with the given account using passphrase as extra authentication. func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { // Make sure the requested account is contained within if !w.Contains(account) { From 2ff9f336ede994f9840baaa60ca7b17b3bd9bf11 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 137/280] core: improve contextual information on core errors (#21869) --- core/blockchain_test.go | 2 +- core/state_processor.go | 2 +- core/state_transition.go | 5 ----- light/lightchain_test.go | 3 ++- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 0ea24c180b..849daac1b8 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -439,7 +439,7 @@ func testBadHashes(t *testing.T, full bool) { _, err = blockchain.InsertHeaderChain(headers, 1) } - if err != ErrBlacklistedHash { + if !errors.Is(err, ErrBlacklistedHash) { t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash) } } diff --git a/core/state_processor.go b/core/state_processor.go index 3a503f1c18..a6ecb8f7ca 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -120,7 +120,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra statedb.SetTxContext(tx.Hash(), i) receipt, gas, err, tokenFeeUsed := applyTransaction(p.config, balanceFee, gp, statedb, coinbaseOwner, blockNumber, header.BaseFee, blockHash, tx, usedGas, vmenv) if err != nil { - return nil, nil, 0, err + return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) diff --git a/core/state_transition.go b/core/state_transition.go index 24375cf8ff..1bba04e2fa 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -17,7 +17,6 @@ package core import ( - "errors" "fmt" "math" "math/big" @@ -32,10 +31,6 @@ import ( var emptyCodeHash = crypto.Keccak256Hash(nil) -var ( - errInsufficientBalanceForGas = errors.New("insufficient balance to pay for gas") -) - /* The State Transitioning Model diff --git a/light/lightchain_test.go b/light/lightchain_test.go index df7808b089..2c710c07d2 100644 --- a/light/lightchain_test.go +++ b/light/lightchain_test.go @@ -18,6 +18,7 @@ package light import ( "context" + "errors" "math/big" "testing" @@ -317,7 +318,7 @@ func TestBadHeaderHashes(t *testing.T) { var err error headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10) core.BadHashes[headers[2].Hash()] = true - if _, err = bc.InsertHeaderChain(headers, 1); err != core.ErrBlacklistedHash { + if _, err = bc.InsertHeaderChain(headers, 1); !errors.Is(err, core.ErrBlacklistedHash) { t.Errorf("error mismatch: have: %v, want %v", err, core.ErrBlacklistedHash) } } From fb85aca8d8961b6407cf92ea70e00808aa1fcb66 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 138/280] accounts/abi/bind: allow specifying signer on transactOpts (#21356) --- accounts/abi/bind/auth.go | 7 ++++-- accounts/abi/bind/backends/simulated_test.go | 25 +++++++------------- accounts/abi/bind/bind_test.go | 12 +++++----- core/state_processor_test.go | 12 +++++----- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 22ae6a218f..8f993c6cca 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -54,14 +54,17 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { } // NewKeyStoreTransactor is a utility method to easily create a transaction signer from -// a decrypted key from a keystore. +// an decrypted key from a keystore. +// +// Deprecated: Use NewKeyStoreTransactorWithChainID instead. func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { + log.Warn("WARNING: NewKeyStoreTransactor has been deprecated in favour of NewTransactorWithChainID") signer := types.HomesteadSigner{} return &TransactOpts{ From: account.Address, Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { if address != account.Address { - return nil, errors.New("not authorized to sign this account") + return nil, ErrNotAuthorized } signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes()) if err != nil { diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 69a96b04c3..40d8ae6b7b 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -39,7 +39,7 @@ import ( func TestSimulatedBackend(t *testing.T) { var gasLimit uint64 = 8000029 key, _ := crypto.GenerateKey() // nolint: gosec - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) genAlloc := make(core.GenesisAlloc) genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} @@ -411,19 +411,10 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) - opts := bind.NewKeyedTransactor(key) + // opts := bind.NewKeyedTransactor(key) + opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000, ¶ms.ChainConfig{ - ConstantinopleBlock: big.NewInt(0), - XDPoS: ¶ms.XDPoSConfig{ - Epoch: 900, - SkipV1Validation: true, - V2: ¶ms.V2{ - SwitchBlock: big.NewInt(900), - CurrentConfig: params.UnitTestV2Configs[0], - }, - }, - }) + sim := NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() parsed, _ := abi.JSON(strings.NewReader(contractAbi)) @@ -836,7 +827,7 @@ func TestSimulatedBackend_PendingCodeAt(t *testing.T) { if err != nil { t.Errorf("could not get code at test addr: %v", err) } - auth := bind.NewKeyedTransactor(testKey) + auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) if err != nil { t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) @@ -872,7 +863,7 @@ func TestSimulatedBackend_CodeAt(t *testing.T) { if err != nil { t.Errorf("could not get code at test addr: %v", err) } - auth := bind.NewKeyedTransactor(testKey) + auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) if err != nil { t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) @@ -905,7 +896,7 @@ func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { if err != nil { t.Errorf("could not get code at test addr: %v", err) } - contractAuth := bind.NewKeyedTransactor(testKey) + contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim) if err != nil { t.Errorf("could not deploy contract: %v", err) @@ -993,7 +984,7 @@ func TestSimulatedBackend_CallContractRevert(t *testing.T) { if err != nil { t.Errorf("could not get code at test addr: %v", err) } - contractAuth := bind.NewKeyedTransactor(testKey) + contractAuth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim) if err != nil { t.Errorf("could not deploy contract: %v", err) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index bb90a6a8cf..d4c232620e 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1156,7 +1156,7 @@ var bindTests = []struct { ` key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() @@ -1296,7 +1296,7 @@ var bindTests = []struct { ` // Initialize test accounts key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() @@ -1392,7 +1392,7 @@ var bindTests = []struct { sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() - transactOpts := bind.NewKeyedTransactor(key) + transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) _, _, _, err := DeployIdentifierCollision(transactOpts, sim) if err != nil { t.Fatalf("failed to deploy contract: %v", err) @@ -1455,7 +1455,7 @@ var bindTests = []struct { sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() - transactOpts := bind.NewKeyedTransactor(key) + transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) _, _, c1, err := DeployContractOne(transactOpts, sim) if err != nil { t.Fatal("Failed to deploy contract") @@ -1513,7 +1513,7 @@ var bindTests = []struct { ` // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() - auth := bind.NewKeyedTransactor(key) + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() @@ -1583,7 +1583,7 @@ var bindTests = []struct { sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() - opts := bind.NewKeyedTransactor(key) + opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) _, _, c, err := DeployNewFallbacks(opts, sim) if err != nil { t.Fatalf("Failed to deploy contract: %v", err) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 6de370ec98..39d6ce194f 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -154,19 +154,19 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas, tooBigNumber, big.NewInt(1)), }, - want: "max priority fee per gas higher than 2^256-1: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas bit length: 257", + want: "could not apply tx 0 [0x15b8391b9981f266b32f3ab7da564bbeb3d6c21628364ea9b32a21139f89f712]: max priority fee per gas higher than 2^256-1: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas bit length: 257", }, { // ErrFeeCapVeryHigh txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), tooBigNumber), }, - want: "max fee per gas higher than 2^256-1: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas bit length: 257", + want: "could not apply tx 0 [0x48bc299b83fdb345c57478f239e89814bb3063eb4e4b49f3b6057a69255c16bd]: max fee per gas higher than 2^256-1: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas bit length: 257", }, { // ErrTipAboveFeeCap txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(2), big.NewInt(1)), }, - want: "max priority fee per gas higher than max fee per gas: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas: 2, maxFeePerGas: 1", + want: "could not apply tx 0 [0xf987a31ff0c71895780a7612f965a0c8b056deb54e020bb44fa478092f14c9b4]: max priority fee per gas higher than max fee per gas: address xdc71562b71999873DB5b286dF957af199Ec94617F7, maxPriorityFeePerGas: 2, maxFeePerGas: 1", }, { // ErrInsufficientFunds // Available balance: 1000000000000000000 @@ -177,13 +177,13 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas, big.NewInt(1), big.NewInt(50000000000000)), }, - want: "insufficient funds for gas * price + value: address xdc71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 1050000000000000000", + want: "could not apply tx 0 [0x413603cd096a87f41b1660d3ed3e27d62e1da78eac138961c0a1314ed43bd129]: insufficient funds for gas * price + value: address xdc71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 1050000000000000000", }, { // Another ErrInsufficientFunds, this one to ensure that feecap/tip of max u256 is allowed txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas, bigNumber, bigNumber), }, - want: "insufficient funds for gas * price + value: address xdc71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 2431633873983640103894990685182446064918669677978451844828609264166175722438635000", + want: "could not apply tx 0 [0xd82a0c2519acfeac9a948258c47e784acd20651d9d80f9a1c67b4137651c3a24]: insufficient funds for gas * price + value: address xdc71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 2431633873983640103894990685182446064918669677978451844828609264166175722438635000", }, }[8:] { block := GenerateBadBlock(t, genesis, ethash.NewFaker(), tt.txs, gspec.Config) @@ -232,7 +232,7 @@ func TestStateProcessorErrors(t *testing.T) { txs: []*types.Transaction{ mkDynamicTx(0, common.Address{}, params.TxGas-1000, big.NewInt(0), big.NewInt(0)), }, - want: "transaction type not supported", + want: "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: transaction type not supported", }, } { block := GenerateBadBlock(t, genesis, ethash.NewFaker(), tt.txs, gspec.Config) From 54e0d6c0939e6794bf22a71d8e3f05495e7c58ea Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 139/280] abi/bind: fix error-handling in generated wrappers for functions returning structs (#22005) Fixes the template used when generating code, which in some scenarios would lead to panic instead of returning an error. --- accounts/abi/bind/bind_test.go | 39 ++++++++++++++++++++++++++++++++++ accounts/abi/bind/template.go | 3 +++ 2 files changed, 42 insertions(+) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index d4c232620e..88b231e215 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -574,6 +574,45 @@ var bindTests = []struct { nil, nil, }, + { + `NonExistentStruct`, + ` + contract NonExistentStruct { + function Struct() public view returns(uint256 a, uint256 b) { + return (10, 10); + } + } + `, + []string{`6080604052348015600f57600080fd5b5060888061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063d5f6622514602d575b600080fd5b6033604c565b6040805192835260208301919091528051918290030190f35b600a809156fea264697066735822beefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeefbeef64736f6c6343decafe0033`}, + []string{`[{"inputs":[],"name":"Struct","outputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"stateMutability":"pure","type":"function"}]`}, + ` + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Create a simulator and wrap a non-deployed contract + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + nonexistent, err := NewNonExistentStruct(common.Address{}, sim) + if err != nil { + t.Fatalf("Failed to access non-existent contract: %v", err) + } + // Ensure that contract calls fail with the appropriate error + if res, err := nonexistent.Struct(nil); err == nil { + t.Fatalf("Call succeeded on non-existent contract: %v", res) + } else if (err != bind.ErrNoCode) { + t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode) + } + `, + nil, + nil, + nil, + nil, + }, // Tests that gas estimation works for contracts with weird gas mechanics too. { `FunkyGasPattern`, diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 6deab685c4..c61dc819c0 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -303,6 +303,9 @@ var ( err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) {{if .Structured}} outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) + if err != nil { + return *outstruct, err + } {{range $i, $t := .Normalized.Outputs}} outstruct.{{.Name}} = out[{{$i}}].({{bindtype .Type $structs}}){{end}} From f87376535d9f5c9bb25dc58757756f08d7450fcb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 140/280] cmd/abigen: clarify abigen alias flag usage (#21875) * doc: clarify abigen alias flag usage update the `abigen --alias` flag help info, give an example to make it more clear related issue: https://github.com/ethereum/go-ethereum/issues/21846 * Update cmd/abigen/main.go Co-authored-by: ligi Co-authored-by: Martin Holst Swende Co-authored-by: ligi --- cmd/abigen/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index a20d75e202..5276b843c9 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -77,7 +77,7 @@ var ( } aliasFlag = &cli.StringFlag{ Name: "alias", - Usage: "Comma separated aliases for function and event renaming, e.g. foo=bar", + Usage: "Comma separated aliases for function and event renaming, e.g. original1=alias1, original2=alias2", } ) From cebdb44051a11c1968e270ec891668b654c43d21 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 141/280] accounts/abi/bind: fix erroneous test (#22053) closes #22049 --- accounts/abi/bind/bind_test.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 88b231e215..fef12a7e75 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1590,11 +1590,7 @@ var bindTests = []struct { contract NewFallbacks { event Fallback(bytes data); fallback() external { - bytes memory data; - assembly { - calldatacopy(data, 0, calldatasize()) - } - emit Fallback(data); + emit Fallback(msg.data); } event Received(address addr, uint value); @@ -1603,7 +1599,7 @@ var bindTests = []struct { } } `, - []string{"60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040526004361061000d575b36610081575b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b005b34801561008e5760006000fd5b505b606036600082377f9043988963722edecc2099c75b0af0ff76af14ffca42ed6bce059a20a2a9f986816040518080602001828103825283818151815260200191508051906020019080838360005b838110156100fa5780820151818401525b6020810190506100de565b50505050905090810190601f1680156101275780820380516001836020036101000a031916815260200191505b509250505060405180910390a1505b00fea26469706673582212205643ca37f40c2b352dc541f42e9e6720de065de756324b7fcc9fb1d67eda4a7d64736f6c63430006040033"}, + []string{"6080604052348015600f57600080fd5b506101078061001f6000396000f3fe608060405236605f577f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1005b348015606a57600080fd5b507f9043988963722edecc2099c75b0af0ff76af14ffca42ed6bce059a20a2a9f98660003660405180806020018281038252848482818152602001925080828437600081840152601f19601f820116905080830192505050935050505060405180910390a100fea26469706673582212201f994dcfbc53bf610b19176f9a361eafa77b447fd9c796fa2c615dfd0aaf3b8b64736f6c634300060c0033"}, []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Fallback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Received","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]`}, ` "bytes" @@ -1652,6 +1648,7 @@ var bindTests = []struct { } // Test fallback function + gotEvent = false opts.Value = nil calldata := []byte{0x01, 0x02, 0x03} c.Fallback(opts, calldata) From f8c67edb64904d9a96090b3fd802ec6e75813de5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 142/280] accounts/scwallet: use go-ethereum crypto instead of go-ecdh (#22212) * accounts/scwallet: use go-ethereum crypto instead of go-ecdh github.com/wsddn/go-ecdh is a wrapper package for ECDH functionality with any elliptic curve. Since 'generic' ECDH is not required in accounts/scwallet (the curve is always secp256k1), we can just use the standard library functionality and our own crypto libraries to perform ECDH and save a dependency. * Update accounts/scwallet/securechannel.go Co-authored-by: Guillaume Ballet * Use the correct key Co-authored-by: Guillaume Ballet --- accounts/scwallet/securechannel.go | 21 +++++++-------------- go.mod | 1 - go.sum | 2 -- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index b27a9a3b92..b973c8cac9 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -20,6 +20,7 @@ import ( "bytes" "crypto/aes" "crypto/cipher" + "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/sha512" @@ -27,7 +28,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/crypto" pcsc "github.com/gballet/go-libpcsclite" - "github.com/wsddn/go-ecdh" "golang.org/x/crypto/pbkdf2" "golang.org/x/text/unicode/norm" ) @@ -63,26 +63,19 @@ type SecureChannelSession struct { // NewSecureChannelSession creates a new secure channel for the given card and public key. func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSession, error) { // Generate an ECDSA keypair for ourselves - gen := ecdh.NewEllipticECDH(crypto.S256()) - private, public, err := gen.GenerateKey(rand.Reader) + key, err := crypto.GenerateKey() if err != nil { return nil, err } - - cardPublic, ok := gen.Unmarshal(keyData) - if !ok { - return nil, fmt.Errorf("could not unmarshal public key from card") - } - - secret, err := gen.GenerateSharedSecret(private, cardPublic) + cardPublic, err := crypto.UnmarshalPubkey(keyData) if err != nil { - return nil, err + return nil, fmt.Errorf("could not unmarshal public key from card: %v", err) } - + secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) return &SecureChannelSession{ card: card, - secret: secret, - publicKey: gen.Marshal(public), + secret: secret.Bytes(), + publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y), }, nil } diff --git a/go.mod b/go.mod index b47ac993d6..58689e1eb3 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,6 @@ require ( github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.3.3 github.com/urfave/cli/v2 v2.27.5 - github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 golang.org/x/text v0.20.0 google.golang.org/protobuf v1.31.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 diff --git a/go.sum b/go.sum index 56803a319e..36ffbcab4c 100644 --- a/go.sum +++ b/go.sum @@ -222,8 +222,6 @@ github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From 4e23f7b607c274ef90f02fd2f18df59572a30478 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 143/280] accounts/scwallet: update documentation (#22242) --- accounts/scwallet/README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md index cfca916b3a..4313d9c6b2 100644 --- a/accounts/scwallet/README.md +++ b/accounts/scwallet/README.md @@ -31,12 +31,16 @@ Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet: ``` - > personal.openWallet("keycard://044def09") - Please enter the pairing password: + > personal.openWallet("keycard://044def09", "pairing password") ``` - Enter the pairing password that you have received during card initialization. Same with the PIN that you will subsequently be - asked for. + The pairing password has been generated during the card initialization process. + + The process needs to be repeated once more with the PIN: + + ``` + > personal.openWallet("keycard://044def09", "PIN number") + ``` If everything goes well, you should see your new account when typing `personal` on the console: From 2ffdb94855b6df81701d67092fd3719fa04b131c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 144/280] accounts/keystore: remove uneeded syntax (#21921) --- accounts/keystore/account_cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index 22fc9d40df..19ca637591 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -262,7 +262,7 @@ func (ac *accountCache) scanAccounts() error { switch { case err != nil: log.Debug("Failed to decode keystore key", "path", path, "err", err) - case (addr == common.Address{}): + case addr == common.Address{}: log.Debug("Failed to decode keystore key", "path", path, "err", "missing or zero address") default: return &accounts.Account{ From 01d3be7eb86bb99b09ba460da7f21e603138b0d3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 145/280] accounts/abi/bind: fixed unpacking error (#22230) There was a dormant error with structured inputs that failed unpacking. This commit fixes the error by switching casting to the better abi.ConvertType function. It also adds a test for calling a view function that returns a struct --- accounts/abi/abi_test.go | 3 ++ accounts/abi/bind/bind_test.go | 65 ++++++++++++++++++++++++++++++++++ accounts/abi/bind/template.go | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 4b8faf3ace..f3f934a201 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -43,6 +43,7 @@ const jsondata = ` { "type" : "function", "name" : "uint64[2]", "inputs" : [ { "name" : "inputs", "type" : "uint64[2]" } ] }, { "type" : "function", "name" : "uint64[]", "inputs" : [ { "name" : "inputs", "type" : "uint64[]" } ] }, { "type" : "function", "name" : "int8", "inputs" : [ { "name" : "inputs", "type" : "int8" } ] }, + { "type" : "function", "name" : "bytes32", "inputs" : [ { "name" : "inputs", "type" : "bytes32" } ] }, { "type" : "function", "name" : "foo", "inputs" : [ { "name" : "inputs", "type" : "uint32" } ] }, { "type" : "function", "name" : "bar", "inputs" : [ { "name" : "inputs", "type" : "uint32" }, { "name" : "string", "type" : "uint16" } ] }, { "type" : "function", "name" : "slice", "inputs" : [ { "name" : "inputs", "type" : "uint32[2]" } ] }, @@ -68,6 +69,7 @@ var ( String, _ = NewType("string", "", nil) Bool, _ = NewType("bool", "", nil) Bytes, _ = NewType("bytes", "", nil) + Bytes32, _ = NewType("bytes32", "", nil) Address, _ = NewType("address", "", nil) Uint64Arr, _ = NewType("uint64[]", "", nil) AddressArr, _ = NewType("address[]", "", nil) @@ -98,6 +100,7 @@ var methods = map[string]Method{ "uint64[]": NewMethod("uint64[]", "uint64[]", Function, "", false, false, []Argument{{"inputs", Uint64Arr, false}}, nil), "uint64[2]": NewMethod("uint64[2]", "uint64[2]", Function, "", false, false, []Argument{{"inputs", Uint64Arr2, false}}, nil), "int8": NewMethod("int8", "int8", Function, "", false, false, []Argument{{"inputs", Int8, false}}, nil), + "bytes32": NewMethod("bytes32", "bytes32", Function, "", false, false, []Argument{{"inputs", Bytes32, false}}, nil), "foo": NewMethod("foo", "foo", Function, "", false, false, []Argument{{"inputs", Uint32, false}}, nil), "bar": NewMethod("bar", "bar", Function, "", false, false, []Argument{{"inputs", Uint32, false}, {"string", Uint16, false}}, nil), "slice": NewMethod("slice", "slice", Function, "", false, false, []Argument{{"inputs", Uint32Arr2, false}}, nil), diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index fef12a7e75..54a61e79f7 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -534,6 +534,71 @@ var bindTests = []struct { nil, nil, }, + // Tests that structs are correctly unpacked + { + + `Structs`, + ` + pragma solidity ^0.6.5; + pragma experimental ABIEncoderV2; + contract Structs { + struct A { + bytes32 B; + } + + function F() public view returns (A[] memory a, uint256[] memory c, bool[] memory d) { + A[] memory a = new A[](2); + a[0].B = bytes32(uint256(1234) << 96); + uint256[] memory c; + bool[] memory d; + return (a, c, d); + } + + function G() public view returns (A[] memory a) { + A[] memory a = new A[](2); + a[0].B = bytes32(uint256(1234) << 96); + return a; + } + } + `, + []string{`608060405234801561001057600080fd5b50610278806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806328811f591461003b5780636fecb6231461005b575b600080fd5b610043610070565b604051610052939291906101a0565b60405180910390f35b6100636100d6565b6040516100529190610186565b604080516002808252606082810190935282918291829190816020015b610095610131565b81526020019060019003908161008d575050805190915061026960611b9082906000906100be57fe5b60209081029190910101515293606093508392509050565b6040805160028082526060828101909352829190816020015b6100f7610131565b8152602001906001900390816100ef575050805190915061026960611b90829060009061012057fe5b602090810291909101015152905090565b60408051602081019091526000815290565b815260200190565b6000815180845260208085019450808401835b8381101561017b578151518752958201959082019060010161015e565b509495945050505050565b600060208252610199602083018461014b565b9392505050565b6000606082526101b3606083018661014b565b6020838203818501528186516101c98185610239565b91508288019350845b818110156101f3576101e5838651610143565b9484019492506001016101d2565b505084810360408601528551808252908201925081860190845b8181101561022b57825115158552938301939183019160010161020d565b509298975050505050505050565b9081526020019056fea2646970667358221220eb85327e285def14230424c52893aebecec1e387a50bb6b75fc4fdbed647f45f64736f6c63430006050033`}, + []string{`[{"inputs":[],"name":"F","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"},{"internalType":"uint256[]","name":"c","type":"uint256[]"},{"internalType":"bool[]","name":"d","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"G","outputs":[{"components":[{"internalType":"bytes32","name":"B","type":"bytes32"}],"internalType":"structStructs.A[]","name":"a","type":"tuple[]"}],"stateMutability":"view","type":"function"}]`}, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + // Generate a new random account and a funded simulator + key, _ := crypto.GenerateKey() + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + + sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + defer sim.Close() + + // Deploy a structs method invoker contract and execute its default method + _, _, structs, err := DeployStructs(auth, sim) + if err != nil { + t.Fatalf("Failed to deploy defaulter contract: %v", err) + } + sim.Commit() + opts := bind.CallOpts{} + if _, err := structs.F(&opts); err != nil { + t.Fatalf("Failed to invoke F method: %v", err) + } + if _, err := structs.G(&opts); err != nil { + t.Fatalf("Failed to invoke G method: %v", err) + } + `, + nil, + nil, + nil, + nil, + }, // Tests that non-existent contracts are reported as such (though only simulator test) { `NonExistent`, diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index c61dc819c0..0831872a96 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -307,7 +307,7 @@ var ( return *outstruct, err } {{range $i, $t := .Normalized.Outputs}} - outstruct.{{.Name}} = out[{{$i}}].({{bindtype .Type $structs}}){{end}} + outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} return *outstruct, err {{else}} From 146ea8ba78520a2e29a277a10fd1ce135116a762 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 146/280] accounts: EIP-2718: Typed Transaction Envelope + EIP-2930 (#21502) --- accounts/abi/bind/auth.go | 4 ++-- accounts/keystore/keystore.go | 1 - accounts/scwallet/wallet.go | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 8f993c6cca..5ed3786064 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -118,7 +118,7 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou if chainID == nil { return nil, ErrNoChainID } - signer := types.NewEIP155Signer(chainID) + signer := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: account.Address, Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { @@ -141,7 +141,7 @@ func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*Tr if chainID == nil { return nil, ErrNoChainID } - signer := types.NewEIP155Signer(chainID) + signer := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: keyAddr, Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index bc8b8d980a..1f46bce34b 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -319,7 +319,6 @@ func (ks *KeyStore) SignTxWithPassphrase(a accounts.Account, passphrase string, return nil, err } defer zeroKey(key.PrivateKey) - // Depending on the presence of the chain ID, sign with or without replay protection. signer := types.LatestSignerForChainID(chainID) return types.SignTx(tx, signer, key.PrivateKey) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 17c089474a..60f1d55b5d 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -699,7 +699,7 @@ func (w *Wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) // the needed details via SignTxWithPassphrase, or by other means (e.g. unlock // the account in a keystore). func (w *Wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - signer := types.NewEIP155Signer(chainID) + signer := types.LatestSignerForChainID(chainID) hash := signer.Hash(tx) sig, err := w.SignHash(account, hash[:]) if err != nil { From c75ba9926718d1b2cdffafef7dada0ab7ed80e95 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 147/280] accounts/keystore: use github.com/google/uuid (#22217) This replaces the github.com/pborman/uuid dependency with github.com/google/uuid because the former is only a wrapper for the latter (since v1.0.0). Co-authored-by: Felix Lange --- accounts/keystore/key.go | 12 +++++++++--- accounts/keystore/passphrase.go | 21 ++++++++++++++++----- accounts/keystore/presale.go | 9 ++++++--- cmd/ethkey/generate.go | 9 ++++++--- go.mod | 3 +-- go.sum | 7 ++----- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index 1fe1dcc6c5..fe113ba3a9 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -30,7 +30,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/pborman/uuid" + "github.com/google/uuid" ) const ( @@ -108,7 +108,10 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) { } u := new(uuid.UUID) - *u = uuid.Parse(keyJSON.Id) + *u, err = uuid.Parse(keyJSON.Id) + if err != nil { + return err + } k.Id = *u addr, err := hex.DecodeString(keyJSON.Address) if err != nil { @@ -126,7 +129,10 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) { } func newKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key { - id := uuid.NewRandom() + id, err := uuid.NewRandom() + if err != nil { + panic(fmt.Sprintf("Could not create random uuid: %v", err)) + } key := &Key{ Id: id, Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey), diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index f791da227a..9492b8311f 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -41,7 +41,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/pborman/uuid" + "github.com/google/uuid" "golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/scrypt" ) @@ -226,9 +226,12 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { return nil, err } key := crypto.ToECDSAUnsafe(keyBytes) - + id, err := uuid.FromBytes(keyId) + if err != nil { + return nil, err + } return &Key{ - Id: keyId, + Id: id, Address: crypto.PubkeyToAddress(key.PublicKey), PrivateKey: key, }, nil @@ -274,7 +277,11 @@ func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byt if keyProtected.Version != version { return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version) } - keyId = uuid.Parse(keyProtected.Id) + keyUUID, err := uuid.Parse(keyProtected.Id) + if err != nil { + return nil, nil, err + } + keyId = keyUUID[:] plainText, err := DecryptDataV3(keyProtected.Crypto, auth) if err != nil { return nil, nil, err @@ -283,7 +290,11 @@ func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byt } func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byte, keyId []byte, err error) { - keyId = uuid.Parse(keyProtected.Id) + keyUUID, err := uuid.Parse(keyProtected.Id) + if err != nil { + return nil, nil, err + } + keyId = keyUUID[:] mac, err := hex.DecodeString(keyProtected.Crypto.MAC) if err != nil { return nil, nil, err diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go index c072361ea1..10eb886ae2 100644 --- a/accounts/keystore/presale.go +++ b/accounts/keystore/presale.go @@ -27,7 +27,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/pborman/uuid" + "github.com/google/uuid" "golang.org/x/crypto/pbkdf2" ) @@ -37,7 +37,10 @@ func importPreSaleKey(keyStore keyStore, keyJSON []byte, password string) (accou if err != nil { return accounts.Account{}, nil, err } - key.Id = uuid.NewRandom() + key.Id, err = uuid.NewRandom() + if err != nil { + return accounts.Account{}, nil, err + } a := accounts.Account{ Address: key.Address, URL: accounts.URL{ @@ -86,7 +89,7 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error ecKey := crypto.ToECDSAUnsafe(ethPriv) key = &Key{ - Id: nil, + Id: uuid.UUID{}, Address: crypto.PubkeyToAddress(ecKey.PublicKey), PrivateKey: ecKey, } diff --git a/cmd/ethkey/generate.go b/cmd/ethkey/generate.go index 6da3f8beb6..1a549f0286 100644 --- a/cmd/ethkey/generate.go +++ b/cmd/ethkey/generate.go @@ -25,7 +25,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/keystore" "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/pborman/uuid" + "github.com/google/uuid" "github.com/urfave/cli/v2" ) @@ -85,9 +85,12 @@ If you want to encrypt an existing private key, it can be specified by setting } // Create the keyfile object with a random UUID. - id := uuid.NewRandom() + UUID, err := uuid.NewRandom() + if err != nil { + utils.Fatalf("Failed to generate random uuid: %v", err) + } key := &keystore.Key{ - Id: id, + Id: UUID, Address: crypto.PubkeyToAddress(privateKey.PublicKey), PrivateKey: privateKey, } diff --git a/go.mod b/go.mod index 58689e1eb3..2302b43cba 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,6 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 - github.com/pborman/uuid v1.2.0 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 github.com/pkg/errors v0.9.1 github.com/prometheus/prometheus v1.7.2-0.20170814170113-3101606756c5 @@ -52,6 +51,7 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 github.com/go-yaml/yaml v2.1.0+incompatible github.com/google/gofuzz v1.2.0 + github.com/google/uuid v1.6.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c github.com/karalabe/usb v0.0.2 @@ -78,7 +78,6 @@ require ( github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/google/uuid v1.3.0 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index 36ffbcab4c..3f9f3042bc 100644 --- a/go.sum +++ b/go.sum @@ -92,9 +92,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -171,8 +170,6 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= From 345ed3dc36dc6a9d64c8610280d5425c1286700d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 148/280] accounts: eip-712 signing for ledger (#22378) * accounts: eip-712 signing for ledger * address review comments --- accounts/usbwallet/ledger.go | 82 ++++++++++++++++++++++++++++++++++++ accounts/usbwallet/trezor.go | 4 ++ accounts/usbwallet/wallet.go | 42 +++++++++++++++++- 3 files changed, 127 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index b1d5ea7603..2e051d071d 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -52,8 +52,10 @@ const ( ledgerOpRetrieveAddress ledgerOpcode = 0x02 // Returns the public key and Ethereum address for a given BIP 32 path ledgerOpSignTransaction ledgerOpcode = 0x04 // Signs an Ethereum transaction after having the user validate the parameters ledgerOpGetConfiguration ledgerOpcode = 0x06 // Returns specific wallet application configuration + ledgerOpSignTypedMessage ledgerOpcode = 0x0c // Signs an Ethereum message following the EIP 712 specification ledgerP1DirectlyFetchAddress ledgerParam1 = 0x00 // Return address directly from the wallet + ledgerP1InitTypedMessageData ledgerParam1 = 0x00 // First chunk of Typed Message data ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address @@ -170,6 +172,24 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return w.ledgerSign(path, tx, chainID) } +// SignTypedMessage implements usbwallet.driver, sending the message to the Ledger and +// waiting for the user to sign or deny the transaction. +// +// Note: this was introduced in the ledger 1.5.0 firmware +func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) { + // If the Ethereum app doesn't run, abort + if w.offline() { + return nil, accounts.ErrWalletClosed + } + // Ensure the wallet is capable of signing the given transaction + if w.version[0] < 1 && w.version[1] < 5 { + //lint:ignore ST1005 brand name displayed on the console + return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2]) + } + // All infos gathered and metadata checks out, request signing + return w.ledgerSignTypedMessage(path, domainHash, messageHash) +} + // ledgerVersion retrieves the current version of the Ethereum wallet app running // on the Ledger wallet. // @@ -367,6 +387,68 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction return sender, signed, nil } +// ledgerSignTypedMessage sends the transaction to the Ledger wallet, and waits for the user +// to confirm or deny the transaction. +// +// The signing protocol is defined as follows: +// +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+-----------------------------+-----+--- +// E0 | 0C | 00 | implementation version : 00 | variable | variable +// +// Where the input is: +// +// Description | Length +// -------------------------------------------------+---------- +// Number of BIP 32 derivations to perform (max 10) | 1 byte +// First derivation index (big endian) | 4 bytes +// ... | 4 bytes +// Last derivation index (big endian) | 4 bytes +// domain hash | 32 bytes +// message hash | 32 bytes +// +// +// +// And the output data is: +// +// Description | Length +// ------------+--------- +// signature V | 1 byte +// signature R | 32 bytes +// signature S | 32 bytes +func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHash []byte, messageHash []byte) ([]byte, error) { + // Flatten the derivation path into the Ledger request + path := make([]byte, 1+4*len(derivationPath)) + path[0] = byte(len(derivationPath)) + for i, component := range derivationPath { + binary.BigEndian.PutUint32(path[1+4*i:], component) + } + // Create the 712 message + payload := append(path, domainHash...) + payload = append(payload, messageHash...) + + // Send the request and wait for the response + var ( + op = ledgerP1InitTypedMessageData + reply []byte + err error + ) + + // Send the message over, ensuring it's processed correctly + reply, err = w.ledgerExchange(ledgerOpSignTypedMessage, op, 0, payload) + + if err != nil { + return nil, err + } + + // Extract the Ethereum signature and do a sanity validation + if len(reply) != crypto.SignatureLength { + return nil, errors.New("reply lacks signature") + } + signature := append(reply[1:], reply[0]) + return signature, nil +} + // ledgerExchange performs a data exchange with the Ledger wallet, sending it a // message and retrieving the response. // diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index cfc44fbba3..5d36ce9909 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -186,6 +186,10 @@ func (w *trezorDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return w.trezorSign(path, tx, chainID) } +func (w *trezorDriver) SignTypedMessage(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) { + return nil, accounts.ErrNotSupported +} + // trezorDerive sends a derivation request to the Trezor device and returns the // Ethereum address located on that path. func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, error) { diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index d0d219fe54..2eb908048f 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -67,6 +67,8 @@ type driver interface { // SignTx sends the transaction to the USB device and waits for the user to confirm // or deny the transaction. SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error) + + SignTypedMessage(path accounts.DerivationPath, messageHash []byte, domainHash []byte) ([]byte, error) } // wallet represents the common functionality shared by all USB hardware @@ -524,7 +526,45 @@ func (w *wallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) // SignData signs keccak256(data). The mimetype parameter describes the type of data being signed func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - return w.SignHash(account, crypto.Keccak256(data)) + // Unless we are doing 712 signing, simply dispatch to signHash + if !(mimeType == accounts.MimetypeTypedData && len(data) == 66 && data[0] == 0x19 && data[1] == 0x01) { + return w.SignHash(account, crypto.Keccak256(data)) + } + + // dispatch to 712 signing if the mimetype is TypedData and the format matches + w.stateLock.RLock() // Comms have own mutex, this is for the state fields + defer w.stateLock.RUnlock() + + // If the wallet is closed, abort + if w.device == nil { + return nil, accounts.ErrWalletClosed + } + // Make sure the requested account is contained within + path, ok := w.paths[account.Address] + if !ok { + return nil, accounts.ErrUnknownAccount + } + // All infos gathered and metadata checks out, request signing + <-w.commsLock + defer func() { w.commsLock <- struct{}{} }() + + // Ensure the device isn't screwed with while user confirmation is pending + // TODO(karalabe): remove if hotplug lands on Windows + w.hub.commsLock.Lock() + w.hub.commsPend++ + w.hub.commsLock.Unlock() + + defer func() { + w.hub.commsLock.Lock() + w.hub.commsPend-- + w.hub.commsLock.Unlock() + }() + // Sign the transaction + signature, err := w.driver.SignTypedMessage(path, data[2:34], data[34:66]) + if err != nil { + return nil, err + } + return signature, nil } // SignDataWithPassphrase implements accounts.Wallet, attempting to sign the given From da6675f05c8d274d6a6b78ae068a8407e28ada42 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 149/280] accounts: documentation fixes (#22645) * replaces `an chance` with `a chance` * replaces `SignHashWithPassphrase` with `SignTextWithPassphrase` as there was no SignHashWithPasspharse function in the file --- accounts/accounts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 18dc3c49d4..1ee8acff6b 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -126,7 +126,7 @@ type Wallet interface { SignData(account Account, mimeType string, data []byte) ([]byte, error) // SignDataWithPassphrase is identical to SignData, but also takes a password - // NOTE: there's an chance that an erroneous call might mistake the two strings, and + // NOTE: there's a chance that an erroneous call might mistake the two strings, and // supply password in the mimetype field, or vice versa. Thus, an implementation // should never echo the mimetype or return the mimetype in the error-response SignDataWithPassphrase(account Account, passphrase, mimeType string, data []byte) ([]byte, error) @@ -140,7 +140,7 @@ type Wallet interface { // a password to decrypt the account, or a PIN code o verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing - // the needed details via SignHashWithPassphrase, or by other means (e.g. unlock + // the needed details via SignTextWithPassphrase, or by other means (e.g. unlock // the account in a keystore). SignText(account Account, text []byte) ([]byte, error) From c2e71efd65e32079e1625c5cc3c1340d0eb0c21b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 150/280] accounts/abi/bind/backends: add simulated reorgs (#22624) --- accounts/abi/bind/backends/simulated.go | 65 ++++-- accounts/abi/bind/backends/simulated_test.go | 212 +++++++++++++++++-- 2 files changed, 243 insertions(+), 34 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 6641f4ed64..62530c782e 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -143,7 +143,7 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi backend.events = filters.NewEventSystem(backend.filterSystem, false) blockchain.Client = backend - backend.rollback() + backend.rollback(blockchain.CurrentBlock()) return backend } @@ -166,7 +166,7 @@ func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBac backend.filterSystem = filters.NewFilterSystem(filterBackend, filters.Config{}) backend.events = filters.NewEventSystem(backend.filterSystem, false) - backend.rollback() + backend.rollback(blockchain.CurrentBlock()) return backend } @@ -185,7 +185,9 @@ func (b *SimulatedBackend) Commit() { if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil { panic(err) // This cannot happen unless the simulator is wrong, fail in that case } - b.rollback() + // Using the last inserted block here makes it possible to build on a side + // chain after a fork. + b.rollback(b.pendingBlock) } // Rollback aborts all pending transactions, reverting to the last committed state. @@ -193,23 +195,50 @@ func (b *SimulatedBackend) Rollback() { b.mu.Lock() defer b.mu.Unlock() - b.rollback() + b.rollback(b.blockchain.CurrentBlock()) } -func (b *SimulatedBackend) rollback() { - blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(int, *core.BlockGen) {}) +func (b *SimulatedBackend) rollback(parent *types.Block) { + blocks, _ := core.GenerateChain(b.config, parent, b.blockchain.Engine(), b.database, 1, func(int, *core.BlockGen) {}) stateDB, _ := b.blockchain.State() b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database()) } +// Fork creates a side-chain that can be used to simulate reorgs. +// +// This function should be called with the ancestor block where the new side +// chain should be started. Transactions (old and new) can then be applied on +// top and Commit-ed. +// +// Note, the side-chain will only become canonical (and trigger the events) when +// it becomes longer. Until then CallContract will still operate on the current +// canonical chain. +// +// There is a % chance that the side chain becomes canonical at the same length +// to simulate live network behavior. +func (b *SimulatedBackend) Fork(ctx context.Context, parent common.Hash) error { + b.mu.Lock() + defer b.mu.Unlock() + + if len(b.pendingBlock.Transactions()) != 0 { + return errors.New("pending block dirty") + } + block, err := b.blockByHash(ctx, parent) + if err != nil { + return err + } + b.rollback(block) + return nil +} + // stateByBlockNumber retrieves a state by a given blocknumber. func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *big.Int) (*state.StateDB, error) { if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 { return b.blockchain.State() } - block, err := b.blockByNumberNoLock(ctx, blockNumber) + block, err := b.blockByNumber(ctx, blockNumber) if err != nil { return nil, err } @@ -315,6 +344,11 @@ func (b *SimulatedBackend) BlockByHash(ctx context.Context, hash common.Hash) (* b.mu.Lock() defer b.mu.Unlock() + return b.blockByHash(ctx, hash) +} + +// blockByHash retrieves a block based on the block hash without Locking. +func (b *SimulatedBackend) blockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { if hash == b.pendingBlock.Hash() { return b.pendingBlock, nil } @@ -333,12 +367,12 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) ( b.mu.Lock() defer b.mu.Unlock() - return b.blockByNumberNoLock(ctx, number) + return b.blockByNumber(ctx, number) } -// blockByNumberNoLock retrieves a block from the database by number, caching it +// blockByNumber retrieves a block from the database by number, caching it // (associated with its hash) if found without Lock. -func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) { +func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 { return b.blockchain.CurrentBlock(), nil } @@ -671,8 +705,12 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa b.mu.Lock() defer b.mu.Unlock() - // Check transaction validity. - block := b.blockchain.CurrentBlock() + // Get the last block + block, err := b.blockByHash(ctx, b.pendingBlock.ParentHash()) + if err != nil { + panic("could not fetch parent") + } + // Check transaction validity signer := types.MakeSigner(b.blockchain.Config(), block.Number()) sender, err := types.Sender(signer, tx) if err != nil { @@ -682,8 +720,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa if tx.Nonce() != nonce { panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)) } - - // Include tx in chain. + // Include tx in chain blocks, receipts := core.GenerateChain(b.config, block, b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { for _, tx := range b.pendingBlock.Transactions() { block.AddTxWithChain(b.blockchain, tx) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 40d8ae6b7b..4c3aa1aad3 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -21,6 +21,7 @@ import ( "context" "errors" "math/big" + "math/rand" "reflect" "strings" "testing" @@ -136,7 +137,7 @@ func TestNewSimulatedBackend(t *testing.T) { } } -func TestSimulatedBackend_AdjustTime(t *testing.T) { +func TestAdjustTime(t *testing.T) { sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -153,7 +154,7 @@ func TestSimulatedBackend_AdjustTime(t *testing.T) { } } -func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { +func TestNewAdjustTimeFail(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) // Create tx and send @@ -191,7 +192,7 @@ func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) { } } -func TestSimulatedBackend_BalanceAt(t *testing.T) { +func TestBalanceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(10000000000) sim := simTestBackend(testAddr) @@ -208,7 +209,7 @@ func TestSimulatedBackend_BalanceAt(t *testing.T) { } } -func TestSimulatedBackend_BlockByHash(t *testing.T) { +func TestBlockByHash(t *testing.T) { sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -229,7 +230,7 @@ func TestSimulatedBackend_BlockByHash(t *testing.T) { } } -func TestSimulatedBackend_BlockByNumber(t *testing.T) { +func TestBlockByNumber(t *testing.T) { sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -264,7 +265,7 @@ func TestSimulatedBackend_BlockByNumber(t *testing.T) { } } -func TestSimulatedBackend_NonceAt(t *testing.T) { +func TestNonceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -314,7 +315,7 @@ func TestSimulatedBackend_NonceAt(t *testing.T) { } } -func TestSimulatedBackend_SendTransaction(t *testing.T) { +func TestSendTransaction(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -345,7 +346,7 @@ func TestSimulatedBackend_SendTransaction(t *testing.T) { } } -func TestSimulatedBackend_TransactionByHash(t *testing.T) { +func TestTransactionByHash(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := NewSimulatedBackend( @@ -396,7 +397,7 @@ func TestSimulatedBackend_TransactionByHash(t *testing.T) { } } -func TestSimulatedBackend_EstimateGas(t *testing.T) { +func TestEstimateGas(t *testing.T) { /* pragma solidity ^0.6.4; contract GasEstimation { @@ -516,7 +517,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) { } } -func TestSimulatedBackend_HeaderByHash(t *testing.T) { +func TestHeaderByHash(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -537,7 +538,7 @@ func TestSimulatedBackend_HeaderByHash(t *testing.T) { } } -func TestSimulatedBackend_HeaderByNumber(t *testing.T) { +func TestHeaderByNumber(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -584,7 +585,7 @@ func TestSimulatedBackend_HeaderByNumber(t *testing.T) { } } -func TestSimulatedBackend_TransactionCount(t *testing.T) { +func TestTransactionCount(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -634,7 +635,7 @@ func TestSimulatedBackend_TransactionCount(t *testing.T) { } } -func TestSimulatedBackend_TransactionInBlock(t *testing.T) { +func TestTransactionInBlock(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -697,7 +698,7 @@ func TestSimulatedBackend_TransactionInBlock(t *testing.T) { } } -func TestSimulatedBackend_PendingNonceAt(t *testing.T) { +func TestPendingNonceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -759,7 +760,7 @@ func TestSimulatedBackend_PendingNonceAt(t *testing.T) { } } -func TestSimulatedBackend_TransactionReceipt(t *testing.T) { +func TestTransactionReceipt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := NewSimulatedBackend( @@ -794,7 +795,7 @@ func TestSimulatedBackend_TransactionReceipt(t *testing.T) { } } -func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { +func TestSuggestGasPrice(t *testing.T) { sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, @@ -810,7 +811,7 @@ func TestSimulatedBackend_SuggestGasPrice(t *testing.T) { } } -func TestSimulatedBackend_PendingCodeAt(t *testing.T) { +func TestPendingCodeAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -846,7 +847,7 @@ func TestSimulatedBackend_PendingCodeAt(t *testing.T) { } } -func TestSimulatedBackend_CodeAt(t *testing.T) { +func TestCodeAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -886,7 +887,7 @@ func TestSimulatedBackend_CodeAt(t *testing.T) { // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: // // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} -func TestSimulatedBackend_PendingAndCallContract(t *testing.T) { +func TestPendingAndCallContract(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -970,7 +971,7 @@ contract Reverter { } } }*/ -func TestSimulatedBackend_CallContractRevert(t *testing.T) { +func TestCallContractRevert(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) // sim := simTestBackend(testAddr) sim := NewXDCSimulatedBackend(core.GenesisAlloc{testAddr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) @@ -1055,3 +1056,174 @@ func TestSimulatedBackend_CallContractRevert(t *testing.T) { sim.Commit() } } + +// TestFork check that the chain length after a reorg is correct. +// Steps: +// 1. Save the current block which will serve as parent for the fork. +// 2. Mine n blocks with n ∈ [0, 20]. +// 3. Assert that the chain length is n. +// 4. Fork by using the parent block as ancestor. +// 5. Mine n+1 blocks which should trigger a reorg. +// 6. Assert that the chain length is n+1. +// Since Commit() was called 2n+1 times in total, +// having a chain length of just n+1 means that a reorg occurred. +func TestFork(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + // 1. + parent := sim.blockchain.CurrentBlock() + // 2. + n := int(rand.Int31n(21)) + for i := 0; i < n; i++ { + sim.Commit() + } + // 3. + if sim.blockchain.CurrentBlock().NumberU64() != uint64(n) { + t.Error("wrong chain length") + } + // 4. + sim.Fork(context.Background(), parent.Hash()) + // 5. + for i := 0; i < n+1; i++ { + sim.Commit() + } + // 6. + if sim.blockchain.CurrentBlock().NumberU64() != uint64(n+1) { + t.Error("wrong chain length") + } +} + +/* +Example contract to test event emission: + +pragma solidity >=0.7.0 <0.9.0; + + contract Callable { + event Called(); + function Call() public { emit Called(); } + } +*/ +const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806334e2292114602d575b600080fd5b60336035565b005b7f81fab7a4a0aa961db47eefc81f143a5220e8c8495260dd65b1356f1d19d3c7b860405160405180910390a156fea2646970667358221220029436d24f3ac598ceca41d4d712e13ced6d70727f4cdc580667de66d2f51d8b64736f6c63430008010033" + +// TestForkLogsReborn check that the simulated reorgs +// correctly remove and reborn logs. +// Steps: +// 1. Deploy the Callable contract. +// 2. Set up an event subscription. +// 3. Save the current block which will serve as parent for the fork. +// 4. Send a transaction. +// 5. Check that the event was included. +// 6. Fork by using the parent block as ancestor. +// 7. Mine two blocks to trigger a reorg. +// 8. Check that the event was removed. +// 9. Re-send the transaction and mine a block. +// +// 10. Check that the event was reborn. +func TestForkLogsReborn(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + // 1. + parsed, _ := abi.JSON(strings.NewReader(callableAbi)) + auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) + _, _, contract, err := bind.DeployContract(auth, parsed, common.FromHex(callableBin), sim) + if err != nil { + t.Errorf("deploying contract: %v", err) + } + sim.Commit() + // 2. + logs, sub, err := contract.WatchLogs(nil, "Called") + if err != nil { + t.Errorf("watching logs: %v", err) + } + defer sub.Unsubscribe() + // 3. + parent := sim.blockchain.CurrentBlock() + // 4. + tx, err := contract.Transact(auth, "Call") + if err != nil { + t.Errorf("transacting: %v", err) + } + sim.Commit() + // 5. + log := <-logs + if log.TxHash != tx.Hash() { + t.Error("wrong event tx hash") + } + if log.Removed { + t.Error("Event should be included") + } + // 6. + if err := sim.Fork(context.Background(), parent.Hash()); err != nil { + t.Errorf("forking: %v", err) + } + // 7. + sim.Commit() + sim.Commit() + // 8. + log = <-logs + if log.TxHash != tx.Hash() { + t.Error("wrong event tx hash") + } + if !log.Removed { + t.Error("Event should be removed") + } + // 9. + if err := sim.SendTransaction(context.Background(), tx); err != nil { + t.Errorf("sending transaction: %v", err) + } + sim.Commit() + // 10. + log = <-logs + if log.TxHash != tx.Hash() { + t.Error("wrong event tx hash") + } + if log.Removed { + t.Error("Event should be included") + } +} + +// TestForkResendTx checks that re-sending a TX after a fork +// is possible and does not cause a "nonce mismatch" panic. +// Steps: +// 1. Save the current block which will serve as parent for the fork. +// 2. Send a transaction. +// 3. Check that the TX is included in block 1. +// 4. Fork by using the parent block as ancestor. +// 5. Mine a block, Re-send the transaction and mine another one. +// 6. Check that the TX is now included in block 2. +func TestForkResendTx(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + // 1. + parent := sim.blockchain.CurrentBlock() + // 2. + _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) + sim.SendTransaction(context.Background(), tx) + sim.Commit() + // 3. + receipt, _ := sim.TransactionReceipt(context.Background(), tx.Hash()) + if h := receipt.BlockNumber.Uint64(); h != 1 { + t.Errorf("TX included in wrong block: %d", h) + } + // 4. + if err := sim.Fork(context.Background(), parent.Hash()); err != nil { + t.Errorf("forking: %v", err) + } + // 5. + sim.Commit() + if err := sim.SendTransaction(context.Background(), tx); err != nil { + t.Errorf("sending transaction: %v", err) + } + sim.Commit() + // 6. + receipt, _ = sim.TransactionReceipt(context.Background(), tx.Hash()) + if h := receipt.BlockNumber.Uint64(); h != 2 { + t.Errorf("TX included in wrong block: %d", h) + } +} From e26b70e5cc1df797129aa4ec7ec335eeb4651da8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 151/280] accounts/abi/bind: fix sim backend test for 1559 (#23038) --- accounts/abi/bind/backends/simulated_test.go | 155 ++++++++++++++----- accounts/abi/bind/util_test.go | 14 +- 2 files changed, 127 insertions(+), 42 deletions(-) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 4c3aa1aad3..9fe0577364 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -44,7 +44,9 @@ func TestSimulatedBackend(t *testing.T) { genAlloc := make(core.GenesisAlloc) genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} - sim := NewSimulatedBackend(genAlloc, gasLimit) + config := *params.TestXDPoSMockChainConfig + config.Eip1559Block = big.NewInt(0) + sim := NewXDCSimulatedBackend(genAlloc, gasLimit, &config) defer sim.Close() // should return an error if the tx is not found @@ -59,9 +61,12 @@ func TestSimulatedBackend(t *testing.T) { } // generate a transaction and confirm you can retrieve it + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + code := `6060604052600a8060106000396000f360606040526008565b00` var gas uint64 = 3000000 - tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code)) + tx := types.NewContractCreation(0, big.NewInt(0), gas, gasPrice, common.FromHex(code)) tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key) err = sim.SendTransaction(context.Background(), tx) @@ -109,27 +114,23 @@ const deployedCode = `60806040526004361061003b576000357c010000000000000000000000 var expectedReturn = []byte{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, 32, 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, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} func simTestBackend(testAddr common.Address) *SimulatedBackend { - return NewSimulatedBackend( + config := *params.TestXDPoSMockChainConfig + config.Eip1559Block = big.NewInt(0) + return NewXDCSimulatedBackend( core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, + testAddr: {Balance: big.NewInt(100000000000000000)}, + }, + 10000000, + &config, ) } func TestNewSimulatedBackend(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - expectedBal := big.NewInt(10000000000) + expectedBal := big.NewInt(100000000000000000) sim := simTestBackend(testAddr) defer sim.Close() - if sim.config != params.AllEthashProtocolChanges { - t.Errorf("expected sim config to equal params.AllEthashProtocolChanges, got %v", sim.config) - } - - if sim.blockchain.Config() != params.AllEthashProtocolChanges { - t.Errorf("expected sim blockchain config to equal params.AllEthashProtocolChanges, got %v", sim.config) - } - stateDB, _ := sim.blockchain.State() bal := stateDB.GetBalance(testAddr) if bal.Cmp(expectedBal) != 0 { @@ -157,8 +158,13 @@ func TestAdjustTime(t *testing.T) { func TestNewAdjustTimeFail(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) + defer sim.Close() + // Create tx and send - tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -179,7 +185,7 @@ func TestNewAdjustTimeFail(t *testing.T) { t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime) } // Put a transaction after adjusting time - tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx2, err := types.SignTx(tx2, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -194,7 +200,7 @@ func TestNewAdjustTimeFail(t *testing.T) { func TestBalanceAt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - expectedBal := big.NewInt(10000000000) + expectedBal := big.NewInt(100000000000000000) sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -282,7 +288,10 @@ func TestNonceAt(t *testing.T) { } // create a signed transaction to send - tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -323,7 +332,10 @@ func TestSendTransaction(t *testing.T) { bgCtx := context.Background() // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -349,16 +361,15 @@ func TestSendTransaction(t *testing.T) { func TestTransactionByHash(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -517,6 +528,64 @@ func TestEstimateGas(t *testing.T) { } } +func TestEstimateGasWithPrice(t *testing.T) { + key, _ := crypto.GenerateKey() + addr := crypto.PubkeyToAddress(key.PublicKey) + + sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000) + defer sim.Close() + + recipient := common.HexToAddress("deadbeef") + var cases = []struct { + name string + message ethereum.CallMsg + expect uint64 + expectError error + }{ + {"EstimateWithoutPrice", ethereum.CallMsg{ + From: addr, + To: &recipient, + Gas: 0, + GasPrice: big.NewInt(0), + Value: big.NewInt(100000000000), + Data: nil, + }, 21000, nil}, + + {"EstimateWithPrice", ethereum.CallMsg{ + From: addr, + To: &recipient, + Gas: 0, + GasPrice: big.NewInt(100000000000), + Value: big.NewInt(100000000000), + Data: nil, + }, 21000, nil}, + + {"EstimateWithVeryHighPrice", ethereum.CallMsg{ + From: addr, + To: &recipient, + Gas: 0, + GasPrice: big.NewInt(1e14), // gascost = 2.1ether + Value: big.NewInt(1e17), // the remaining balance for fee is 2.1ether + Data: nil, + }, 21000, nil}, + } + for i, c := range cases { + got, err := sim.EstimateGas(context.Background(), c.message) + if c.expectError != nil { + if err == nil { + t.Fatalf("test %d: expect error, got nil", i) + } + if c.expectError.Error() != err.Error() { + t.Fatalf("test %d: expect error, want %v, got %v", i, c.expectError, err) + } + continue + } + if got != c.expect { + t.Fatalf("test %d: gas estimation mismatch, want %d, got %d", i, c.expect, got) + } + } +} + func TestHeaderByHash(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) @@ -606,7 +675,10 @@ func TestTransactionCount(t *testing.T) { } // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -661,7 +733,10 @@ func TestTransactionInBlock(t *testing.T) { } // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -716,7 +791,10 @@ func TestPendingNonceAt(t *testing.T) { } // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -739,7 +817,7 @@ func TestPendingNonceAt(t *testing.T) { } // make a new transaction with a nonce of 1 - tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err = types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -763,16 +841,15 @@ func TestPendingNonceAt(t *testing.T) { func TestTransactionReceipt(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := NewSimulatedBackend( - core.GenesisAlloc{ - testAddr: {Balance: big.NewInt(10000000000)}, - }, 10000000, - ) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() // create a signed transaction to send - tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, testKey) if err != nil { t.Errorf("could not sign tx: %v", err) @@ -973,8 +1050,7 @@ contract Reverter { }*/ func TestCallContractRevert(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - // sim := simTestBackend(testAddr) - sim := NewXDCSimulatedBackend(core.GenesisAlloc{testAddr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := simTestBackend(testAddr) defer sim.Close() bgCtx := context.Background() @@ -1202,7 +1278,10 @@ func TestForkResendTx(t *testing.T) { // 1. parent := sim.blockchain.CurrentBlock() // 2. - _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + + _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) sim.SendTransaction(context.Background(), tx) sim.Commit() diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 3ebc832ccd..04d70729ba 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -104,17 +104,23 @@ func TestWaitDeployed(t *testing.T) { } func TestWaitDeployedCornerCases(t *testing.T) { - backend := backends.NewSimulatedBackend( + config := *params.TestXDPoSMockChainConfig + config.Eip1559Block = big.NewInt(0) + backend := backends.NewXDCSimulatedBackend( core.GenesisAlloc{ - crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)}, + crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(100000000000000000)}, }, 10000000, + &config, ) defer backend.Close() + head, _ := backend.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + // Create a transaction to an account. code := "6060604052600a8060106000396000f360606040526008565b00" - tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code)) + tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, gasPrice, common.FromHex(code)) tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -126,7 +132,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { } // Create a transaction that is not mined. - tx = types.NewContractCreation(1, big.NewInt(0), 3000000, big.NewInt(1), common.FromHex(code)) + tx = types.NewContractCreation(1, big.NewInt(0), 3000000, gasPrice, common.FromHex(code)) tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) go func() { From 74ec7022c223466882e7e7be72ff0e9e5aca088c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 152/280] accounts/abi/bind: replace context.TODO with context.Background (#23088) --- accounts/abi/bind/base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index eac659e7d4..6cde7d0ab0 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -498,7 +498,7 @@ func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event strin // user specified it as such. func ensureContext(ctx context.Context) context.Context { if ctx == nil { - return context.TODO() + return context.Background() } return ctx } From 92d9f7e13ae9d908c7df658859447bb26d8b6e58 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 153/280] accounts/abi/bind: parse ABI only once, create metadata struct (#22583) --- accounts/abi/bind/base.go | 25 +++++++++++++++++++++++ accounts/abi/bind/template.go | 38 ++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 6cde7d0ab0..1343ef9816 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -21,6 +21,8 @@ import ( "errors" "fmt" "math/big" + "strings" + "sync" "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" @@ -80,6 +82,29 @@ type WatchOpts struct { Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } +// MetaData collects all metadata for a bound contract. +type MetaData struct { + mu sync.Mutex + Sigs map[string]string + Bin string + ABI string + ab *abi.ABI +} + +func (m *MetaData) GetAbi() (*abi.ABI, error) { + m.mu.Lock() + defer m.mu.Unlock() + if m.ab != nil { + return m.ab, nil + } + if parsed, err := abi.JSON(strings.NewReader(m.ABI)); err != nil { + return nil, err + } else { + m.ab = &parsed + } + return m.ab, nil +} + // BoundContract is the base wrapper object that reflects a contract on the // Ethereum network. It contains a collection of methods that are used by the // higher level contract bindings to operate. diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 0831872a96..e3f031ade0 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -89,6 +89,7 @@ package {{.Package}} import ( "math/big" "strings" + "errors" ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" @@ -100,6 +101,7 @@ import ( // Reference imports to suppress errors if they are not otherwise used. var ( + _ = errors.New _ = big.NewInt _ = strings.NewReader _ = ethereum.ErrNotFound @@ -119,32 +121,48 @@ var ( {{end}} {{range $contract := .Contracts}} - // {{.Type}}ABI is the input ABI used to generate the binding from. - const {{.Type}}ABI = "{{.InputABI}}" - - {{if $contract.FuncSigs}} - // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. - var {{.Type}}FuncSigs = map[string]string{ + // {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract. + var {{.Type}}MetaData = &bind.MetaData{ + ABI: "{{.InputABI}}", + {{if $contract.FuncSigs -}} + Sigs: map[string]string{ {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", {{end}} - } + }, + {{end -}} + {{if .InputBin -}} + Bin: "0x{{.InputBin}}", + {{end}} + } + // {{.Type}}ABI is the input ABI used to generate the binding from. + // Deprecated: Use {{.Type}}MetaData.ABI instead. + var {{.Type}}ABI = {{.Type}}MetaData.ABI + + {{if $contract.FuncSigs}} + // Deprecated: Use {{.Type}}MetaData.Sigs instead. + // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. + var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs {{end}} {{if .InputBin}} // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. - var {{.Type}}Bin = "0x{{.InputBin}}" + // Deprecated: Use {{.Type}}MetaData.Bin instead. + var {{.Type}}Bin = {{.Type}}MetaData.Bin // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { - parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI)) + parsed, err := {{.Type}}MetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } {{range $pattern, $name := .Libraries}} {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) {{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:], -1) {{end}} - address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) if err != nil { return common.Address{}, nil, nil, err } From 36d3e7dcc2e23848de1830d19dc715b8b60a691a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 154/280] accounts/abi/bind: set Context in TransactOpts (#23188) --- accounts/abi/bind/auth.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 5ed3786064..83e663a057 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -17,6 +17,7 @@ package bind import ( + "context" "crypto/ecdsa" "errors" "io" @@ -72,6 +73,7 @@ func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account } return tx.WithSignature(signer, signature) }, + Context: context.Background(), }, nil } @@ -95,6 +97,7 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { } return tx.WithSignature(signer, signature) }, + Context: context.Background(), } } @@ -131,6 +134,7 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou } return tx.WithSignature(signer, signature) }, + Context: context.Background(), }, nil } @@ -154,5 +158,6 @@ func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*Tr } return tx.WithSignature(signer, signature) }, + Context: context.Background(), }, nil } From 83b7c0eacb9b0eba24302542adcd74a9d788b084 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 155/280] accounts/keystore: add go:build lines (#23468) --- accounts/keystore/watch.go | 1 + accounts/keystore/watch_fallback.go | 1 + 2 files changed, 2 insertions(+) diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index 0a2d142bd9..b587cb95bd 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build (darwin && !ios && cgo) || freebsd || (linux && !arm64) || netbsd || solaris // +build darwin,!ios,cgo freebsd linux,!arm64 netbsd solaris package keystore diff --git a/accounts/keystore/watch_fallback.go b/accounts/keystore/watch_fallback.go index de0e87f8a5..e40eca42fe 100644 --- a/accounts/keystore/watch_fallback.go +++ b/accounts/keystore/watch_fallback.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build (darwin && !cgo) || ios || (linux && arm64) || windows || (!darwin && !freebsd && !linux && !netbsd && !solaris) // +build darwin,!cgo ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris // This is the fallback implementation of directory watching. From e33909649b1513863e17a73ad559aec90edb6e82 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 156/280] cmd/utils: don't enumerate usb when --usb isn't set (#22130) --- cmd/XDC/main.go | 3 ++- cmd/utils/flags.go | 12 ++++++++++-- node/config.go | 4 ++++ p2p/simulations/adapters/docker.go | 1 - p2p/simulations/adapters/exec.go | 1 - p2p/simulations/adapters/inproc.go | 1 - 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index ea6db1d893..d87f5e2b61 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -62,7 +62,8 @@ var ( utils.BootnodesV5Flag, utils.DataDirFlag, utils.KeyStoreDirFlag, - //utils.NoUSBFlag, + utils.NoUSBFlag, // deprecated + utils.USBFlag, utils.SmartCardDaemonPathFlag, //utils.EthashCacheDirFlag, //utils.EthashCachesInMemoryFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 0b3d9a32b0..3e96d68ca9 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -88,6 +88,11 @@ var ( Usage: "Directory for the keystore (default = inside the datadir)", Category: flags.AccountCategory, } + USBFlag = &cli.BoolFlag{ + Name: "usb", + Usage: "Enable monitoring and management of USB hardware wallets", + Category: flags.AccountCategory, + } SmartCardDaemonPathFlag = &cli.StringFlag{ Name: "pcscdpath", Usage: "Path to the smartcard daemon (pcscd) socket file", @@ -1220,8 +1225,11 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { if ctx.IsSet(LightKDFFlag.Name) { cfg.UseLightweightKDF = ctx.Bool(LightKDFFlag.Name) } - if ctx.IsSet(NoUSBFlag.Name) { - cfg.NoUSB = ctx.Bool(NoUSBFlag.Name) + if ctx.IsSet(NoUSBFlag.Name) || cfg.NoUSB { + log.Warn("Option nousb is deprecated and USB is deactivated by default. Use --usb to enable") + } + if ctx.IsSet(USBFlag.Name) { + cfg.USB = ctx.Bool(USBFlag.Name) } if ctx.IsSet(AnnounceTxsFlag.Name) { cfg.AnnounceTxs = ctx.Bool(AnnounceTxsFlag.Name) diff --git a/node/config.go b/node/config.go index b4af885535..f6a261ee4b 100644 --- a/node/config.go +++ b/node/config.go @@ -87,8 +87,12 @@ type Config struct { InsecureUnlockAllowed bool `toml:",omitempty"` // NoUSB disables hardware wallet monitoring and connectivity. + // Deprecated: USB monitoring is disabled by default and must be enabled explicitly. NoUSB bool `toml:",omitempty"` + // USB enables hardware wallet monitoring and connectivity. + USB bool `toml:",omitempty"` + // SmartCardDaemonPath is the path to the smartcard daemon's socket. SmartCardDaemonPath string `toml:",omitempty"` diff --git a/p2p/simulations/adapters/docker.go b/p2p/simulations/adapters/docker.go index 712ad0d895..101f16313c 100644 --- a/p2p/simulations/adapters/docker.go +++ b/p2p/simulations/adapters/docker.go @@ -93,7 +93,6 @@ func (d *DockerAdapter) NewNode(config *NodeConfig) (Node, error) { conf.Stack.P2P.EnableMsgEvents = false conf.Stack.P2P.NoDiscovery = true conf.Stack.P2P.NAT = nil - conf.Stack.NoUSB = true conf.Stack.Logger = log.New("node.id", config.ID.String()) node := &DockerNode{ diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go index 153aa32d64..d9a840f60f 100644 --- a/p2p/simulations/adapters/exec.go +++ b/p2p/simulations/adapters/exec.go @@ -104,7 +104,6 @@ func (e *ExecAdapter) NewNode(config *NodeConfig) (Node, error) { conf.Stack.P2P.EnableMsgEvents = false conf.Stack.P2P.NoDiscovery = true conf.Stack.P2P.NAT = nil - conf.Stack.NoUSB = true // listen on a random localhost port (we'll get the actual port after // starting the node through the RPC admin.nodeInfo method) diff --git a/p2p/simulations/adapters/inproc.go b/p2p/simulations/adapters/inproc.go index 4363e5eaab..2b11b39f07 100644 --- a/p2p/simulations/adapters/inproc.go +++ b/p2p/simulations/adapters/inproc.go @@ -84,7 +84,6 @@ func (sa *SimAdapter) NewNode(config *NodeConfig) (Node, error) { Dialer: sa, EnableMsgEvents: true, }, - NoUSB: true, Logger: log.New("node.id", id.String()), }) if err != nil { From f74eacd2cddf92288ddb03057a95ed5a60ac6620 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 157/280] node: remove dependency on wallet backend packages (#23019) * accounts: new AddBackends method in manager * node,cmd/geth: mv accman backend init to cmd/geth * node,cmd/geth: mv scrypt config downstreawm from node * accounts: use static buffer size for accman sub chan minor fix * accounts,cmd/geth: update accman backends through its event loop * accounts,node: add comments * accounts: un-export newBackendEvent * accounts: use chan instead of wg in newBlockEvent * node: rename isKeyDirEphem * accounts,cmd: AddBackends->AddBackend * accounts: fix potential blocking when adding backend --- accounts/manager.go | 64 +++++++++++++++++++++++++++++-------- cmd/XDC/accountcmd.go | 9 ++++-- cmd/XDC/config.go | 56 +++++++++++++++++++++++++++++++++ node/config.go | 73 +++++++++---------------------------------- node/node.go | 69 ++++++++++++++++++++++++++-------------- 5 files changed, 174 insertions(+), 97 deletions(-) diff --git a/accounts/manager.go b/accounts/manager.go index e2ad6ddc8c..a1f3afed2f 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -25,6 +25,10 @@ import ( "github.com/XinFinOrg/XDPoSChain/event" ) +// managerSubBufferSize determines how many incoming wallet events +// the manager will buffer in its channel. +const managerSubBufferSize = 50 + // Config contains the settings of the global account manager. // // TODO(rjl493456442, karalabe, holiman): Get rid of this when account management @@ -33,18 +37,27 @@ type Config struct { InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed } +// newBackendEvent lets the manager know it should +// track the given backend for wallet updates. +type newBackendEvent struct { + backend Backend + processed chan struct{} // Informs event emitter that backend has been integrated +} + // Manager is an overarching account manager that can communicate with various // backends for signing transactions. type Manager struct { - config *Config // Global account manager configurations - backends map[reflect.Type][]Backend // Index of backends currently registered - updaters []event.Subscription // Wallet update subscriptions for all backends - updates chan WalletEvent // Subscription sink for backend wallet changes - wallets []Wallet // Cache of all wallets from all registered backends + config *Config // Global account manager configurations + backends map[reflect.Type][]Backend // Index of backends currently registered + updaters []event.Subscription // Wallet update subscriptions for all backends + updates chan WalletEvent // Subscription sink for backend wallet changes + newBackends chan newBackendEvent // Incoming backends to be tracked by the manager + wallets []Wallet // Cache of all wallets from all registered backends feed event.Feed // Wallet feed notifying of arrivals/departures quit chan chan error + term chan struct{} // Channel is closed upon termination of the update loop lock sync.RWMutex } @@ -57,7 +70,7 @@ func NewManager(config *Config, backends ...Backend) *Manager { wallets = merge(wallets, backend.Wallets()...) } // Subscribe to wallet notifications from all backends - updates := make(chan WalletEvent, 4*len(backends)) + updates := make(chan WalletEvent, managerSubBufferSize) subs := make([]event.Subscription, len(backends)) for i, backend := range backends { @@ -65,12 +78,14 @@ func NewManager(config *Config, backends ...Backend) *Manager { } // Assemble the account manager and return am := &Manager{ - config: config, - backends: make(map[reflect.Type][]Backend), - updaters: subs, - updates: updates, - wallets: wallets, - quit: make(chan chan error), + config: config, + backends: make(map[reflect.Type][]Backend), + updaters: subs, + updates: updates, + newBackends: make(chan newBackendEvent), + wallets: wallets, + quit: make(chan chan error), + term: make(chan struct{}), } for _, backend := range backends { kind := reflect.TypeOf(backend) @@ -93,6 +108,14 @@ func (am *Manager) Config() *Config { return am.config } +// AddBackend starts the tracking of an additional backend for wallet updates. +// cmd/geth assumes once this func returns the backends have been already integrated. +func (am *Manager) AddBackend(backend Backend) { + done := make(chan struct{}) + am.newBackends <- newBackendEvent{backend, done} + <-done +} + // update is the wallet event loop listening for notifications from the backends // and updating the cache of wallets. func (am *Manager) update() { @@ -122,10 +145,22 @@ func (am *Manager) update() { // Notify any listeners of the event am.feed.Send(event) - + case event := <-am.newBackends: + am.lock.Lock() + // Update caches + backend := event.backend + am.wallets = merge(am.wallets, backend.Wallets()...) + am.updaters = append(am.updaters, backend.Subscribe(am.updates)) + kind := reflect.TypeOf(backend) + am.backends[kind] = append(am.backends[kind], backend) + am.lock.Unlock() + close(event.processed) case errc := <-am.quit: // Manager terminating, return errc <- nil + // Signals event emitters the loop is not receiving values + // to prevent them from getting stuck. + close(am.term) return } } @@ -133,6 +168,9 @@ func (am *Manager) update() { // Backends retrieves the backend(s) with the given type from the account manager. func (am *Manager) Backends(kind reflect.Type) []Backend { + am.lock.RLock() + defer am.lock.RUnlock() + return am.backends[kind] } diff --git a/cmd/XDC/accountcmd.go b/cmd/XDC/accountcmd.go index ae89a698ea..252a109b3d 100644 --- a/cmd/XDC/accountcmd.go +++ b/cmd/XDC/accountcmd.go @@ -302,11 +302,16 @@ func accountCreate(ctx *cli.Context) error { } } utils.SetNodeConfig(ctx, &cfg.Node) - scryptN, scryptP, keydir, err := cfg.Node.AccountConfig() - + keydir, err := cfg.Node.KeyDirConfig() if err != nil { utils.Fatalf("Failed to read configuration: %v", err) } + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if cfg.Node.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx)) diff --git a/cmd/XDC/config.go b/cmd/XDC/config.go index ef0dbbb00d..78c63fdc6a 100644 --- a/cmd/XDC/config.go +++ b/cmd/XDC/config.go @@ -28,6 +28,9 @@ import ( "unicode" "github.com/XinFinOrg/XDPoSChain/XDCx" + "github.com/XinFinOrg/XDPoSChain/accounts/keystore" + "github.com/XinFinOrg/XDPoSChain/accounts/scwallet" + "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet" "github.com/XinFinOrg/XDPoSChain/cmd/utils" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/eth/ethconfig" @@ -207,6 +210,11 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) { if err != nil { utils.Fatalf("Failed to create the protocol stack: %v", err) } + // Node doesn't by default populate account manager backends + if err := setAccountManagerBackends(stack); err != nil { + utils.Fatalf("Failed to set account manager backends: %v", err) + } + utils.SetEthConfig(ctx, stack, &cfg.Eth) if ctx.IsSet(utils.EthStatsURLFlag.Name) { cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name) @@ -335,3 +343,51 @@ func applyMetricConfig(ctx *cli.Context, cfg *XDCConfig) { } } } + +func setAccountManagerBackends(stack *node.Node) error { + conf := stack.Config() + am := stack.AccountManager() + keydir := stack.KeyStoreDir() + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + if conf.UseLightweightKDF { + scryptN = keystore.LightScryptN + scryptP = keystore.LightScryptP + } + + // For now, we're using EITHER external signer OR local signers. + // If/when we implement some form of lockfile for USB and keystore wallets, + // we can have both, but it's very confusing for the user to see the same + // accounts in both externally and locally, plus very racey. + am.AddBackend(keystore.NewKeyStore(keydir, scryptN, scryptP)) + if conf.USB { + // Start a USB hub for Ledger hardware wallets + if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { + log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) + } else { + am.AddBackend(ledgerhub) + } + // Start a USB hub for Trezor hardware wallets (HID version) + if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { + log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) + } else { + am.AddBackend(trezorhub) + } + // Start a USB hub for Trezor hardware wallets (WebUSB version) + if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { + log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) + } else { + am.AddBackend(trezorhub) + } + } + if len(conf.SmartCardDaemonPath) > 0 { + // Start a smart card hub + if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil { + log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) + } else { + am.AddBackend(schub) + } + } + + return nil +} diff --git a/node/config.go b/node/config.go index f6a261ee4b..186d0bc91f 100644 --- a/node/config.go +++ b/node/config.go @@ -24,10 +24,6 @@ import ( "runtime" "strings" - "github.com/XinFinOrg/XDPoSChain/accounts" - "github.com/XinFinOrg/XDPoSChain/accounts/keystore" - "github.com/XinFinOrg/XDPoSChain/accounts/scwallet" - "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" @@ -389,15 +385,8 @@ func (c *Config) parsePersistentNodes(path string) []*discover.Node { return nodes } -// AccountConfig determines the settings for scrypt and keydirectory -func (c *Config) AccountConfig() (int, int, string, error) { - scryptN := keystore.StandardScryptN - scryptP := keystore.StandardScryptP - if c.UseLightweightKDF { - scryptN = keystore.LightScryptN - scryptP = keystore.LightScryptP - } - +// KeyDirConfig determines the settings for keydirectory +func (c *Config) KeyDirConfig() (string, error) { var ( keydir string err error @@ -414,61 +403,29 @@ func (c *Config) AccountConfig() (int, int, string, error) { case c.KeyStoreDir != "": keydir, err = filepath.Abs(c.KeyStoreDir) } - return scryptN, scryptP, keydir, err + return keydir, err } -func makeAccountManager(conf *Config) (*accounts.Manager, string, error) { - scryptN, scryptP, keydir, err := conf.AccountConfig() - var ephemeral string +// getKeyStoreDir retrieves the key directory and will create +// and ephemeral one if necessary. +func getKeyStoreDir(conf *Config) (string, bool, error) { + keydir, err := conf.KeyDirConfig() + if err != nil { + return "", false, err + } + isEphemeral := false if keydir == "" { // There is no datadir. keydir, err = os.MkdirTemp("", "go-ethereum-keystore") - ephemeral = keydir + isEphemeral = true } if err != nil { - return nil, "", err + return "", false, err } if err := os.MkdirAll(keydir, 0700); err != nil { - return nil, "", err - } - // Assemble the account manager and supported backends - var backends []accounts.Backend - if len(backends) == 0 { - // For now, we're using EITHER external signer OR local signers. - // If/when we implement some form of lockfile for USB and keystore wallets, - // we can have both, but it's very confusing for the user to see the same - // accounts in both externally and locally, plus very racey. - backends = append(backends, keystore.NewKeyStore(keydir, scryptN, scryptP)) - if !conf.NoUSB { - // Start a USB hub for Ledger hardware wallets - if ledgerhub, err := usbwallet.NewLedgerHub(); err != nil { - log.Warn(fmt.Sprintf("Failed to start Ledger hub, disabling: %v", err)) - } else { - backends = append(backends, ledgerhub) - } - // Start a USB hub for Trezor hardware wallets (HID version) - if trezorhub, err := usbwallet.NewTrezorHubWithHID(); err != nil { - log.Warn(fmt.Sprintf("Failed to start HID Trezor hub, disabling: %v", err)) - } else { - backends = append(backends, trezorhub) - } - // Start a USB hub for Trezor hardware wallets (WebUSB version) - if trezorhub, err := usbwallet.NewTrezorHubWithWebUSB(); err != nil { - log.Warn(fmt.Sprintf("Failed to start WebUSB Trezor hub, disabling: %v", err)) - } else { - backends = append(backends, trezorhub) - } - } - if len(conf.SmartCardDaemonPath) > 0 { - // Start a smart card hub - if schub, err := scwallet.NewHub(conf.SmartCardDaemonPath, scwallet.Scheme, keydir); err != nil { - log.Warn(fmt.Sprintf("Failed to start smart card hub, disabling: %v", err)) - } else { - backends = append(backends, schub) - } - } + return "", false, err } - return accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}, backends...), ephemeral, nil + return keydir, isEphemeral, nil } diff --git a/node/node.go b/node/node.go index 32201efa3b..d5d1ca433f 100644 --- a/node/node.go +++ b/node/node.go @@ -41,9 +41,12 @@ import ( // Node is a container on which services can be registered. type Node struct { - eventmux *event.TypeMux // Event multiplexer used between the services of a stack - config *Config - accman *accounts.Manager + eventmux *event.TypeMux // Event multiplexer used between the services of a stack + config *Config + accman *accounts.Manager + log log.Logger + keyDir string // key store directory + keyDirTemp bool // If true, key directory will be removed by Stop ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop instanceDirLock flock.Releaser // prevents concurrent use of instance directory @@ -75,8 +78,6 @@ type Node struct { stop chan struct{} // Channel to wait for termination notifications lock sync.RWMutex - - log log.Logger } const ( @@ -96,6 +97,10 @@ func New(conf *Config) (*Node, error) { } conf.DataDir = absdatadir } + if conf.Logger == nil { + conf.Logger = log.New() + } + // Ensure that the instance name doesn't cause weird conflicts with // other files in the data directory. if strings.ContainsAny(conf.Name, `/\`) { @@ -107,28 +112,28 @@ func New(conf *Config) (*Node, error) { if strings.HasSuffix(conf.Name, ".ipc") { return nil, errors.New(`Config.Name cannot end in ".ipc"`) } - // Ensure that the AccountManager method works before the node has started. - // We rely on this in cmd/geth. - am, ephemeralKeystore, err := makeAccountManager(conf) + + node := &Node{ + config: conf, + eventmux: new(event.TypeMux), + log: conf.Logger, + serviceFuncs: []ServiceConstructor{}, + ipcEndpoint: conf.IPCEndpoint(), + httpEndpoint: conf.HTTPEndpoint(), + wsEndpoint: conf.WSEndpoint(), + } + + keyDir, isEphem, err := getKeyStoreDir(conf) if err != nil { return nil, err } - if conf.Logger == nil { - conf.Logger = log.New() - } - // Note: any interaction with Config that would create/touch files - // in the data directory or instance directory is delayed until Start. - return &Node{ - accman: am, - ephemeralKeystore: ephemeralKeystore, - config: conf, - serviceFuncs: []ServiceConstructor{}, - ipcEndpoint: conf.IPCEndpoint(), - httpEndpoint: conf.HTTPEndpoint(), - wsEndpoint: conf.WSEndpoint(), - eventmux: new(event.TypeMux), - log: conf.Logger, - }, nil + node.keyDir = keyDir + node.keyDirTemp = isEphem + // Creates an empty AccountManager with no backends. Callers (e.g. cmd/geth) + // are required to add the backends later on. + node.accman = accounts.NewManager(&accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed}) + + return node, nil } // Close stops the Node and releases resources acquired in @@ -143,6 +148,12 @@ func (n *Node) Close() error { if err := n.accman.Close(); err != nil { errs = append(errs, err) } + if n.keyDirTemp { + if err := os.RemoveAll(n.keyDir); err != nil { + errs = append(errs, err) + } + } + // Report any errors that might have occurred switch len(errs) { case 0: @@ -569,6 +580,11 @@ func (n *Node) RPCHandler() (*rpc.Server, error) { return n.inprocHandler, nil } +// Config returns the configuration of node. +func (n *Node) Config() *Config { + return n.config +} + // Server retrieves the currently running P2P network layer. This method is meant // only to inspect fields of the currently running server, life cycle management // should be left to this Node entity. @@ -608,6 +624,11 @@ func (n *Node) InstanceDir() string { return n.config.instanceDir() } +// KeyStoreDir retrieves the key directory +func (n *Node) KeyStoreDir() string { + return n.keyDir +} + // AccountManager retrieves the account manager used by the protocol stack. func (n *Node) AccountManager() *accounts.Manager { return n.accman From bcae4205e431de349dc73d194d1a6e276d1446f4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 158/280] accounts/keystore: fix flaky tests (#23599) * ethclient/gethclient: fix flaky test (due to map key ordering) * accounts/keystore: fix test failing due to rand collision due to low time resolution on windows --- accounts/keystore/account_cache_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index aa1636efc8..92b26f71bc 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -96,7 +96,7 @@ func TestWatchNoDir(t *testing.T) { // Create ks but not the directory that it watches. rand.Seed(time.Now().UnixNano()) - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watch-test-%d-%d", os.Getpid(), rand.Int())) + dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() @@ -322,7 +322,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { // Create a temporary kesytore to test with rand.Seed(time.Now().UnixNano()) - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watch-test-%d-%d", os.Getpid(), rand.Int())) + dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() From 2b396f29adedc7854ddc6857f24f80d22a335eb9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:12 +0800 Subject: [PATCH 159/280] accounts/abi: fix resolving single struct argument (#23573) --- accounts/abi/argument.go | 2 +- accounts/abi/bind/bind_test.go | 71 ++++++++++++++++++++++++++++++++++ accounts/abi/unpack_test.go | 18 +++++---- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index e6d5245596..261b4d1b86 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -137,7 +137,7 @@ func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{ dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) - if dst.Kind() == reflect.Struct && src.Kind() != reflect.Struct { + if dst.Kind() == reflect.Struct { return set(dst.Field(0), src) } return set(dst, src) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 54a61e79f7..0ba6befa48 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1737,6 +1737,77 @@ var bindTests = []struct { nil, nil, }, + // Test resolving single struct argument + { + `NewSingleStructArgument`, + ` + pragma solidity ^0.8.0; + + contract NewSingleStructArgument { + struct MyStruct{ + uint256 a; + uint256 b; + } + event StructEvent(MyStruct s); + function TestEvent() public { + emit StructEvent(MyStruct({a: 1, b: 2})); + } + } + `, + []string{"608060405234801561001057600080fd5b50610113806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806324ec1d3f14602d575b600080fd5b60336035565b005b7fb4b2ff75e30cb4317eaae16dd8a187dd89978df17565104caa6c2797caae27d460405180604001604052806001815260200160028152506040516078919060ba565b60405180910390a1565b6040820160008201516096600085018260ad565b50602082015160a7602085018260ad565b50505050565b60b48160d3565b82525050565b600060408201905060cd60008301846082565b92915050565b600081905091905056fea26469706673582212208823628796125bf9941ce4eda18da1be3cf2931b231708ab848e1bd7151c0c9a64736f6c63430008070033"}, + []string{`[{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"indexed":false,"internalType":"struct Test.MyStruct","name":"s","type":"tuple"}],"name":"StructEvent","type":"event"},{"inputs":[],"name":"TestEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}]`}, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + var ( + key, _ = crypto.GenerateKey() + user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + ) + defer sim.Close() + + _, _, d, err := DeployNewSingleStructArgument(user, sim) + if err != nil { + t.Fatalf("Failed to deploy contract %v", err) + } + sim.Commit() + + _, err = d.TestEvent(user) + if err != nil { + t.Fatalf("Failed to call contract %v", err) + } + sim.Commit() + + it, err := d.FilterStructEvent(nil) + if err != nil { + t.Fatalf("Failed to filter contract event %v", err) + } + var count int + for it.Next() { + if it.Event.S.A.Cmp(big.NewInt(1)) != 0 { + t.Fatal("Unexpected contract event") + } + if it.Event.S.B.Cmp(big.NewInt(2)) != 0 { + t.Fatal("Unexpected contract event") + } + count += 1 + } + if count != 1 { + t.Fatal("Unexpected contract event number") + } + `, + nil, + nil, + nil, + nil, + }, } // Tests that packages generated by the binder can be successfully compiled and diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 0524d5d3d3..bb259dc0aa 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -762,20 +762,24 @@ func TestUnpackTuple(t *testing.T) { buff.Write(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) // ret[b] = -1 // If the result is single tuple, use struct as return value container directly. - v := struct { + type v struct { A *big.Int B *big.Int - }{new(big.Int), new(big.Int)} + } + type r struct { + Result v + } + var ret0 = new(r) + err = abi.UnpackIntoInterface(ret0, "tuple", buff.Bytes()) - err = abi.UnpackIntoInterface(&v, "tuple", buff.Bytes()) if err != nil { t.Error(err) } else { - if v.A.Cmp(big.NewInt(1)) != 0 { - t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A) + if ret0.Result.A.Cmp(big.NewInt(1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", 1, ret0.Result.A) } - if v.B.Cmp(big.NewInt(-1)) != 0 { - t.Errorf("unexpected value unpacked: want %x, got %x", -1, v.B) + if ret0.Result.B.Cmp(big.NewInt(-1)) != 0 { + t.Errorf("unexpected value unpacked: want %x, got %x", -1, ret0.Result.B) } } From 2af78feca0e21df7a1002c45225b78022bf5ec9c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 160/280] accounts/abi/bind: check event signature before parsing (#23230) * accounts/abi/bind: check event signature before parsing * remove redundant break line --- accounts/abi/bind/base.go | 3 +++ accounts/abi/bind/base_test.go | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 1343ef9816..b24cc58eff 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -505,6 +505,9 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) // UnpackLogIntoMap unpacks a retrieved log into the provided map. func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error { + if log.Topics[0] != c.abi.Events[event].ID { + return fmt.Errorf("event signature mismatch") + } if len(log.Data) > 0 { if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil { return err diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 5bc9eee3fc..2294b1ff04 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -185,7 +185,7 @@ const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16 func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { hash := crypto.Keccak256Hash([]byte("testName")) topics := []common.Hash{ - common.HexToHash("0x0"), + crypto.Keccak256Hash([]byte("received(string,address,uint256,bytes)")), hash, } mockLog := newMockLog(topics, common.HexToHash("0x0")) @@ -210,7 +210,7 @@ func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { } hash := crypto.Keccak256Hash(sliceBytes) topics := []common.Hash{ - common.HexToHash("0x0"), + crypto.Keccak256Hash([]byte("received(string[],address,uint256,bytes)")), hash, } mockLog := newMockLog(topics, common.HexToHash("0x0")) @@ -235,7 +235,7 @@ func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { } hash := crypto.Keccak256Hash(arrBytes) topics := []common.Hash{ - common.HexToHash("0x0"), + crypto.Keccak256Hash([]byte("received(address[2],address,uint256,bytes)")), hash, } mockLog := newMockLog(topics, common.HexToHash("0x0")) @@ -262,7 +262,7 @@ func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { var functionTy [24]byte copy(functionTy[:], functionTyBytes[0:24]) topics := []common.Hash{ - common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + crypto.Keccak256Hash([]byte("received(function,address,uint256,bytes)")), common.BytesToHash(functionTyBytes), } mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) @@ -283,7 +283,7 @@ func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { bytes := []byte{1, 2, 3, 4, 5} hash := crypto.Keccak256Hash(bytes) topics := []common.Hash{ - common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), + crypto.Keccak256Hash([]byte("received(bytes,address,uint256,bytes)")), hash, } mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) From 46a16f914909baf0cf88d316acc731937d269b34 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 161/280] accounts/abi: fix some go-critic linter warnings (#23709) --- accounts/abi/reflect.go | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 4a0274ed35..faa62a642b 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -28,11 +28,13 @@ import ( // given type // e.g. turn // var fields []reflect.StructField -// fields = append(fields, reflect.StructField{ -// Name: "X", -// Type: reflect.TypeOf(new(big.Int)), -// Tag: reflect.StructTag("json:\"" + "x" + "\""), -// } +// +// fields = append(fields, reflect.StructField{ +// Name: "X", +// Type: reflect.TypeOf(new(big.Int)), +// Tag: reflect.StructTag("json:\"" + "x" + "\""), +// } +// // into // type TupleT struct { X *big.Int } func ConvertType(in interface{}, proto interface{}) interface{} { @@ -123,22 +125,15 @@ func set(dst, src reflect.Value) error { func setSlice(dst, src reflect.Value) error { slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) for i := 0; i < src.Len(); i++ { - if src.Index(i).Kind() == reflect.Struct { - if err := set(slice.Index(i), src.Index(i)); err != nil { - return err - } - } else { - // e.g. [][32]uint8 to []common.Hash - if err := set(slice.Index(i), src.Index(i)); err != nil { - return err - } + if err := set(slice.Index(i), src.Index(i)); err != nil { + return err } } if dst.CanSet() { dst.Set(slice) return nil } - return errors.New("Cannot set slice, destination not settable") + return errors.New("cannot set slice, destination not settable") } func setArray(dst, src reflect.Value) error { From 0c9babc95c6f3f8e4ef9f40d9900bda6bd8d5ee0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 162/280] accounts/abi/bind: refactor transact method (#23719) --- accounts/abi/bind/base.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index b24cc58eff..35b8c2cde7 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -24,7 +24,7 @@ import ( "strings" "sync" - "github.com/XinFinOrg/XDPoSChain" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -164,7 +164,7 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return err } var ( - msg = XDPoSChain.CallMsg{From: opts.From, To: &c.address, Data: input, GasPrice: common.MinGasPrice50x, Gas: uint64(4200000)} + msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input, GasPrice: common.MinGasPrice50x, Gas: uint64(4200000)} ctx = ensureContext(opts.Context) code []byte output []byte @@ -339,7 +339,7 @@ func (c *BoundContract) estimateGasLimit(opts *TransactOpts, contract *common.Ad return 0, ErrNoCode } } - msg := XDPoSChain.CallMsg{ + msg := ethereum.CallMsg{ From: opts.From, To: contract, GasPrice: gasPrice, @@ -420,7 +420,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int // Start the background filtering logs := make(chan types.Log, 128) - config := XDPoSChain.FilterQuery{ + config := ethereum.FilterQuery{ Addresses: []common.Address{c.address}, Topics: topics, FromBlock: new(big.Int).SetUint64(opts.Start), @@ -466,7 +466,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter // Start the background filtering logs := make(chan types.Log, 128) - config := XDPoSChain.FilterQuery{ + config := ethereum.FilterQuery{ Addresses: []common.Address{c.address}, Topics: topics, } From 7fb05b7c16cbca5cafad165c5cfcc7591318ef6b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 163/280] accounts/abi: add basic support for error types (#23161) This is the initial step for support of Solidity errors in contract bindings. As of this change, errors can be decoded, but are not supported in bindings yet. Closes #23157 --- accounts/abi/abi.go | 55 +++++++---------- accounts/abi/abi_test.go | 14 +++++ accounts/abi/bind/bind_test.go | 55 +++++++++++++++++ accounts/abi/error.go | 107 ++++++++++++++++++--------------- accounts/abi/error_handling.go | 82 +++++++++++++++++++++++++ 5 files changed, 232 insertions(+), 81 deletions(-) create mode 100644 accounts/abi/error_handling.go diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 574829b328..a60d76dd4a 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -34,6 +34,7 @@ type ABI struct { Constructor Method Methods map[string]Method Events map[string]Event + Errors map[string]Error // Additional "special" functions introduced in solidity v0.6.0. // It's separated from the original default fallback. Each contract @@ -157,12 +158,13 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } abi.Methods = make(map[string]Method) abi.Events = make(map[string]Event) + abi.Errors = make(map[string]Error) for _, field := range fields { switch field.Type { case "constructor": abi.Constructor = NewMethod("", "", Constructor, field.StateMutability, field.Constant, field.Payable, field.Inputs, nil) case "function": - name := abi.overloadedMethodName(field.Name) + name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Methods[s]; return ok }) abi.Methods[name] = NewMethod(name, field.Name, Function, field.StateMutability, field.Constant, field.Payable, field.Inputs, field.Outputs) case "fallback": // New introduced function type in v0.6.0, check more detail @@ -182,8 +184,10 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } abi.Receive = NewMethod("", "", Receive, field.StateMutability, field.Constant, field.Payable, nil, nil) case "event": - name := abi.overloadedEventName(field.Name) + name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Events[s]; return ok }) abi.Events[name] = NewEvent(name, field.Name, field.Anonymous, field.Inputs) + case "error": + abi.Errors[field.Name] = NewError(field.Name, field.Inputs) default: return fmt.Errorf("abi: could not recognize type %v of field %v", field.Type, field.Name) } @@ -191,36 +195,6 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { return nil } -// overloadedMethodName returns the next available name for a given function. -// Needed since solidity allows for function overload. -// -// e.g. if the abi contains Methods send, send1 -// overloadedMethodName would return send2 for input send. -func (abi *ABI) overloadedMethodName(rawName string) string { - name := rawName - _, ok := abi.Methods[name] - for idx := 0; ok; idx++ { - name = fmt.Sprintf("%s%d", rawName, idx) - _, ok = abi.Methods[name] - } - return name -} - -// overloadedEventName returns the next available name for a given event. -// Needed since solidity allows for event overload. -// -// e.g. if the abi contains events received, received1 -// overloadedEventName would return received2 for input received. -func (abi *ABI) overloadedEventName(rawName string) string { - name := rawName - _, ok := abi.Events[name] - for idx := 0; ok; idx++ { - name = fmt.Sprintf("%s%d", rawName, idx) - _, ok = abi.Events[name] - } - return name -} - // MethodById looks up a method by the 4-byte id, // returns nil if none found. func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { @@ -277,3 +251,20 @@ func UnpackRevert(data []byte) (string, error) { } return unpacked[0].(string), nil } + +// overloadedName returns the next available name for a given thing. +// Needed since solidity allows for overloading. +// +// e.g. if the abi contains Methods send, send1 +// overloadedName would return send2 for input send. +// +// overloadedName works for methods, events and errors. +func overloadedName(rawName string, isAvail func(string) bool) string { + name := rawName + ok := isAvail(name) + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", rawName, idx) + ok = isAvail(name) + } + return name +} diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index f3f934a201..7736892040 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -295,6 +295,20 @@ func TestOverloadedMethodSignature(t *testing.T) { check("bar0", "bar(uint256,uint256)", false) } +func TestCustomErrors(t *testing.T) { + json := `[{ "inputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ],"name": "MyError", "type": "error"} ]` + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + check := func(name string, expect string) { + if abi.Errors[name].Sig != expect { + t.Fatalf("The signature of overloaded method mismatch, want %s, have %s", expect, abi.Methods[name].Sig) + } + } + check("MyError", "MyError(uint256)") +} + func TestMultiPack(t *testing.T) { abi, err := JSON(strings.NewReader(jsondata)) if err != nil { diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 0ba6befa48..05ecda79a2 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1802,6 +1802,61 @@ var bindTests = []struct { if count != 1 { t.Fatal("Unexpected contract event number") } + `, + nil, + nil, + nil, + nil, + }, + // Test errors introduced in v0.8.4 + { + `NewErrors`, + ` + pragma solidity >0.8.4; + + contract NewErrors { + error MyError(uint256); + error MyError1(uint256); + error MyError2(uint256, uint256); + error MyError3(uint256 a, uint256 b, uint256 c); + function Error() public pure { + revert MyError3(1,2,3); + } + } + `, + []string{"0x6080604052348015600f57600080fd5b5060998061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063726c638214602d575b600080fd5b60336035565b005b60405163024876cd60e61b815260016004820152600260248201526003604482015260640160405180910390fdfea264697066735822122093f786a1bc60216540cd999fbb4a6109e0fef20abcff6e9107fb2817ca968f3c64736f6c63430008070033"}, + []string{`[{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError1","type":"error"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"MyError2","type":"error"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"},{"internalType":"uint256","name":"c","type":"uint256"}],"name":"MyError3","type":"error"},{"inputs":[],"name":"Error","outputs":[],"stateMutability":"pure","type":"function"}]`}, + ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + ` + var ( + key, _ = crypto.GenerateKey() + user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + ) + defer sim.Close() + + _, tx, contract, err := DeployNewErrors(user, sim) + if err != nil { + t.Fatal(err) + } + sim.Commit() + _, err = bind.WaitDeployed(nil, sim, tx) + if err != nil { + t.Error(err) + } + if err := contract.Error(new(bind.CallOpts)); err == nil { + t.Fatalf("expected contract to throw error") + } + // TODO (MariusVanDerWijden unpack error using abigen + // once that is implemented `, nil, nil, diff --git a/accounts/abi/error.go b/accounts/abi/error.go index f0f71b6c91..bd0f32ae2a 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -1,4 +1,4 @@ -// Copyright 2016 The go-ethereum Authors +// Copyright 2021 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 @@ -17,66 +17,75 @@ package abi import ( + "bytes" "errors" "fmt" - "reflect" + "strings" + + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/crypto" ) -var ( - errBadBool = errors.New("abi: improperly encoded boolean value") -) - -// formatSliceString formats the reflection kind with the given slice size -// and returns a formatted string representation. -func formatSliceString(kind reflect.Kind, sliceSize int) string { - if sliceSize == -1 { - return fmt.Sprintf("[]%v", kind) - } - return fmt.Sprintf("[%d]%v", sliceSize, kind) +type Error struct { + Name string + Inputs Arguments + str string + // Sig contains the string signature according to the ABI spec. + // e.g. event foo(uint32 a, int b) = "foo(uint32,int256)" + // Please note that "int" is substitute for its canonical representation "int256" + Sig string + // ID returns the canonical representation of the event's signature used by the + // abi definition to identify event names and types. + ID common.Hash } -// sliceTypeCheck checks that the given slice can by assigned to the reflection -// type in t. -func sliceTypeCheck(t Type, val reflect.Value) error { - if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { - return typeErr(formatSliceString(t.GetType().Kind(), t.Size), val.Type()) - } - - if t.T == ArrayTy && val.Len() != t.Size { - return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) - } - - if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { - if val.Len() > 0 { - return sliceTypeCheck(*t.Elem, val.Index(0)) +func NewError(name string, inputs Arguments) Error { + // sanitize inputs to remove inputs without names + // and precompute string and sig representation. + names := make([]string, len(inputs)) + types := make([]string, len(inputs)) + for i, input := range inputs { + if input.Name == "" { + inputs[i] = Argument{ + Name: fmt.Sprintf("arg%d", i), + Indexed: input.Indexed, + Type: input.Type, + } + } else { + inputs[i] = input } + // string representation + names[i] = fmt.Sprintf("%v %v", input.Type, inputs[i].Name) + if input.Indexed { + names[i] = fmt.Sprintf("%v indexed %v", input.Type, inputs[i].Name) + } + // sig representation + types[i] = input.Type.String() } - if val.Type().Elem().Kind() != t.Elem.GetType().Kind() { - return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), val.Type()) + str := fmt.Sprintf("error %v(%v)", name, strings.Join(names, ", ")) + sig := fmt.Sprintf("%v(%v)", name, strings.Join(types, ",")) + id := common.BytesToHash(crypto.Keccak256([]byte(sig))) + + return Error{ + Name: name, + Inputs: inputs, + str: str, + Sig: sig, + ID: id, } - return nil } -// typeCheck checks that the given reflection value can be assigned to the reflection -// type in t. -func typeCheck(t Type, value reflect.Value) error { - if t.T == SliceTy || t.T == ArrayTy { - return sliceTypeCheck(t, value) - } - - // Check base type validity. Element types will be checked later on. - if t.GetType().Kind() != value.Kind() { - return typeErr(t.GetType().Kind(), value.Kind()) - } else if t.T == FixedBytesTy && t.Size != value.Len() { - return typeErr(t.GetType(), value.Type()) - } else { - return nil - } - +func (e *Error) String() string { + return e.str } -// typeErr returns a formatted type casting error. -func typeErr(expected, got interface{}) error { - return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected) +func (e *Error) Unpack(data []byte) (interface{}, error) { + if len(data) < 4 { + return "", errors.New("invalid data for unpacking") + } + if !bytes.Equal(data[:4], e.ID[:4]) { + return "", errors.New("invalid data for unpacking") + } + return e.Inputs.Unpack(data[4:]) } diff --git a/accounts/abi/error_handling.go b/accounts/abi/error_handling.go new file mode 100644 index 0000000000..f0f71b6c91 --- /dev/null +++ b/accounts/abi/error_handling.go @@ -0,0 +1,82 @@ +// Copyright 2016 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 . + +package abi + +import ( + "errors" + "fmt" + "reflect" +) + +var ( + errBadBool = errors.New("abi: improperly encoded boolean value") +) + +// formatSliceString formats the reflection kind with the given slice size +// and returns a formatted string representation. +func formatSliceString(kind reflect.Kind, sliceSize int) string { + if sliceSize == -1 { + return fmt.Sprintf("[]%v", kind) + } + return fmt.Sprintf("[%d]%v", sliceSize, kind) +} + +// sliceTypeCheck checks that the given slice can by assigned to the reflection +// type in t. +func sliceTypeCheck(t Type, val reflect.Value) error { + if val.Kind() != reflect.Slice && val.Kind() != reflect.Array { + return typeErr(formatSliceString(t.GetType().Kind(), t.Size), val.Type()) + } + + if t.T == ArrayTy && val.Len() != t.Size { + return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len())) + } + + if t.Elem.T == SliceTy || t.Elem.T == ArrayTy { + if val.Len() > 0 { + return sliceTypeCheck(*t.Elem, val.Index(0)) + } + } + + if val.Type().Elem().Kind() != t.Elem.GetType().Kind() { + return typeErr(formatSliceString(t.Elem.GetType().Kind(), t.Size), val.Type()) + } + return nil +} + +// typeCheck checks that the given reflection value can be assigned to the reflection +// type in t. +func typeCheck(t Type, value reflect.Value) error { + if t.T == SliceTy || t.T == ArrayTy { + return sliceTypeCheck(t, value) + } + + // Check base type validity. Element types will be checked later on. + if t.GetType().Kind() != value.Kind() { + return typeErr(t.GetType().Kind(), value.Kind()) + } else if t.T == FixedBytesTy && t.Size != value.Len() { + return typeErr(t.GetType(), value.Type()) + } else { + return nil + } + +} + +// typeErr returns a formatted type casting error. +func typeErr(expected, got interface{}) error { + return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected) +} From 65c3ad5cbadd73c14addbcfc7f46a0c9a44f463a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 164/280] accounts/abi/bin/backends: return basefee in suggestGasPrice (#23838) Co-authored-by: mrx --- accounts/abi/bind/backends/simulated_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 9fe0577364..2432f11a39 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -883,8 +883,12 @@ func TestSuggestGasPrice(t *testing.T) { if err != nil { t.Errorf("could not get gas price: %v", err) } - if gasPrice.Uint64() != uint64(1) { - t.Errorf("gas price was not expected value of 1. actual: %v", gasPrice.Uint64()) + baseFee := sim.pendingBlock.Header().BaseFee + if baseFee == nil { + baseFee = big.NewInt(1) + } + if gasPrice.Uint64() != baseFee.Uint64() { + t.Errorf("gas price was not expected value of %v. actual: %v", sim.pendingBlock.Header().BaseFee.Uint64(), gasPrice.Uint64()) } } From bdf9d80b56faf0293a22f9f6e769c8c4f752d93d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 165/280] accounts/abi/bind/backends: fix race condition in simulated backend (#23898) Now that `SimulatedBackend.SuggestGasPrice` inspects member values, a lock needs to be added to prevent a race condition. --- accounts/abi/bind/backends/simulated.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 62530c782e..0fff0f8fb5 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -549,6 +549,9 @@ func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Ad // SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated // chain doesn't have miners, we just return a gas price of 1 for any call. func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { + b.mu.Lock() + defer b.mu.Unlock() + if b.pendingBlock.Header().BaseFee != nil { return b.pendingBlock.Header().BaseFee, nil } From b33307eaeac621b14b15f0b636d5c33642fef836 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 166/280] accounts/abi/bind: correctly handle structs used only as constructor params (#23940) The `structs` map is populated by iterating over all methods except the constructor, which results in a nil-pointer dereference. I've first reproduced the problem with a new test and then implemented the fix. Co-authored-by: Arran Schlosberg --- accounts/abi/bind/bind.go | 7 +++ accounts/abi/bind/bind_test.go | 84 ++++++++++++++++++++++++++-------- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 0d2a0cc0a5..c8ef5d0cfd 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -85,6 +85,13 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] transactIdentifiers = make(map[string]bool) eventIdentifiers = make(map[string]bool) ) + + for _, input := range evmABI.Constructor.Inputs { + if hasStruct(input.Type) { + bindStructType[lang](input.Type, structs) + } + } + for _, original := range evmABI.Methods { // Normalize the method for capital cases and non-anonymous inputs/outputs normalized := original diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 05ecda79a2..8393ada957 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1863,6 +1863,50 @@ var bindTests = []struct { nil, nil, }, + { + name: `ConstructorWithStructParam`, + contract: ` + pragma solidity >=0.8.0 <0.9.0; + + contract ConstructorWithStructParam { + struct StructType { + uint256 field; + } + + constructor(StructType memory st) {} + } + `, + bytecode: []string{`0x608060405234801561001057600080fd5b506040516101c43803806101c48339818101604052810190610032919061014a565b50610177565b6000604051905090565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100958261004c565b810181811067ffffffffffffffff821117156100b4576100b361005d565b5b80604052505050565b60006100c7610038565b90506100d3828261008c565b919050565b6000819050919050565b6100eb816100d8565b81146100f657600080fd5b50565b600081519050610108816100e2565b92915050565b60006020828403121561012457610123610047565b5b61012e60206100bd565b9050600061013e848285016100f9565b60008301525092915050565b6000602082840312156101605761015f610042565b5b600061016e8482850161010e565b91505092915050565b603f806101856000396000f3fe6080604052600080fdfea2646970667358221220cdffa667affecefac5561f65f4a4ba914204a8d4eb859d8cd426fb306e5c12a364736f6c634300080a0033`}, + abi: []string{`[{"inputs":[{"components":[{"internalType":"uint256","name":"field","type":"uint256"}],"internalType":"struct ConstructorWithStructParam.StructType","name":"st","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"}]`}, + imports: ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + tester: ` + var ( + key, _ = crypto.GenerateKey() + user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + ) + defer sim.Close() + + _, tx, _, err := DeployConstructorWithStructParam(user, sim, ConstructorWithStructParamStructType{Field: big.NewInt(42)}) + if err != nil { + t.Fatalf("DeployConstructorWithStructParam() got err %v; want nil err", err) + } + sim.Commit() + + if _, err = bind.WaitDeployed(nil, sim, tx); err != nil { + t.Logf("Deployment tx: %+v", tx) + t.Errorf("bind.WaitDeployed(nil, %T, ) got err %v; want nil err", sim, err) + } + `, + }, } // Tests that packages generated by the binder can be successfully compiled and @@ -1887,22 +1931,23 @@ func TestGolangBindings(t *testing.T) { } // Generate the test suite for all the contracts for i, tt := range bindTests { - var types []string - if tt.types != nil { - types = tt.types - } else { - types = []string{tt.name} - } - // Generate the binding and create a Go source file in the workspace - bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs, tt.aliases) - if err != nil { - t.Fatalf("test %d: failed to generate binding: %v", i, err) - } - if err = os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil { - t.Fatalf("test %d: failed to write binding: %v", i, err) - } - // Generate the test file with the injected test code - code := fmt.Sprintf(` + t.Run(tt.name, func(t *testing.T) { + var types []string + if tt.types != nil { + types = tt.types + } else { + types = []string{tt.name} + } + // Generate the binding and create a Go source file in the workspace + bind, err := Bind(types, tt.abi, tt.bytecode, tt.fsigs, "bindtest", LangGo, tt.libs, tt.aliases) + if err != nil { + t.Fatalf("test %d: failed to generate binding: %v", i, err) + } + if err = os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil { + t.Fatalf("test %d: failed to write binding: %v", i, err) + } + // Generate the test file with the injected test code + code := fmt.Sprintf(` package bindtest import ( @@ -1914,9 +1959,10 @@ func TestGolangBindings(t *testing.T) { %s } `, tt.imports, tt.name, tt.tester) - if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), []byte(code), 0600); err != nil { - t.Fatalf("test %d: failed to write tests: %v", i, err) - } + if err := os.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), []byte(code), 0600); err != nil { + t.Fatalf("test %d: failed to write tests: %v", i, err) + } + }) } // Convert the package to go modules and use the current source for go-ethereum moder := exec.Command(gocmd, "mod", "init", "bindtest") From c5acd6822de6d9c736579ec4ed9a706528d13048 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 167/280] accounts/abi: avoid unnecessary alloc (#24128) --- accounts/abi/unpack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 4bafd5b6df..45196c7a1a 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -291,7 +291,7 @@ func tuplePointsTo(index int, output []byte) (start int, err error) { offset := big.NewInt(0).SetBytes(output[index : index+32]) outputLen := big.NewInt(int64(len(output))) - if offset.Cmp(big.NewInt(int64(len(output)))) > 0 { + if offset.Cmp(outputLen) > 0 { return 0, fmt.Errorf("abi: cannot marshal in to go slice: offset %v would go over slice boundary (len=%v)", offset, outputLen) } if offset.BitLen() > 63 { From d89e2d6734b3e020023a26f70af81144a38d77b4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 168/280] accounts: fix comments (#24186) --- accounts/accounts.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 1ee8acff6b..606ffc99e7 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -187,7 +187,7 @@ type Backend interface { // TextHash is a helper function that calculates a hash for the given message that can be // safely used to calculate a signature from. // -// The hash is calulcated as +// The hash is calculated as // // keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). // @@ -200,7 +200,7 @@ func TextHash(data []byte) []byte { // TextAndHash is a helper function that calculates a hash for the given message that can be // safely used to calculate a signature from. // -// The hash is calulcated as +// The hash is calculated as // // keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). // From 78fd3b44d79a832540269cf69a2d8ee7dc71e005 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 169/280] accounts: corrected spelling mistakes (#24194) Co-authored-by: sanskar khare --- accounts/accounts.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 606ffc99e7..70581dddd1 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -89,7 +89,7 @@ type Wallet interface { // accounts. // // Note, self derivation will increment the last component of the specified path - // opposed to decending into a child path to allow discovering accounts starting + // opposed to descending into a child path to allow discovering accounts starting // from non zero components. // // Some hardware wallets switched derivation paths through their evolution, so @@ -118,7 +118,7 @@ type Wallet interface { // or optionally with the aid of any location metadata from the embedded URL field. // // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code o verify the transaction), + // a password to decrypt the account, or a PIN code to verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing // the needed details via SignDataWithPassphrase, or by other means (e.g. unlock @@ -137,11 +137,13 @@ type Wallet interface { // or optionally with the aid of any location metadata from the embedded URL field. // // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code o verify the transaction), + // a password to decrypt the account, or a PIN code to verify the transaction), // an AuthNeededError instance will be returned, containing infos for the user // about which fields or actions are needed. The user may retry by providing // the needed details via SignTextWithPassphrase, or by other means (e.g. unlock // the account in a keystore). + // + // This method should return the signature in 'canonical' format, with v 0 or 1. SignText(account Account, text []byte) ([]byte, error) // SignTextWithPassphrase is identical to Signtext, but also takes a password From 9e82b201c77cfae346c1600dbacae68ffc7b1546 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 170/280] accouts/scwallet: typo fix (#24207) --- accounts/scwallet/wallet.go | 2 +- accounts/usbwallet/wallet.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 60f1d55b5d..d643a6839a 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -638,7 +638,7 @@ func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun // accounts. // // Note, self derivation will increment the last component of the specified path -// opposed to decending into a child path to allow discovering accounts starting +// opposed to descending into a child path to allow discovering accounts starting // from non zero components. // // Some hardware wallets switched derivation paths through their evolution, so diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 2eb908048f..f8e331c6dd 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -496,7 +496,7 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun // accounts. // // Note, self derivation will increment the last component of the specified path -// opposed to decending into a child path to allow discovering accounts starting +// opposed to descending into a child path to allow discovering accounts starting // from non zero components. // // Some hardware wallets switched derivation paths through their evolution, so From 4f7123c3c0807040da8fc38949405c51ef07f45d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 171/280] accounts/abi/bind/backends: return errors instead of panic (#24242) --- accounts/abi/bind/backends/simulated.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 0fff0f8fb5..2abe3c3539 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -703,7 +703,6 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM } // SendTransaction updates the pending block to include the given transaction. -// It panics if the transaction is invalid. func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { b.mu.Lock() defer b.mu.Unlock() @@ -711,17 +710,17 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa // Get the last block block, err := b.blockByHash(ctx, b.pendingBlock.ParentHash()) if err != nil { - panic("could not fetch parent") + return fmt.Errorf("could not fetch parent") } // Check transaction validity signer := types.MakeSigner(b.blockchain.Config(), block.Number()) sender, err := types.Sender(signer, tx) if err != nil { - panic(fmt.Errorf("invalid transaction: %v", err)) + return fmt.Errorf("invalid transaction: %v", err) } nonce := b.pendingState.GetNonce(sender) if tx.Nonce() != nonce { - panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce)) + return fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce) } // Include tx in chain blocks, receipts := core.GenerateChain(b.config, block, b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { From c55d8c8bab4b0f302e2ac6af6e513a9b6e65462f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 172/280] accounts: fix typo in errors.go (#24270) --- accounts/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/errors.go b/accounts/errors.go index 2fed35f9d0..727e5329be 100644 --- a/accounts/errors.go +++ b/accounts/errors.go @@ -42,7 +42,7 @@ var ErrInvalidPassphrase = errors.New("invalid password") var ErrWalletAlreadyOpen = errors.New("wallet already open") // ErrWalletClosed is returned if a wallet is attempted to be opened the -// secodn time. +// second time. var ErrWalletClosed = errors.New("wallet closed") // AuthNeededError is returned by backends for signing requests where the user From c78cc1e8f8025c4f08061fe8bd96622983bf8115 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 173/280] accounts/abi: simplify Arguments.Unpack (#24277) Since len(nonIndexedArgs) is definitely 0 in this context, the code can be simplified. --- accounts/abi/argument.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 261b4d1b86..e6c117fe5f 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -81,13 +81,7 @@ func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { if len(arguments) != 0 { return nil, fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") } - // Nothing to unmarshal, return default variables - nonIndexedArgs := arguments.NonIndexed() - defaultVars := make([]interface{}, len(nonIndexedArgs)) - for index, arg := range nonIndexedArgs { - defaultVars[index] = reflect.New(arg.Type.GetType()) - } - return defaultVars, nil + return make([]interface{}, 0), nil } return arguments.UnpackValues(data) } From f22046701f931e0e4ba676c418c15256e7a4c690 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 174/280] accounts: correct spelling mistake (#24323) I believe the sentence is attempting to explain that the URL is "[used] by upper layers to define a sorting order over all wallets from multiple backends." --- accounts/accounts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 70581dddd1..359c4f680e 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -46,7 +46,7 @@ const ( // accounts (derived from the same seed). type Wallet interface { // URL retrieves the canonical path under which this wallet is reachable. It is - // user by upper layers to define a sorting order over all wallets from multiple + // used by upper layers to define a sorting order over all wallets from multiple // backends. URL() URL From 8b9138521eaffb3ef13d8ee28ce2c720fcb44a4f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 175/280] accounts/abi/bind: improve WaitMined error handling (#24321) This change makes it so WaitMined no longer logs an error when the receipt is unavailable. It also changes the simulated backend to return NotFound for unavailable receipts, just like ethclient does. --- accounts/abi/bind/backends/simulated.go | 3 +++ accounts/abi/bind/util.go | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 2abe3c3539..32a1409070 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -317,6 +317,9 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common defer b.mu.Unlock() receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config) + if receipt == nil { + return nil, ethereum.ErrNotFound + } return receipt, nil } diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go index dec604a801..0b16b6764c 100644 --- a/accounts/abi/bind/util.go +++ b/accounts/abi/bind/util.go @@ -21,6 +21,7 @@ import ( "errors" "time" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/log" @@ -35,14 +36,16 @@ func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*ty logger := log.New("hash", tx.Hash()) for { receipt, err := b.TransactionReceipt(ctx, tx.Hash()) - if receipt != nil { + if err == nil { return receipt, nil } - if err != nil { - logger.Trace("Receipt retrieval failed", "err", err) - } else { + + if errors.Is(err, ethereum.ErrNotFound) { logger.Trace("Transaction not yet mined") + } else { + logger.Trace("Receipt retrieval failed", "err", err) } + // Wait for the next round. select { case <-ctx.Done(): From 5b10b2441c3644b1ad057e40e0d7279b414d4a19 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 176/280] all: use T.TempDir to create temporary test directories (#24633) --- accounts/abi/bind/backends/simulated.go | 8 +--- accounts/abi/bind/bind_test.go | 8 +--- accounts/keystore/account_cache_test.go | 1 - accounts/keystore/keystore_test.go | 39 ++++++------------- accounts/keystore/plain_test.go | 16 ++------ cmd/XDC/accountcmd_test.go | 8 ++-- cmd/XDC/consolecmd_test.go | 13 ++----- cmd/XDC/dao_test.go | 3 +- cmd/XDC/run_test.go | 17 +------- cmd/ethkey/message_test.go | 7 +--- cmd/utils/flags_test.go | 15 ++----- .../XDPoS/engines/engine_v2/forensics_test.go | 8 +--- .../XDPoS/engines/engine_v2/snapshot_test.go | 6 +-- consensus/ethash/algorithm_test.go | 2 + consensus/ethash/ethash_test.go | 2 + consensus/tests/engine_v2_tests/helper.go | 8 +--- console/console_test.go | 5 +-- core/bench_test.go | 18 ++------- eth/filters/filter_test.go | 15 ++----- internal/guide/guide_test.go | 7 +--- internal/jsre/jsre_test.go | 18 +++------ node/config_test.go | 17 +++----- node/node_test.go | 7 +--- node/service_test.go | 6 +-- p2p/discover/database_test.go | 7 +--- p2p/discv5/database_test.go | 7 +--- trie/trie_test.go | 11 ++---- 27 files changed, 73 insertions(+), 206 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 32a1409070..eb3026f184 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -86,13 +86,9 @@ func SimulateWalletAddressAndSignFn() (common.Address, func(account accounts.Acc veryLightScryptN := 2 veryLightScryptP := 1 dir, _ := os.MkdirTemp("", "eth-SimulateWalletAddressAndSignFn-test") - - new := func(kd string) *keystore.KeyStore { - return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) - } - defer os.RemoveAll(dir) - ks := new(dir) + + ks := keystore.NewKeyStore(dir, veryLightScryptN, veryLightScryptP) pass := "" // not used but required by API a1, err := ks.NewAccount(pass) if err != nil { diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 8393ada957..a2ce6b8f4d 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1919,14 +1919,10 @@ func TestGolangBindings(t *testing.T) { } t.Log("Using config", params.TestXDPoSMockChainConfig) // Create a temporary workspace for the test suite - ws, err := os.MkdirTemp("", "binding-test") - if err != nil { - t.Fatalf("failed to create temporary workspace: %v", err) - } - // defer os.RemoveAll(ws) + ws := t.TempDir() pkg := filepath.Join(ws, "bindtest") - if err = os.MkdirAll(pkg, 0700); err != nil { + if err := os.MkdirAll(pkg, 0700); err != nil { t.Fatalf("failed to create package: %v", err) } // Generate the test suite for all the contracts diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 92b26f71bc..6416aa0435 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -55,7 +55,6 @@ func TestWatchNewFile(t *testing.T) { t.Parallel() dir, ks := tmpKeyStore(t, false) - defer os.RemoveAll(dir) // Ensure the watcher is started before adding any files. ks.Accounts() diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 75af63ff77..82d576e521 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -37,7 +37,6 @@ var testSigData = make([]byte, 32) func TestKeyStore(t *testing.T) { dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) a, err := ks.NewAccount("foo") if err != nil { @@ -71,8 +70,7 @@ func TestKeyStore(t *testing.T) { } func TestSign(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) pass := "" // not used but required by API a1, err := ks.NewAccount(pass) @@ -88,8 +86,7 @@ func TestSign(t *testing.T) { } func TestSignWithPassphrase(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) pass := "passwd" acc, err := ks.NewAccount(pass) @@ -116,8 +113,7 @@ func TestSignWithPassphrase(t *testing.T) { } func TestTimedUnlock(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) pass := "foo" a1, err := ks.NewAccount(pass) @@ -151,8 +147,7 @@ func TestTimedUnlock(t *testing.T) { } func TestOverrideUnlock(t *testing.T) { - dir, ks := tmpKeyStore(t, false) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, false) pass := "foo" a1, err := ks.NewAccount(pass) @@ -192,8 +187,7 @@ func TestOverrideUnlock(t *testing.T) { // This test should fail under -race if signing races the expiration goroutine. func TestSignRace(t *testing.T) { - dir, ks := tmpKeyStore(t, false) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, false) // Create a test account. a1, err := ks.NewAccount("") @@ -221,8 +215,7 @@ func TestSignRace(t *testing.T) { // addition and removal of wallet event subscriptions. func TestWalletNotifierLifecycle(t *testing.T) { // Create a temporary kesytore to test with - dir, ks := tmpKeyStore(t, false) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, false) // Ensure that the notification updater is not running yet time.Sleep(250 * time.Millisecond) @@ -282,8 +275,7 @@ type walletEvent struct { // Tests that wallet notifications and correctly fired when accounts are added // or deleted from the keystore. func TestWalletNotifications(t *testing.T) { - dir, ks := tmpKeyStore(t, false) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, false) // Subscribe to the wallet feed and collect events. var ( @@ -344,8 +336,7 @@ func TestWalletNotifications(t *testing.T) { // TestImportECDSA tests the import functionality of a keystore. func TestImportECDSA(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate key: %v", key) @@ -363,8 +354,7 @@ func TestImportECDSA(t *testing.T) { // TestImportExport tests the import and export functionality of a keystore. func TestImportExport(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -394,8 +384,7 @@ func TestImportExport(t *testing.T) { // TestImportRace tests the keystore on races. // This test should fail under -race if importing races. func TestImportRace(t *testing.T) { - dir, ks := tmpKeyStore(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStore(t, true) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -404,8 +393,7 @@ func TestImportRace(t *testing.T) { if err != nil { t.Fatalf("failed to export account: %v", acc) } - dir2, ks2 := tmpKeyStore(t, true) - defer os.RemoveAll(dir2) + _, ks2 := tmpKeyStore(t, true) var atom uint32 var wg sync.WaitGroup wg.Add(2) @@ -461,10 +449,7 @@ func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { } func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { - d, err := os.MkdirTemp("", "eth-keystore-test") - if err != nil { - t.Fatal(err) - } + d := t.TempDir() newKs := NewPlaintextKeyStore if encrypted { newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } diff --git a/accounts/keystore/plain_test.go b/accounts/keystore/plain_test.go index b7c0f5b3a5..97fe8d3e25 100644 --- a/accounts/keystore/plain_test.go +++ b/accounts/keystore/plain_test.go @@ -20,7 +20,6 @@ import ( "crypto/rand" "encoding/hex" "fmt" - "os" "path/filepath" "reflect" "strings" @@ -31,10 +30,7 @@ import ( ) func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { - d, err := os.MkdirTemp("", "geth-keystore-test") - if err != nil { - t.Fatal(err) - } + d := t.TempDir() if encrypted { ks = &keyStorePassphrase{d, veryLightScryptN, veryLightScryptP, true} } else { @@ -44,8 +40,7 @@ func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { } func TestKeyStorePlain(t *testing.T) { - dir, ks := tmpKeyStoreIface(t, false) - defer os.RemoveAll(dir) + _, ks := tmpKeyStoreIface(t, false) pass := "" // not used but required by API k1, account, err := storeNewKey(ks, rand.Reader, pass) @@ -65,8 +60,7 @@ func TestKeyStorePlain(t *testing.T) { } func TestKeyStorePassphrase(t *testing.T) { - dir, ks := tmpKeyStoreIface(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStoreIface(t, true) pass := "foo" k1, account, err := storeNewKey(ks, rand.Reader, pass) @@ -86,8 +80,7 @@ func TestKeyStorePassphrase(t *testing.T) { } func TestKeyStorePassphraseDecryptionFail(t *testing.T) { - dir, ks := tmpKeyStoreIface(t, true) - defer os.RemoveAll(dir) + _, ks := tmpKeyStoreIface(t, true) pass := "foo" k1, account, err := storeNewKey(ks, rand.Reader, pass) @@ -101,7 +94,6 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) { func TestImportPreSaleKey(t *testing.T) { dir, ks := tmpKeyStoreIface(t, true) - defer os.RemoveAll(dir) // file content of a presale key file generated with: // python pyethsaletool.py genwallet diff --git a/cmd/XDC/accountcmd_test.go b/cmd/XDC/accountcmd_test.go index 2afb457699..5c102e8673 100644 --- a/cmd/XDC/accountcmd_test.go +++ b/cmd/XDC/accountcmd_test.go @@ -33,7 +33,7 @@ import ( // are copied into a temporary keystore directory. func tmpDatadirWithKeystore(t *testing.T) string { - datadir := tmpdir(t) + datadir := t.TempDir() keystore := filepath.Join(datadir, "keystore") source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore") if err := cp.CopyAll(keystore, source); err != nil { @@ -43,8 +43,7 @@ func tmpDatadirWithKeystore(t *testing.T) string { } func TestAccountListEmpty(t *testing.T) { - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() XDC := runXDC(t, "account", "list", "--datadir", datadir) XDC.ExpectExit() } @@ -144,8 +143,7 @@ Repeat passphrase: {{.InputLine "foobar2"}} } func TestWalletImport(t *testing.T) { - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() XDC := runXDC(t, "wallet", "import", "--datadir", datadir, "--lightkdf", "testdata/guswallet.json") defer XDC.ExpectExit() XDC.Expect(` diff --git a/cmd/XDC/consolecmd_test.go b/cmd/XDC/consolecmd_test.go index 4854b3d5ab..9ad40e690f 100644 --- a/cmd/XDC/consolecmd_test.go +++ b/cmd/XDC/consolecmd_test.go @@ -19,7 +19,6 @@ package main import ( "crypto/rand" "math/big" - "os" "path/filepath" "runtime" "strconv" @@ -39,8 +38,7 @@ const ( // then terminated by closing the input stream. func TestConsoleWelcome(t *testing.T) { coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() // Start a XDC console, make sure it's cleaned up and terminate the console XDC := runXDC(t, @@ -77,8 +75,7 @@ at block: 0 ({{niltime}}) func TestIPCAttachWelcome(t *testing.T) { // Configure the instance for IPC attachement coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() var ipc string if runtime.GOOS == "windows" { ipc = `\\.\pipe\XDC` + strconv.Itoa(trulyRandInt(100000, 999999)) @@ -100,8 +97,7 @@ func TestIPCAttachWelcome(t *testing.T) { func TestHTTPAttachWelcome(t *testing.T) { coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() XDC := runXDC(t, "--datadir", datadir, "--XDCx-datadir", datadir+"/XDCx", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", @@ -117,8 +113,7 @@ func TestHTTPAttachWelcome(t *testing.T) { func TestWSAttachWelcome(t *testing.T) { coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() XDC := runXDC(t, "--datadir", datadir, "--XDCx-datadir", datadir+"/XDCx", "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", diff --git a/cmd/XDC/dao_test.go b/cmd/XDC/dao_test.go index b487b364be..daa46994da 100644 --- a/cmd/XDC/dao_test.go +++ b/cmd/XDC/dao_test.go @@ -100,8 +100,7 @@ func TestDAOForkBlockNewChain(t *testing.T) { func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) { // Create a temporary data directory to use and inspect later - datadir := tmpdir(t) - defer os.RemoveAll(datadir) + datadir := t.TempDir() // Start a XDC instance with the requested flags set and immediately terminate if genesis != "" { diff --git a/cmd/XDC/run_test.go b/cmd/XDC/run_test.go index 98f6092fed..10f3f85c7a 100644 --- a/cmd/XDC/run_test.go +++ b/cmd/XDC/run_test.go @@ -25,14 +25,6 @@ import ( "github.com/docker/docker/pkg/reexec" ) -func tmpdir(t *testing.T) string { - dir, err := os.MkdirTemp("", "XDC-test") - if err != nil { - t.Fatal(err) - } - return dir -} - type testXDC struct { *cmdtest.TestCmd @@ -78,15 +70,10 @@ func runXDC(t *testing.T, args ...string) *testXDC { } } if tt.Datadir == "" { - tt.Datadir = tmpdir(t) + // The temporary datadir will be removed automatically if something fails below. + tt.Datadir = t.TempDir() tt.Cleanup = func() { os.RemoveAll(tt.Datadir) } args = append([]string{"--datadir", tt.Datadir}, args...) - // Remove the temporary datadir if something fails below. - defer func() { - if t.Failed() { - tt.Cleanup() - } - }() } // Boot "XDC". This actually runs the test binary but the TestMain diff --git a/cmd/ethkey/message_test.go b/cmd/ethkey/message_test.go index 28a74de98a..c06cf1ffad 100644 --- a/cmd/ethkey/message_test.go +++ b/cmd/ethkey/message_test.go @@ -17,17 +17,12 @@ package main import ( - "os" "path/filepath" "testing" ) func TestMessageSignVerify(t *testing.T) { - tmpdir, err := os.MkdirTemp("", "ethkey-test") - if err != nil { - t.Fatal("Can't create temporary directory:", err) - } - defer os.RemoveAll(tmpdir) + tmpdir := t.TempDir() keyfile := filepath.Join(tmpdir, "the-keyfile") message := "test message" diff --git a/cmd/utils/flags_test.go b/cmd/utils/flags_test.go index 728cbb7070..52712f0361 100644 --- a/cmd/utils/flags_test.go +++ b/cmd/utils/flags_test.go @@ -73,13 +73,10 @@ func TestWalkMatch(t *testing.T) { root string pattern string } - dir, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - test1Dir, _ := os.MkdirTemp(dir, "test1") - test2Dir, _ := os.MkdirTemp(dir, "test2") - err = os.WriteFile(filepath.Join(test1Dir, "test1.ldb"), []byte("hello"), os.ModePerm) + test1Dir := t.TempDir() + test2Dir := t.TempDir() + + err := os.WriteFile(filepath.Join(test1Dir, "test1.ldb"), []byte("hello"), os.ModePerm) if err != nil { log.Fatal(err) } @@ -87,10 +84,6 @@ func TestWalkMatch(t *testing.T) { if err != nil { log.Fatal(err) } - defer func() { - os.RemoveAll(test1Dir) - os.RemoveAll(test2Dir) - }() tests := []struct { name string diff --git a/consensus/XDPoS/engines/engine_v2/forensics_test.go b/consensus/XDPoS/engines/engine_v2/forensics_test.go index 3b6dc1b252..3cd6e25984 100644 --- a/consensus/XDPoS/engines/engine_v2/forensics_test.go +++ b/consensus/XDPoS/engines/engine_v2/forensics_test.go @@ -48,13 +48,9 @@ func getSignerAndSignFn(pk *ecdsa.PrivateKey) (common.Address, func(account acco veryLightScryptN := 2 veryLightScryptP := 1 dir, _ := os.MkdirTemp("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) - - new := func(kd string) *keystore.KeyStore { - return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) - } - defer os.RemoveAll(dir) - ks := new(dir) + + ks := keystore.NewKeyStore(dir, veryLightScryptN, veryLightScryptP) pass := "" // not used but required by API a1, err := ks.ImportECDSA(pk, pass) if err != nil { diff --git a/consensus/XDPoS/engines/engine_v2/snapshot_test.go b/consensus/XDPoS/engines/engine_v2/snapshot_test.go index db47701ad8..fac04f0897 100644 --- a/consensus/XDPoS/engines/engine_v2/snapshot_test.go +++ b/consensus/XDPoS/engines/engine_v2/snapshot_test.go @@ -2,7 +2,6 @@ package engine_v2 import ( "fmt" - "os" "testing" "github.com/XinFinOrg/XDPoSChain/common" @@ -24,10 +23,7 @@ func TestGetMasterNodes(t *testing.T) { func TestStoreLoadSnapshot(t *testing.T) { snap := newSnapshot(1, common.Hash{0x1}, nil) - dir, err := os.MkdirTemp("", "snapshot-test") - if err != nil { - panic(fmt.Sprintf("can't create temporary directory: %v", err)) - } + dir := t.TempDir() db, err := leveldb.New(dir, 256, 0, "", false) if err != nil { panic(fmt.Sprintf("can't create temporary database: %v", err)) diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index 6a9d8809ad..40524a81e4 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -687,6 +687,8 @@ func TestHashimoto(t *testing.T) { // Tests that caches generated on disk may be done concurrently. func TestConcurrentDiskCacheGeneration(t *testing.T) { // Create a temp folder to generate the caches into + // TODO: t.TempDir fails to remove the directory on Windows + // \AppData\Local\Temp\1\TestConcurrentDiskCacheGeneration2382060137\001\cache-R23-1dca8a85e74aa763: Access is denied. cachedir, err := os.MkdirTemp("", "") if err != nil { t.Fatalf("Failed to create temporary cache dir: %v", err) diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go index 5b13473cf3..c6d319ba7c 100644 --- a/consensus/ethash/ethash_test.go +++ b/consensus/ethash/ethash_test.go @@ -45,6 +45,8 @@ func TestTestMode(t *testing.T) { // This test checks that cache lru logic doesn't crash under load. // It reproduces https://github.com/XinFinOrg/XDPoSChain/issues/14943 func TestCacheFileEvict(t *testing.T) { + // TODO: t.TempDir fails to remove the directory on Windows + // \AppData\Local\Temp\1\TestCacheFileEvict2179435125\001\cache-R23-0000000000000000: Access is denied. tmpdir, err := os.MkdirTemp("", "ethash-test") if err != nil { t.Fatal(err) diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index c13b289b34..01a607b033 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -77,13 +77,9 @@ func getSignerAndSignFn(pk *ecdsa.PrivateKey) (common.Address, func(account acco veryLightScryptN := 2 veryLightScryptP := 1 dir, _ := os.MkdirTemp("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5))) - - new := func(kd string) *keystore.KeyStore { - return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP) - } - defer os.RemoveAll(dir) - ks := new(dir) + + ks := keystore.NewKeyStore(dir, veryLightScryptN, veryLightScryptP) pass := "" // not used but required by API a1, err := ks.ImportECDSA(pk, pass) if err != nil { diff --git a/console/console_test.go b/console/console_test.go index 0d5c94a754..2f5cfd5c54 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -87,10 +87,7 @@ type tester struct { // Please ensure you call Close() on the returned tester to avoid leaks. func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester { // Create a temporary storage for the node keys and initialize it - workspace, err := os.MkdirTemp("", "console-tester-") - if err != nil { - t.Fatalf("failed to create temporary keystore: %v", err) - } + workspace := t.TempDir() // Create a networkless protocol stack and start an Ethereum service within stack, err := node.New(&node.Config{DataDir: workspace, UseLightweightKDF: true, Name: testInstance}) diff --git a/core/bench_test.go b/core/bench_test.go index afdb15383c..7da8d8249d 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -148,14 +148,11 @@ func genUncles(i int, gen *BlockGen) { func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // Create the database in memory or in a temporary directory. var db ethdb.Database + var err error if !disk { db = rawdb.NewMemoryDatabase() } else { - dir, err := os.MkdirTemp("", "eth-core-bench") - if err != nil { - b.Fatalf("cannot create temporary directory: %v", err) - } - defer os.RemoveAll(dir) + dir := b.TempDir() db, err = rawdb.NewLevelDBDatabase(dir, 128, 128, "", false) if err != nil { b.Fatalf("cannot create temporary database: %v", err) @@ -250,10 +247,7 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) { func benchWriteChain(b *testing.B, full bool, count uint64) { for i := 0; i < b.N; i++ { - dir, err := os.MkdirTemp("", "eth-chain-bench") - if err != nil { - b.Fatalf("cannot create temporary directory: %v", err) - } + dir := b.TempDir() db, err := rawdb.NewLevelDBDatabase(dir, 128, 1024, "", false) if err != nil { b.Fatalf("error opening database at %v: %v", dir, err) @@ -265,11 +259,7 @@ func benchWriteChain(b *testing.B, full bool, count uint64) { } func benchReadChain(b *testing.B, full bool, count uint64) { - dir, err := os.MkdirTemp("", "eth-chain-bench") - if err != nil { - b.Fatalf("cannot create temporary directory: %v", err) - } - defer os.RemoveAll(dir) + dir := b.TempDir() db, err := rawdb.NewLevelDBDatabase(dir, 128, 1024, "", false) if err != nil { diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index e1a87796bb..1dc61bdab1 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -19,13 +19,12 @@ package filters import ( "context" "math/big" - "os" "testing" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -41,11 +40,7 @@ func makeReceipt(addr common.Address) *types.Receipt { } func BenchmarkFilters(b *testing.B) { - dir, err := os.MkdirTemp("", "filtertest") - if err != nil { - b.Fatal(err) - } - defer os.RemoveAll(dir) + dir := b.TempDir() var ( db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) @@ -95,11 +90,7 @@ func BenchmarkFilters(b *testing.B) { } func TestFilters(t *testing.T) { - dir, err := os.MkdirTemp("", "filtertest") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() var ( db, _ = rawdb.NewLevelDBDatabase(dir, 0, 0, "", false) diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go index 64b9e162fa..1b608e90cb 100644 --- a/internal/guide/guide_test.go +++ b/internal/guide/guide_test.go @@ -24,7 +24,6 @@ package guide import ( "math/big" - "os" "path/filepath" "testing" "time" @@ -37,11 +36,7 @@ import ( // Tests that the account management snippets work correctly. func TestAccountManagement(t *testing.T) { // Create a temporary folder to work with - workdir, err := os.MkdirTemp("", "") - if err != nil { - t.Fatalf("Failed to create temporary work dir: %v", err) - } - defer os.RemoveAll(workdir) + workdir := t.TempDir() // Create an encrypted keystore with standard crypto parameters ks := keystore.NewKeyStore(filepath.Join(workdir, "keystore"), keystore.StandardScryptN, keystore.StandardScryptP) diff --git a/internal/jsre/jsre_test.go b/internal/jsre/jsre_test.go index 9b58fb0490..4de1275e6c 100644 --- a/internal/jsre/jsre_test.go +++ b/internal/jsre/jsre_test.go @@ -39,23 +39,19 @@ func (no *testNativeObjectBinding) TestMethod(call goja.FunctionCall) goja.Value return no.vm.ToValue(&msg{m}) } -func newWithTestJS(t *testing.T, testjs string) (*JSRE, string) { - dir, err := os.MkdirTemp("", "jsre-test") - if err != nil { - t.Fatal("cannot create temporary directory:", err) - } +func newWithTestJS(t *testing.T, testjs string) *JSRE { + dir := t.TempDir() if testjs != "" { if err := os.WriteFile(path.Join(dir, "test.js"), []byte(testjs), os.ModePerm); err != nil { t.Fatal("cannot create test.js:", err) } } jsre := New(dir, os.Stdout) - return jsre, dir + return jsre } func TestExec(t *testing.T) { - jsre, dir := newWithTestJS(t, `msg = "testMsg"`) - defer os.RemoveAll(dir) + jsre := newWithTestJS(t, `msg = "testMsg"`) err := jsre.Exec("test.js") if err != nil { @@ -77,8 +73,7 @@ func TestExec(t *testing.T) { } func TestNatto(t *testing.T) { - jsre, dir := newWithTestJS(t, `setTimeout(function(){msg = "testMsg"}, 1);`) - defer os.RemoveAll(dir) + jsre := newWithTestJS(t, `setTimeout(function(){msg = "testMsg"}, 1);`) err := jsre.Exec("test.js") if err != nil { @@ -113,8 +108,7 @@ func TestBind(t *testing.T) { } func TestLoadScript(t *testing.T) { - jsre, dir := newWithTestJS(t, `msg = "testMsg"`) - defer os.RemoveAll(dir) + jsre := newWithTestJS(t, `msg = "testMsg"`) _, err := jsre.Run(`loadScript("test.js")`) if err != nil { diff --git a/node/config_test.go b/node/config_test.go index 321a7bad6e..8b3de74b9d 100644 --- a/node/config_test.go +++ b/node/config_test.go @@ -31,11 +31,7 @@ import ( // ones or automatically generated temporary ones. func TestDatadirCreation(t *testing.T) { // Create a temporary data dir and check that it can be used by a node - dir, err := os.MkdirTemp("", "") - if err != nil { - t.Fatalf("failed to create manual data dir: %v", err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() node, err := New(&Config{DataDir: dir}) if err != nil { @@ -61,7 +57,10 @@ func TestDatadirCreation(t *testing.T) { if err != nil { t.Fatalf("failed to create temporary file: %v", err) } - defer os.Remove(file.Name()) + defer func() { + file.Close() + os.Remove(file.Name()) + }() dir = filepath.Join(file.Name(), "invalid/path") node, err = New(&Config{DataDir: dir}) @@ -108,11 +107,7 @@ func TestIPCPathResolution(t *testing.T) { // ephemeral. func TestNodeKeyPersistency(t *testing.T) { // Create a temporary folder and make sure no key is present - dir, err := os.MkdirTemp("", "node-test") - if err != nil { - t.Fatalf("failed to create temporary data directory: %v", err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() keyfile := filepath.Join(dir, "unit-test", datadirPrivateKey) diff --git a/node/node_test.go b/node/node_test.go index b733ea5174..6e6ea3be79 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -19,7 +19,6 @@ package node import ( "errors" "net/http" - "os" "reflect" "testing" "time" @@ -80,11 +79,7 @@ func TestNodeLifeCycle(t *testing.T) { // Tests that if the data dir is already in use, an appropriate error is returned. func TestNodeUsedDataDir(t *testing.T) { // Create a temporary folder to use as the data directory - dir, err := os.MkdirTemp("", "") - if err != nil { - t.Fatalf("failed to create temporary data directory: %v", err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() // Create a new node based on the data directory original, err := New(&Config{DataDir: dir}) diff --git a/node/service_test.go b/node/service_test.go index be941ee914..3a0c77981b 100644 --- a/node/service_test.go +++ b/node/service_test.go @@ -28,11 +28,7 @@ import ( // the configured service context. func TestContextDatabases(t *testing.T) { // Create a temporary folder and ensure no database is contained within - dir, err := os.MkdirTemp("", "") - if err != nil { - t.Fatalf("failed to create temporary data directory: %v", err) - } - defer os.RemoveAll(dir) + dir := t.TempDir() if _, err := os.Stat(filepath.Join(dir, "database")); err == nil { t.Fatalf("non-created database already exists") diff --git a/p2p/discover/database_test.go b/p2p/discover/database_test.go index d881c65337..f1ea25139c 100644 --- a/p2p/discover/database_test.go +++ b/p2p/discover/database_test.go @@ -19,7 +19,6 @@ package discover import ( "bytes" "net" - "os" "path/filepath" "reflect" "testing" @@ -254,11 +253,7 @@ func TestNodeDBSeedQuery(t *testing.T) { } func TestNodeDBPersistency(t *testing.T) { - root, err := os.MkdirTemp("", "nodedb-") - if err != nil { - t.Fatalf("failed to create temporary data folder: %v", err) - } - defer os.RemoveAll(root) + root := t.TempDir() var ( testKey = []byte("somekey") diff --git a/p2p/discv5/database_test.go b/p2p/discv5/database_test.go index 73ee613a34..9f9c2ee3a0 100644 --- a/p2p/discv5/database_test.go +++ b/p2p/discv5/database_test.go @@ -19,7 +19,6 @@ package discv5 import ( "bytes" "net" - "os" "path/filepath" "reflect" "testing" @@ -254,11 +253,7 @@ func TestNodeDBSeedQuery(t *testing.T) { } func TestNodeDBPersistency(t *testing.T) { - root, err := os.MkdirTemp("", "nodedb-") - if err != nil { - t.Fatalf("failed to create temporary data folder: %v", err) - } - defer os.RemoveAll(root) + root := t.TempDir() var ( testKey = []byte("somekey") diff --git a/trie/trie_test.go b/trie/trie_test.go index 58ba7102d1..a02d79d337 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -496,7 +496,7 @@ const benchElemCount = 20000 func benchGet(b *testing.B, commit bool) { trie := new(Trie) if commit { - _, tmpdb := tempDB() + tmpdb := tempDB(b) trie, _ = New(common.Hash{}, tmpdb) } k := make([]byte, 32) @@ -837,16 +837,13 @@ func benchmarkDerefRootFixedSize(b *testing.B, addresses [][20]byte, accounts [] b.StopTimer() } -func tempDB() (string, *Database) { - dir, err := os.MkdirTemp("", "trie-bench") - if err != nil { - panic(fmt.Sprintf("can't create temporary directory: %v", err)) - } +func tempDB(tb testing.TB) *Database { + dir := tb.TempDir() diskdb, err := leveldb.New(dir, 256, 0, "", false) if err != nil { panic(fmt.Sprintf("can't create temporary database: %v", err)) } - return dir, NewDatabase(diskdb) + return NewDatabase(diskdb) } func getString(trie *Trie, k string) []byte { From 206b61420fc4639ab4eea4a7a754f7f4c8e5f52d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 177/280] abi/base: return error for pending call error (#24649) If a pending contract call errors, return that error right away rather than ignoring it to allow an error somewhere else. This is helpful for callers to know if perhaps a call failed because of the context deadline being expired. This change mirrors the behavior of non-pending contract calls. --- accounts/abi/bind/base.go | 5 +- accounts/abi/bind/base_test.go | 168 ++++++++++++++++++++++++++++++--- 2 files changed, 161 insertions(+), 12 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 35b8c2cde7..5c63a66aad 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -175,7 +175,10 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return ErrNoPendingState } output, err = pb.PendingCallContract(ctx, msg) - if err == nil && len(output) == 0 { + if err != nil { + return err + } + if len(output) == 0 { // Make sure we have a contract to operate on, and bail out otherwise. if code, err = pb.PendingCodeAt(ctx, c.address); err != nil { return err diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 2294b1ff04..1d3698b877 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -18,6 +18,7 @@ package bind_test import ( "context" + "errors" "math/big" "reflect" "strings" @@ -75,35 +76,51 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac } type mockCaller struct { - codeAtBlockNumber *big.Int - callContractBlockNumber *big.Int - pendingCodeAtCalled bool - pendingCallContractCalled bool + codeAtBlockNumber *big.Int + callContractBlockNumber *big.Int + callContractBytes []byte + callContractErr error + codeAtBytes []byte + codeAtErr error } func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { mc.codeAtBlockNumber = blockNumber - return []byte{1, 2, 3}, nil + return mc.codeAtBytes, mc.codeAtErr } func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { mc.callContractBlockNumber = blockNumber - return nil, nil + return mc.callContractBytes, mc.callContractErr } -func (mc *mockCaller) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { +type mockPendingCaller struct { + *mockCaller + pendingCodeAtBytes []byte + pendingCodeAtErr error + pendingCodeAtCalled bool + pendingCallContractCalled bool + pendingCallContractBytes []byte + pendingCallContractErr error +} + +func (mc *mockPendingCaller) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { mc.pendingCodeAtCalled = true - return nil, nil + return mc.pendingCodeAtBytes, mc.pendingCodeAtErr } -func (mc *mockCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { +func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { mc.pendingCallContractCalled = true - return nil, nil + return mc.pendingCallContractBytes, mc.pendingCallContractErr } func TestPassingBlockNumber(t *testing.T) { - mc := &mockCaller{} + mc := &mockPendingCaller{ + mockCaller: &mockCaller{ + codeAtBytes: []byte{1, 2, 3}, + }, + } bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{ Methods: map[string]abi.Method{ @@ -330,3 +347,132 @@ func newMockLog(topics []common.Hash, txHash common.Hash) types.Log { Removed: false, } } + +func TestCall(t *testing.T) { + var method, methodWithArg = "something", "somethingArrrrg" + tests := []struct { + name, method string + opts *bind.CallOpts + mc bind.ContractCaller + results *[]interface{} + wantErr bool + wantErrExact error + }{{ + name: "ok not pending", + mc: &mockCaller{ + codeAtBytes: []byte{0}, + }, + method: method, + }, { + name: "ok pending", + mc: &mockPendingCaller{ + pendingCodeAtBytes: []byte{0}, + }, + opts: &bind.CallOpts{ + Pending: true, + }, + method: method, + }, { + name: "pack error, no method", + mc: new(mockCaller), + method: "else", + wantErr: true, + }, { + name: "interface error, pending but not a PendingContractCaller", + mc: new(mockCaller), + opts: &bind.CallOpts{ + Pending: true, + }, + method: method, + wantErrExact: bind.ErrNoPendingState, + }, { + name: "pending call canceled", + mc: &mockPendingCaller{ + pendingCallContractErr: context.DeadlineExceeded, + }, + opts: &bind.CallOpts{ + Pending: true, + }, + method: method, + wantErrExact: context.DeadlineExceeded, + }, { + name: "pending code at error", + mc: &mockPendingCaller{ + pendingCodeAtErr: errors.New(""), + }, + opts: &bind.CallOpts{ + Pending: true, + }, + method: method, + wantErr: true, + }, { + name: "no pending code at", + mc: new(mockPendingCaller), + opts: &bind.CallOpts{ + Pending: true, + }, + method: method, + wantErrExact: bind.ErrNoCode, + }, { + name: "call contract error", + mc: &mockCaller{ + callContractErr: context.DeadlineExceeded, + }, + method: method, + wantErrExact: context.DeadlineExceeded, + }, { + name: "code at error", + mc: &mockCaller{ + codeAtErr: errors.New(""), + }, + method: method, + wantErr: true, + }, { + name: "no code at", + mc: new(mockCaller), + method: method, + wantErrExact: bind.ErrNoCode, + }, { + name: "unpack error missing arg", + mc: &mockCaller{ + codeAtBytes: []byte{0}, + }, + method: methodWithArg, + wantErr: true, + }, { + name: "interface unpack error", + mc: &mockCaller{ + codeAtBytes: []byte{0}, + }, + method: method, + results: &[]interface{}{0}, + wantErr: true, + }} + for _, test := range tests { + bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{ + Methods: map[string]abi.Method{ + method: { + Name: method, + Outputs: abi.Arguments{}, + }, + methodWithArg: { + Name: methodWithArg, + Outputs: abi.Arguments{abi.Argument{}}, + }, + }, + }, test.mc, nil, nil) + err := bc.Call(test.opts, test.results, test.method) + if test.wantErr || test.wantErrExact != nil { + if err == nil { + t.Fatalf("%q expected error", test.name) + } + if test.wantErrExact != nil && !errors.Is(err, test.wantErrExact) { + t.Fatalf("%q expected error %q but got %q", test.name, test.wantErrExact, err) + } + continue + } + if err != nil { + t.Fatalf("%q unexpected error: %v", test.name, err) + } + } +} From 98629d0c4b2b8566458706e0ff4ae22714766cf0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 178/280] accounts: fix typo in comments (#24805) --- accounts/errors.go | 3 +-- accounts/hd.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/accounts/errors.go b/accounts/errors.go index 727e5329be..03cb569eba 100644 --- a/accounts/errors.go +++ b/accounts/errors.go @@ -41,8 +41,7 @@ var ErrInvalidPassphrase = errors.New("invalid password") // second time. var ErrWalletAlreadyOpen = errors.New("wallet already open") -// ErrWalletClosed is returned if a wallet is attempted to be opened the -// second time. +// ErrWalletClosed is returned if a wallet is offline. var ErrWalletClosed = errors.New("wallet closed") // AuthNeededError is returned by backends for signing requests where the user diff --git a/accounts/hd.go b/accounts/hd.go index e4fb0543de..daca75ebbc 100644 --- a/accounts/hd.go +++ b/accounts/hd.go @@ -41,7 +41,7 @@ var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} // DerivationPath represents the computer friendly version of a hierarchical -// deterministic wallet account derivaion path. +// deterministic wallet account derivation path. // // The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki // defines derivation paths to be of the form: From a09fd97b117d5e72abd7e2a6cc29d3d5796fe827 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 179/280] abi: fix checks when all fields are indexed (#24792) This PR fixes abi checks in the edge case where all arguments are indexed --- accounts/abi/argument.go | 8 ++++---- accounts/abi/unpack_test.go | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index e6c117fe5f..c5326d5700 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -78,7 +78,7 @@ func (arguments Arguments) isTuple() bool { // Unpack performs the operation hexdata -> Go format. func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { if len(data) == 0 { - if len(arguments) != 0 { + if len(arguments.NonIndexed()) != 0 { return nil, fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") } return make([]interface{}, 0), nil @@ -93,7 +93,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) return fmt.Errorf("abi: cannot unpack into a nil map") } if len(data) == 0 { - if len(arguments) != 0 { + if len(arguments.NonIndexed()) != 0 { return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") } return nil // Nothing to unmarshal, return @@ -115,8 +115,8 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error { return fmt.Errorf("abi: Unpack(non-pointer %T)", v) } if len(values) == 0 { - if len(arguments) != 0 { - return fmt.Errorf("abi: attempting to copy no values while %d arguments are expected", len(arguments)) + if len(arguments.NonIndexed()) != 0 { + return fmt.Errorf("abi: attempting to copy no values while arguments are expected") } return nil // Nothing to copy, return } diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index bb259dc0aa..751c97cd61 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -201,6 +201,23 @@ var unpackTests = []unpackTest{ IntOne *big.Int }{big.NewInt(1)}, }, + { + def: `[{"type":"bool"}]`, + enc: "", + want: false, + err: "abi: attempting to unmarshall an empty string while arguments are expected", + }, + { + def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`, + enc: "", + want: false, + err: "abi: attempting to unmarshall an empty string while arguments are expected", + }, + { + def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`, + enc: "", + want: false, + }, } // TestLocalUnpackTests runs test specially designed only for unpacking. From 16cdf8f4ec2917916ae8236b04023ea439ebcdf9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 180/280] accounts/abi: eplace strings.Replace with string.ReplaceAll (#24835) --- accounts/abi/bind/bind.go | 2 +- accounts/abi/bind/template.go | 2 +- accounts/abi/type.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index c8ef5d0cfd..21bbccc224 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -172,7 +172,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] contracts[types[i]] = &tmplContract{ Type: capitalise(types[i]), - InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1), + InputABI: strings.ReplaceAll(strippedABI, "\"", "\\\""), InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"), Constructor: evmABI.Constructor, Calls: calls, diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index e3f031ade0..c1c041f234 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -160,7 +160,7 @@ var ( } {{range $pattern, $name := .Libraries}} {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) - {{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:], -1) + {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) {{end}} address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) if err != nil { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 95b985f303..60a790cc2b 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -200,7 +200,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty if internalType != "" && strings.HasPrefix(internalType, structPrefix) { // Foo.Bar type definition is not allowed in golang, // convert the format to FooBar - typ.TupleRawName = strings.Replace(internalType[len(structPrefix):], ".", "", -1) + typ.TupleRawName = strings.ReplaceAll(internalType[len(structPrefix):], ".", "") } case "function": From 04fabd63a4e93b42c882edda206289b927321cc1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 181/280] accounts/abi: validate fieldnames, fixes #24930 (#24932) --- accounts/abi/bind/base_test.go | 8 ++++++++ accounts/abi/type.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 1d3698b877..7fad9c7bb6 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -476,3 +476,11 @@ func TestCall(t *testing.T) { } } } + +// TestCrashers contains some strings which previously caused the abi codec to crash. +func TestCrashers(t *testing.T) { + abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"_1"}]}]}]`)) + abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"&"}]}]}]`)) + abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"----"}]}]}]`)) + abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"foo.Bar"}]}]}]`)) +} diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 60a790cc2b..c70bf510ba 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -23,6 +23,8 @@ import ( "regexp" "strconv" "strings" + "unicode" + "unicode/utf8" "github.com/XinFinOrg/XDPoSChain/common" ) @@ -172,6 +174,9 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty if err != nil { return Type{}, err } + if !isValidFieldName(fieldName) { + return Type{}, fmt.Errorf("field %d has invalid name", idx) + } overloadedNames[fieldName] = fieldName fields = append(fields, reflect.StructField{ Name: fieldName, // reflect.StructOf will panic for any exported field. @@ -398,3 +403,30 @@ func getTypeSize(t Type) int { } return 32 } + +// isLetter reports whether a given 'rune' is classified as a Letter. +// This method is copied from reflect/type.go +func isLetter(ch rune) bool { + return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch) +} + +// isValidFieldName checks if a string is a valid (struct) field name or not. +// +// According to the language spec, a field name should be an identifier. +// +// identifier = letter { letter | unicode_digit } . +// letter = unicode_letter | "_" . +// This method is copied from reflect/type.go +func isValidFieldName(fieldName string) bool { + for i, c := range fieldName { + if i == 0 && !isLetter(c) { + return false + } + + if !(isLetter(c) || unicode.IsDigit(c)) { + return false + } + } + + return len(fieldName) > 0 +} From c4308f0fbc77d64937a981a3f2cd5d3b61c958e3 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 182/280] cmd/abigen: accept combined-json via stdin (#24960) --- cmd/abigen/main.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 5276b843c9..1184b072ab 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -56,7 +56,7 @@ var ( } jsonFlag = &cli.StringFlag{ Name: "combined-json", - Usage: "Path to the combined-json file generated by compiler", + Usage: "Path to the combined-json file generated by compiler, - for STDIN", } excFlag = &cli.StringFlag{ Name: "exc", @@ -165,9 +165,18 @@ func abigen(c *cli.Context) error { var contracts map[string]*compiler.Contract if c.IsSet(jsonFlag.Name) { - jsonOutput, err := os.ReadFile(c.String(jsonFlag.Name)) + var ( + input = c.String(jsonFlag.Name) + jsonOutput []byte + err error + ) + if input == "-" { + jsonOutput, err = io.ReadAll(os.Stdin) + } else { + jsonOutput, err = os.ReadFile(input) + } if err != nil { - utils.Fatalf("Failed to read combined-json from compiler: %v", err) + utils.Fatalf("Failed to read combined-json: %v", err) } contracts, err = compiler.ParseCombinedJSON(jsonOutput, "", "", "", "") if err != nil { From 13eef329989430322e3fde77595cc4f0f07f3088 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:13 +0800 Subject: [PATCH 183/280] accounts/abi/bind: fix duplicate field names in the generated go struct (#24924) * accounts/abi/bind: fix duplicate field names in the generated go struct #24627 * accounts, cmd/abigen: resolve name conflicts * ci lint, accounts/abi: remove unused function overloadedArgName Co-authored-by: Gary Rong --- accounts/abi/abi.go | 23 +++------------- accounts/abi/bind/bind.go | 25 +++++++++++++++--- accounts/abi/bind/bind_test.go | 48 ++++++++++++++++++++++++++++++++++ accounts/abi/error.go | 6 +++-- accounts/abi/event.go | 7 +++-- accounts/abi/type.go | 24 +++++------------ accounts/abi/utils.go | 41 +++++++++++++++++++++++++++++ cmd/abigen/main.go | 6 ++++- 8 files changed, 136 insertions(+), 44 deletions(-) create mode 100644 accounts/abi/utils.go diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index a60d76dd4a..70eda9a5d8 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -164,7 +164,7 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { case "constructor": abi.Constructor = NewMethod("", "", Constructor, field.StateMutability, field.Constant, field.Payable, field.Inputs, nil) case "function": - name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Methods[s]; return ok }) + name := ResolveNameConflict(field.Name, func(s string) bool { _, ok := abi.Methods[s]; return ok }) abi.Methods[name] = NewMethod(name, field.Name, Function, field.StateMutability, field.Constant, field.Payable, field.Inputs, field.Outputs) case "fallback": // New introduced function type in v0.6.0, check more detail @@ -184,9 +184,11 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { } abi.Receive = NewMethod("", "", Receive, field.StateMutability, field.Constant, field.Payable, nil, nil) case "event": - name := overloadedName(field.Name, func(s string) bool { _, ok := abi.Events[s]; return ok }) + name := ResolveNameConflict(field.Name, func(s string) bool { _, ok := abi.Events[s]; return ok }) abi.Events[name] = NewEvent(name, field.Name, field.Anonymous, field.Inputs) case "error": + // Errors cannot be overloaded or overridden but are inherited, + // no need to resolve the name conflict here. abi.Errors[field.Name] = NewError(field.Name, field.Inputs) default: return fmt.Errorf("abi: could not recognize type %v of field %v", field.Type, field.Name) @@ -251,20 +253,3 @@ func UnpackRevert(data []byte) (string, error) { } return unpacked[0].(string), nil } - -// overloadedName returns the next available name for a given thing. -// Needed since solidity allows for overloading. -// -// e.g. if the abi contains Methods send, send1 -// overloadedName would return send2 for input send. -// -// overloadedName works for methods, events and errors. -func overloadedName(rawName string, isAvail func(string) bool) string { - name := rawName - ok := isAvail(name) - for idx := 0; ok; idx++ { - name = fmt.Sprintf("%s%d", rawName, idx) - ok = isAvail(name) - } - return name -} diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 21bbccc224..3f6eb4e91b 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -96,6 +96,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Normalize the method for capital cases and non-anonymous inputs/outputs normalized := original normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + // Ensure there is no duplicated identifier var identifiers = callIdentifiers if !original.IsConstant() { @@ -105,6 +106,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName) } identifiers[normalizedName] = true + normalized.Name = normalizedName normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) @@ -149,12 +151,22 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] eventIdentifiers[normalizedName] = true normalized.Name = normalizedName + used := make(map[string]bool) normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { if input.Name == "" { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } + // Event is a bit special, we need to define event struct in binding, + // ensure there is no camel-case-style name conflict. + for index := 0; ; index++ { + if !used[capitalise(normalized.Inputs[j].Name)] { + used[capitalise(normalized.Inputs[j].Name)] = true + break + } + normalized.Inputs[j].Name = fmt.Sprintf("%s%d", normalized.Inputs[j].Name, index) + } if hasStruct(input.Type) { bindStructType[lang](input.Type, structs) } @@ -330,15 +342,22 @@ func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { if s, exist := structs[id]; exist { return s.Name } - var fields []*tmplField + var ( + names = make(map[string]bool) + fields []*tmplField + ) for i, elem := range kind.TupleElems { - field := bindStructTypeGo(*elem, structs) - fields = append(fields, &tmplField{Type: field, Name: capitalise(kind.TupleRawNames[i]), SolKind: *elem}) + name := capitalise(kind.TupleRawNames[i]) + name = abi.ResolveNameConflict(name, func(s string) bool { return names[s] }) + names[name] = true + fields = append(fields, &tmplField{Type: bindStructTypeGo(*elem, structs), Name: name, SolKind: *elem}) } name := kind.TupleRawName if name == "" { name = fmt.Sprintf("Struct%d", len(structs)) } + name = capitalise(name) + structs[id] = &tmplStruct{ Name: name, Fields: fields, diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index a2ce6b8f4d..b9df18ce24 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1901,6 +1901,54 @@ var bindTests = []struct { } sim.Commit() + if _, err = bind.WaitDeployed(nil, sim, tx); err != nil { + t.Logf("Deployment tx: %+v", tx) + t.Errorf("bind.WaitDeployed(nil, %T, ) got err %v; want nil err", sim, err) + } + `, + }, + { + name: `NameConflict`, + contract: ` + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.4.22 <0.9.0; + contract oracle { + struct request { + bytes data; + bytes _data; + } + event log (int msg, int _msg); + function addRequest(request memory req) public pure {} + function getRequest() pure public returns (request memory) { + return request("", ""); + } + } + `, + bytecode: []string{`0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033`}, + abi: []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`}, + imports: ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + tester: ` + var ( + key, _ = crypto.GenerateKey() + user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + ) + defer sim.Close() + + _, tx, _, err := DeployNameConflict(user, sim) + if err != nil { + t.Fatalf("DeployNameConflict() got err %v; want nil err", err) + } + sim.Commit() + if _, err = bind.WaitDeployed(nil, sim, tx); err != nil { t.Logf("Deployment tx: %+v", tx) t.Errorf("bind.WaitDeployed(nil, %T, ) got err %v; want nil err", sim, err) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index bd0f32ae2a..61601007aa 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -30,11 +30,13 @@ type Error struct { Name string Inputs Arguments str string + // Sig contains the string signature according to the ABI spec. - // e.g. event foo(uint32 a, int b) = "foo(uint32,int256)" + // e.g. error foo(uint32 a, int b) = "foo(uint32,int256)" // Please note that "int" is substitute for its canonical representation "int256" Sig string - // ID returns the canonical representation of the event's signature used by the + + // ID returns the canonical representation of the error's signature used by the // abi definition to identify event names and types. ID common.Hash } diff --git a/accounts/abi/event.go b/accounts/abi/event.go index 1eb53d9e91..65dcd940ea 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -29,24 +29,27 @@ import ( // don't get the signature canonical representation as the first LOG topic. type Event struct { // Name is the event name used for internal representation. It's derived from - // the raw name and a suffix will be added in the case of a event overload. + // the raw name and a suffix will be added in the case of event overloading. // // e.g. // These are two events that have the same name: // * foo(int,int) // * foo(uint,uint) - // The event name of the first one wll be resolved as foo while the second one + // The event name of the first one will be resolved as foo while the second one // will be resolved as foo0. Name string + // RawName is the raw event name parsed from ABI. RawName string Anonymous bool Inputs Arguments str string + // Sig contains the string signature according to the ABI spec. // e.g. event foo(uint32 a, int b) = "foo(uint32,int256)" // Please note that "int" is substitute for its canonical representation "int256" Sig string + // ID returns the canonical representation of the event's signature used by the // abi definition to identify event names and types. ID common.Hash diff --git a/accounts/abi/type.go b/accounts/abi/type.go index c70bf510ba..f0c682cebd 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -162,22 +162,26 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty elems []*Type names []string expression string // canonical parameter expression + used = make(map[string]bool) ) expression += "(" - overloadedNames := make(map[string]string) for idx, c := range components { cType, err := NewType(c.Type, c.InternalType, c.Components) if err != nil { return Type{}, err } - fieldName, err := overloadedArgName(c.Name, overloadedNames) + name := ToCamelCase(c.Name) + if name == "" { + return Type{}, errors.New("abi: purely anonymous or underscored field is not supported") + } + fieldName := ResolveNameConflict(name, func(s string) bool { return used[s] }) if err != nil { return Type{}, err } + used[fieldName] = true if !isValidFieldName(fieldName) { return Type{}, fmt.Errorf("field %d has invalid name", idx) } - overloadedNames[fieldName] = fieldName fields = append(fields, reflect.StructField{ Name: fieldName, // reflect.StructOf will panic for any exported field. Type: cType.GetType(), @@ -254,20 +258,6 @@ func (t Type) GetType() reflect.Type { } } -func overloadedArgName(rawName string, names map[string]string) (string, error) { - fieldName := ToCamelCase(rawName) - if fieldName == "" { - return "", errors.New("abi: purely anonymous or underscored field is not supported") - } - // Handle overloaded fieldNames - _, ok := names[fieldName] - for idx := 0; ok; idx++ { - fieldName = fmt.Sprintf("%s%d", ToCamelCase(rawName), idx) - _, ok = names[fieldName] - } - return fieldName, nil -} - // String implements Stringer. func (t Type) String() (out string) { return t.stringKind diff --git a/accounts/abi/utils.go b/accounts/abi/utils.go new file mode 100644 index 0000000000..e24df5b700 --- /dev/null +++ b/accounts/abi/utils.go @@ -0,0 +1,41 @@ +// Copyright 2022 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 . + +package abi + +import "fmt" + +// ResolveNameConflict returns the next available name for a given thing. +// This helper can be used for lots of purposes: +// +// - In solidity function overloading is supported, this function can fix +// the name conflicts of overloaded functions. +// - In golang binding generation, the parameter(in function, event, error, +// and struct definition) name will be converted to camelcase style which +// may eventually lead to name conflicts. +// +// Name conflicts are mostly resolved by adding number suffix. +// e.g. if the abi contains Methods send, send1 +// ResolveNameConflict would return send2 for input send. +func ResolveNameConflict(rawName string, used func(string) bool) string { + name := rawName + ok := used(name) + for idx := 0; ok; idx++ { + name = fmt.Sprintf("%s%d", rawName, idx) + ok = used(name) + } + return name +} diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 1184b072ab..1634be8476 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -198,7 +198,11 @@ func abigen(c *cli.Context) error { nameParts := strings.Split(name, ":") types = append(types, nameParts[len(nameParts)-1]) - libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] + // Derive the library placeholder which is a 34 character prefix of the + // hex encoding of the keccak256 hash of the fully qualified library name. + // Note that the fully qualified library name is the path of its source + // file and the library name separated by ":". + libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] // the first 2 chars are 0x libs[libPattern] = nameParts[len(nameParts)-1] } } From 9dda5b9819f401fed3aa24831088d5191651c987 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 184/280] accounts: more linters (#24783) --- accounts/abi/abi_test.go | 4 +--- accounts/abi/bind/backends/simulated_test.go | 3 +-- accounts/keystore/account_cache_test.go | 2 +- accounts/keystore/passphrase_test.go | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 7736892040..42de31b898 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1073,9 +1073,7 @@ func TestABI_EventById(t *testing.T) { } if event == nil { t.Errorf("We should find a event for topic %s, test #%d", topicID.Hex(), testnum) - } - - if event.ID != topicID { + } else if event.ID != topicID { t.Errorf("Event id %s does not match topic %s, test #%d", event.ID.Hex(), topicID.Hex(), testnum) } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 2432f11a39..1ab12790e4 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -620,8 +620,7 @@ func TestHeaderByNumber(t *testing.T) { } if latestBlockHeader == nil { t.Errorf("received a nil block header") - } - if latestBlockHeader.Number.Uint64() != uint64(0) { + } else if latestBlockHeader.Number.Uint64() != uint64(0) { t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64()) } diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 6416aa0435..88da7d77ec 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -384,7 +384,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { time.Sleep(1000 * time.Millisecond) // Now replace file contents with crap - if err := os.WriteFile(file, []byte("foo"), 0644); err != nil { + if err := os.WriteFile(file, []byte("foo"), 0600); err != nil { t.Fatal(err) return } diff --git a/accounts/keystore/passphrase_test.go b/accounts/keystore/passphrase_test.go index ba6c48e3cb..d843de3b94 100644 --- a/accounts/keystore/passphrase_test.go +++ b/accounts/keystore/passphrase_test.go @@ -52,7 +52,7 @@ func TestKeyEncryptDecrypt(t *testing.T) { t.Errorf("test %d: key address mismatch: have %x, want %x", i, key.Address, address) } // Recrypt with a new password and start over - password += "new data appended" + password += "new data appended" // nolint: gosec if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil { t.Errorf("test %d: failed to recrypt key %v", i, err) } From d9b4f0f2c3d68ed0b0c21573b25e2b07b1ef1169 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 185/280] accounts/abi: prefer new(big.Int) over big.NewInt(0) (#25087) --- accounts/abi/unpack.go | 10 ++++------ accounts/abi/unpack_test.go | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 45196c7a1a..256c2c650b 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -256,7 +256,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { // lengthPrefixPointsTo interprets a 32 byte slice as an offset and then determines which indices to look to decode the type. func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err error) { - bigOffsetEnd := big.NewInt(0).SetBytes(output[index : index+32]) + bigOffsetEnd := new(big.Int).SetBytes(output[index : index+32]) bigOffsetEnd.Add(bigOffsetEnd, common.Big32) outputLength := big.NewInt(int64(len(output))) @@ -269,11 +269,9 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err } offsetEnd := int(bigOffsetEnd.Uint64()) - lengthBig := big.NewInt(0).SetBytes(output[offsetEnd-32 : offsetEnd]) + lengthBig := new(big.Int).SetBytes(output[offsetEnd-32 : offsetEnd]) - totalSize := big.NewInt(0) - totalSize.Add(totalSize, bigOffsetEnd) - totalSize.Add(totalSize, lengthBig) + totalSize := new(big.Int).Add(bigOffsetEnd, lengthBig) if totalSize.BitLen() > 63 { return 0, 0, fmt.Errorf("abi: length larger than int64: %v", totalSize) } @@ -288,7 +286,7 @@ func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err // tuplePointsTo resolves the location reference for dynamic tuple. func tuplePointsTo(index int, output []byte) (start int, err error) { - offset := big.NewInt(0).SetBytes(output[index : index+32]) + offset := new(big.Int).SetBytes(output[index : index+32]) outputLen := big.NewInt(int64(len(output))) if offset.Cmp(outputLen) > 0 { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 751c97cd61..2dc5e3be99 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -424,7 +424,7 @@ func TestMultiReturnWithStringArray(t *testing.T) { } buff := new(bytes.Buffer) buff.Write(common.Hex2Bytes("000000000000000000000000000000000000000000000000000000005c1b78ea0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000001a055690d9db80000000000000000000000000000ab1257528b3782fb40d7ed5f72e624b744dffb2f00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008457468657265756d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001048656c6c6f2c20457468657265756d2100000000000000000000000000000000")) - temp, _ := big.NewInt(0).SetString("30000000000000000000", 10) + temp, _ := new(big.Int).SetString("30000000000000000000", 10) ret1, ret1Exp := new([3]*big.Int), [3]*big.Int{big.NewInt(1545304298), big.NewInt(6), temp} ret2, ret2Exp := new(common.Address), common.HexToAddress("ab1257528b3782fb40d7ed5f72e624b744dffb2f") ret3, ret3Exp := new([2]string), [2]string{"Ethereum", "Hello, Ethereum!"} From 53ea297d6ad8fe2aec29c73ef4f305e440837097 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 186/280] accounts/abi: replace fmt.Errorf with errors.New in abi argument (#25181) Replace unnecessary fmt.Errorf with errors.New in accounts/abi/argument.go --- accounts/abi/argument.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index c5326d5700..ed204e0a81 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -18,6 +18,7 @@ package abi import ( "encoding/json" + "errors" "fmt" "reflect" "strings" @@ -79,7 +80,7 @@ func (arguments Arguments) isTuple() bool { func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { if len(data) == 0 { if len(arguments.NonIndexed()) != 0 { - return nil, fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") + return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected") } return make([]interface{}, 0), nil } @@ -90,11 +91,11 @@ func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error { // Make sure map is not nil if v == nil { - return fmt.Errorf("abi: cannot unpack into a nil map") + return errors.New("abi: cannot unpack into a nil map") } if len(data) == 0 { if len(arguments.NonIndexed()) != 0 { - return fmt.Errorf("abi: attempting to unmarshall an empty string while arguments are expected") + return errors.New("abi: attempting to unmarshall an empty string while arguments are expected") } return nil // Nothing to unmarshal, return } @@ -116,7 +117,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error { } if len(values) == 0 { if len(arguments.NonIndexed()) != 0 { - return fmt.Errorf("abi: attempting to copy no values while arguments are expected") + return errors.New("abi: attempting to copy no values while arguments are expected") } return nil // Nothing to copy, return } From b62913b54fca95b8a5da8071ba22d2e7275fc250 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 187/280] accounts/scwallet: change format 0x%x to %#x (#25221) --- accounts/scwallet/securechannel.go | 4 ++-- accounts/scwallet/wallet.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index b973c8cac9..5c7f59b7e5 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -178,7 +178,7 @@ func (s *SecureChannelSession) mutuallyAuthenticate() error { return err } if response.Sw1 != 0x90 || response.Sw2 != 0x00 { - return fmt.Errorf("got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2) + return fmt.Errorf("got unexpected response from MUTUALLY_AUTHENTICATE: %#x%x", response.Sw1, response.Sw2) } if len(response.Data) != scSecretLength { @@ -261,7 +261,7 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b rapdu.deserialize(plainData) if rapdu.Sw1 != sw1Ok { - return nil, fmt.Errorf("unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) + return nil, fmt.Errorf("unexpected response status Cla=%#x, Ins=%#x, Sw=%#x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) } return rapdu, nil diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index d643a6839a..530bdd4d7b 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -167,7 +167,7 @@ func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) { } if response.Sw1 != sw1Ok { - return nil, fmt.Errorf("unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) + return nil, fmt.Errorf("unexpected insecure response status Cla=%#x, Ins=%#x, Sw=%#x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) } return response, nil From c5eecc55227013d2311852e98586d6cf9b6b97d2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 188/280] accounts/abi/bind/backends: return hash of new blocks (#25163) Co-authored-by: Jens --- accounts/abi/bind/backends/simulated.go | 6 ++- accounts/abi/bind/backends/simulated_test.go | 39 ++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index eb3026f184..fd93996f96 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -174,16 +174,20 @@ func (b *SimulatedBackend) Close() error { // Commit imports all the pending transactions as a single block and starts a // fresh new state. -func (b *SimulatedBackend) Commit() { +func (b *SimulatedBackend) Commit() common.Hash { b.mu.Lock() defer b.mu.Unlock() if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil { panic(err) // This cannot happen unless the simulator is wrong, fail in that case } + blockHash := b.pendingBlock.Hash() + // Using the last inserted block here makes it possible to build on a side // chain after a fork. b.rollback(b.pendingBlock) + + return blockHash } // Rollback aborts all pending transactions, reverting to the last committed state. diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 1ab12790e4..f37a57c25c 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -1309,3 +1309,42 @@ func TestForkResendTx(t *testing.T) { t.Errorf("TX included in wrong block: %d", h) } } + +func TestCommitReturnValue(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + + startBlockHeight := sim.blockchain.CurrentBlock().NumberU64() + + // Test if Commit returns the correct block hash + h1 := sim.Commit() + if h1 != sim.blockchain.CurrentBlock().Hash() { + t.Error("Commit did not return the hash of the last block.") + } + + // Create a block in the original chain (containing a transaction to force different block hashes) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) + tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) + sim.SendTransaction(context.Background(), tx) + h2 := sim.Commit() + + // Create another block in the original chain + sim.Commit() + + // Fork at the first bock + if err := sim.Fork(context.Background(), h1); err != nil { + t.Errorf("forking: %v", err) + } + + // Test if Commit returns the correct block hash after the reorg + h2fork := sim.Commit() + if h2 == h2fork { + t.Error("The block in the fork and the original block are the same block!") + } + if sim.blockchain.GetHeader(h2fork, startBlockHeight+2) == nil { + t.Error("Could not retrieve the just created block (side-chain)") + } +} From b3d89c0d84e9c78938daf0a9db25f5cf43172703 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 189/280] accounts/abi: substitude arg%d to the range keyword (#25307) * accounts/abi: substitude arg%d to the range keyword * support more keywords * review feedback --- accounts/abi/bind/bind.go | 41 ++++++++++++++++++++++++++++++++-- accounts/abi/bind/bind_test.go | 39 +++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 3f6eb4e91b..dc9a25e69b 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -40,6 +40,43 @@ const ( LangGo Lang = iota ) +func isKeyWord(arg string) bool { + switch arg { + case "break": + case "case": + case "chan": + case "const": + case "continue": + case "default": + case "defer": + case "else": + case "fallthrough": + case "for": + case "func": + case "go": + case "goto": + case "if": + case "import": + case "interface": + case "iota": + case "map": + case "make": + case "new": + case "package": + case "range": + case "return": + case "select": + case "struct": + case "switch": + case "type": + case "var": + default: + return false + } + + return true +} + // Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant // to be used as is in client code, but rather as an intermediate struct which // enforces compile time type safety and naming convention opposed to having to @@ -111,7 +148,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { - if input.Name == "" { + if input.Name == "" || isKeyWord(input.Name) { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } if hasStruct(input.Type) { @@ -155,7 +192,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] normalized.Inputs = make([]abi.Argument, len(original.Inputs)) copy(normalized.Inputs, original.Inputs) for j, input := range normalized.Inputs { - if input.Name == "" { + if input.Name == "" || isKeyWord(input.Name) { normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j) } // Event is a bit special, we need to define event struct in binding, diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index b9df18ce24..8b707b92b6 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1924,7 +1924,7 @@ var bindTests = []struct { } } `, - bytecode: []string{`0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033`}, + bytecode: []string{"0x608060405234801561001057600080fd5b5061042b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063c2bb515f1461003b578063cce7b04814610059575b600080fd5b610043610075565b60405161005091906101af565b60405180910390f35b610073600480360381019061006e91906103ac565b6100b5565b005b61007d6100b8565b604051806040016040528060405180602001604052806000815250815260200160405180602001604052806000815250815250905090565b50565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561010c5780820151818401526020810190506100f1565b8381111561011b576000848401525b50505050565b6000601f19601f8301169050919050565b600061013d826100d2565b61014781856100dd565b93506101578185602086016100ee565b61016081610121565b840191505092915050565b600060408301600083015184820360008601526101888282610132565b915050602083015184820360208601526101a28282610132565b9150508091505092915050565b600060208201905081810360008301526101c9818461016b565b905092915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61022282610121565b810181811067ffffffffffffffff82111715610241576102406101ea565b5b80604052505050565b60006102546101d1565b90506102608282610219565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561028f5761028e6101ea565b5b61029882610121565b9050602081019050919050565b82818337600083830152505050565b60006102c76102c284610274565b61024a565b9050828152602081018484840111156102e3576102e261026f565b5b6102ee8482856102a5565b509392505050565b600082601f83011261030b5761030a61026a565b5b813561031b8482602086016102b4565b91505092915050565b60006040828403121561033a576103396101e5565b5b610344604061024a565b9050600082013567ffffffffffffffff81111561036457610363610265565b5b610370848285016102f6565b600083015250602082013567ffffffffffffffff81111561039457610393610265565b5b6103a0848285016102f6565b60208301525092915050565b6000602082840312156103c2576103c16101db565b5b600082013567ffffffffffffffff8111156103e0576103df6101e0565b5b6103ec84828501610324565b9150509291505056fea264697066735822122033bca1606af9b6aeba1673f98c52003cec19338539fb44b86690ce82c51483b564736f6c634300080e0033"}, abi: []string{`[ { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "int256", "name": "msg", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "_msg", "type": "int256" } ], "name": "log", "type": "event" }, { "inputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "req", "type": "tuple" } ], "name": "addRequest", "outputs": [], "stateMutability": "pure", "type": "function" }, { "inputs": [], "name": "getRequest", "outputs": [ { "components": [ { "internalType": "bytes", "name": "data", "type": "bytes" }, { "internalType": "bytes", "name": "_data", "type": "bytes" } ], "internalType": "struct oracle.request", "name": "", "type": "tuple" } ], "stateMutability": "pure", "type": "function" } ]`}, imports: ` "math/big" @@ -1955,6 +1955,43 @@ var bindTests = []struct { } `, }, + { + name: "RangeKeyword", + contract: ` + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.4.22 <0.9.0; + contract keywordcontract { + function functionWithKeywordParameter(range uint256) public pure {} + } + `, + bytecode: []string{"0x608060405234801561001057600080fd5b5060dc8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063527a119f14602d575b600080fd5b60436004803603810190603f9190605b565b6045565b005b50565b6000813590506055816092565b92915050565b600060208284031215606e57606d608d565b5b6000607a848285016048565b91505092915050565b6000819050919050565b600080fd5b6099816083565b811460a357600080fd5b5056fea2646970667358221220d4f4525e2615516394055d369fb17df41c359e5e962734f27fd683ea81fd9db164736f6c63430008070033"}, + abi: []string{`[{"inputs":[{"internalType":"uint256","name":"range","type":"uint256"}],"name":"functionWithKeywordParameter","outputs":[],"stateMutability":"pure","type":"function"}]`}, + imports: ` + "math/big" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" + "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" + `, + tester: ` + var ( + key, _ = crypto.GenerateKey() + user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + ) + _, tx, _, err := DeployRangeKeyword(user, sim) + if err != nil { + t.Fatalf("error deploying contract: %v", err) + } + sim.Commit() + + if _, err = bind.WaitDeployed(nil, sim, tx); err != nil { + t.Errorf("error deploying the contract: %v", err) + } + `, + }, } // Tests that packages generated by the binder can be successfully compiled and From 78a35f1dc3d1b150e9912ab6b923ace619893704 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 190/280] accounts: lint whitespace (#25312) --- accounts/abi/bind/base_test.go | 1 - accounts/abi/error_handling.go | 1 - accounts/abi/event_test.go | 1 - accounts/abi/reflect.go | 1 - accounts/abi/unpack.go | 1 - accounts/keystore/keystore_test.go | 2 -- accounts/keystore/passphrase.go | 1 - 7 files changed, 8 deletions(-) diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 7fad9c7bb6..97972b352e 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -115,7 +115,6 @@ func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ether } func TestPassingBlockNumber(t *testing.T) { - mc := &mockPendingCaller{ mockCaller: &mockCaller{ codeAtBytes: []byte{1, 2, 3}, diff --git a/accounts/abi/error_handling.go b/accounts/abi/error_handling.go index f0f71b6c91..7add707292 100644 --- a/accounts/abi/error_handling.go +++ b/accounts/abi/error_handling.go @@ -73,7 +73,6 @@ func typeCheck(t Type, value reflect.Value) error { } else { return nil } - } // typeErr returns a formatted type casting error. diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index e5ac313742..7181026607 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -161,7 +161,6 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) { } func TestEventTupleUnpack(t *testing.T) { - type EventTransfer struct { Value *big.Int } diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index faa62a642b..e6d3ad7680 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -222,7 +222,6 @@ func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[stri // second round ~~~ for _, argName := range argNames { - structFieldName := ToCamelCase(argName) if structFieldName == "" { diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index 256c2c650b..a19ff8e387 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -116,7 +116,6 @@ func ReadFixedBytes(t Type, word []byte) (interface{}, error) { reflect.Copy(array, reflect.ValueOf(word[0:t.Size])) return array.Interface(), nil - } // forEachUnpack iteratively unpack elements. diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 82d576e521..cada74238e 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -378,7 +378,6 @@ func TestImportExport(t *testing.T) { if _, err = ks2.Import(json, "new", "new"); err == nil { t.Errorf("importing a key twice succeeded") } - } // TestImportRace tests the keystore on races. @@ -403,7 +402,6 @@ func TestImportRace(t *testing.T) { if _, err := ks2.Import(json, "new", "new"); err != nil { atomic.AddUint32(&atom, 1) } - }() } wg.Wait() diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index 9492b8311f..aad14137d5 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -340,7 +340,6 @@ func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) { r := ensureInt(cryptoJSON.KDFParams["r"]) p := ensureInt(cryptoJSON.KDFParams["p"]) return scrypt.Key(authArray, salt, n, r, p, dkLen) - } else if cryptoJSON.KDF == "pbkdf2" { c := ensureInt(cryptoJSON.KDFParams["c"]) prf := cryptoJSON.KDFParams["prf"].(string) From 08fedbb50325eabc98ce58a73241d77d1e3bb765 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 191/280] accounts/abi: display name in "method/event not found" error (#25512) --- accounts/abi/abi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 70eda9a5d8..f68d94c961 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -95,7 +95,7 @@ func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { args = event.Inputs } if args == nil { - return nil, errors.New("abi: could not locate named method or event") + return nil, fmt.Errorf("abi: could not locate named method or event: %s", name) } return args, nil } From c046f36afdc0c629f84946617f852b2a3dfeb508 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 192/280] accounts: fix some typos (#25551) --- accounts/abi/reflect_test.go | 2 +- accounts/keystore/account_cache_test.go | 2 +- accounts/keystore/file_cache.go | 4 ++-- accounts/keystore/keystore_test.go | 2 +- accounts/usbwallet/trezor.go | 4 ++-- accounts/usbwallet/wallet.go | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index cf13a79da8..76ef1ad2aa 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -32,7 +32,7 @@ type reflectTest struct { var reflectTests = []reflectTest{ { - name: "OneToOneCorrespondance", + name: "OneToOneCorrespondence", args: []string{"fieldA"}, struc: struct { FieldA int `abi:"fieldA"` diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 88da7d77ec..05caa7a975 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -319,7 +319,7 @@ func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { func TestUpdatedKeyfileContents(t *testing.T) { t.Parallel() - // Create a temporary kesytore to test with + // Create a temporary keystore to test with rand.Seed(time.Now().UnixNano()) dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index cd1306d32a..f2bd7efbe6 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -39,7 +39,7 @@ type fileCache struct { func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, error) { t0 := time.Now() - // List all the failes from the keystore folder + // List all the files from the keystore folder files, err := os.ReadDir(keyDir) if err != nil { return nil, nil, nil, err @@ -61,7 +61,7 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er log.Trace("Ignoring file on account scan", "path", path) continue } - // Gather the set of all and fresly modified files + // Gather the set of all and freshly modified files all.Add(path) info, err := fi.Info() diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index cada74238e..d2042fe6a9 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -214,7 +214,7 @@ func TestSignRace(t *testing.T) { // Tests that the wallet notifier loop starts and stops correctly based on the // addition and removal of wallet event subscriptions. func TestWalletNotifierLifecycle(t *testing.T) { - // Create a temporary kesytore to test with + // Create a temporary keystore to test with _, ks := tmpKeyStore(t, false) // Ensure that the notification updater is not running yet diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 5d36ce9909..52ca4b2d83 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -197,10 +197,10 @@ func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, er if _, err := w.trezorExchange(&trezor.EthereumGetAddress{AddressN: derivationPath}, address); err != nil { return common.Address{}, err } - if addr := address.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary fomats + if addr := address.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary formats return common.BytesToAddress(addr), nil } - if addr := address.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal fomats + if addr := address.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal formats return common.HexToAddress(addr), nil } return common.Address{}, errors.New("missing derived address") diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index f8e331c6dd..4377f16af7 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -380,7 +380,7 @@ func (w *wallet) selfDerive() { // of legacy-ledger, the first account on the legacy-path will // be shown to the user, even if we don't actively track it if i < len(nextAddrs)-1 { - w.log.Info("Skipping trakcking first account on legacy path, use personal.deriveAccount(,, false) to track", + w.log.Info("Skipping tracking first account on legacy path, use personal.deriveAccount(,, false) to track", "path", path, "address", nextAddrs[i]) break } From b6be9c181c8329a63a4af47a2c1d7bb065cf87ab Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 193/280] accounts/abi/bind/backends: typo fix (#25549) --- accounts/abi/bind/backends/simulated.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fd93996f96..3dc555d603 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -659,7 +659,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // User specified the legacy gas field, convert to 1559 gas typing call.GasFeeCap, call.GasTipCap = call.GasPrice, call.GasPrice } else { - // User specified 1559 gas feilds (or none), use those + // User specified 1559 gas fields (or none), use those if call.GasFeeCap == nil { call.GasFeeCap = new(big.Int) } From aec9d767cc367024e4bcdc8c56188d1798d2589d Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 194/280] accounts/abi: fix set function (#25477) * accounts/abi: fix set function * don't break things * update test --- accounts/abi/reflect.go | 2 +- accounts/abi/unpack_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index e6d3ad7680..fb3b163c49 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -101,7 +101,7 @@ func mustArrayToByteSlice(value reflect.Value) reflect.Value { func set(dst, src reflect.Value) error { dstType, srcType := dst.Type(), src.Type() switch { - case dstType.Kind() == reflect.Interface && dst.Elem().IsValid(): + case dstType.Kind() == reflect.Interface && dst.Elem().IsValid() && (dst.Elem().Type().Kind() == reflect.Ptr || dst.Elem().CanSet()): return set(dst.Elem(), src) case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeOf(big.Int{}): return set(dst.Elem(), src) diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 2dc5e3be99..8947211634 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -352,6 +352,11 @@ func TestMethodMultiReturn(t *testing.T) { &[]interface{}{&expected.Int, &expected.String}, "", "Can unpack into a slice", + }, { + &[]interface{}{&bigint, ""}, + &[]interface{}{&expected.Int, expected.String}, + "", + "Can unpack into a slice without indirection", }, { &[2]interface{}{&bigint, new(string)}, &[2]interface{}{&expected.Int, &expected.String}, From bdf80d77e41d0f682938d11a48ad49a62aa43ef9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 195/280] accounts/abi/bind: add const for tx fee elasticity multiplier (#25504) Co-authored-by: Felix Lange Co-authored-by: rjl493456442 --- accounts/abi/bind/base.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 5c63a66aad..bdc479537d 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -36,6 +36,8 @@ var ( errNoEventSignature = errors.New("no event signature") ) +const basefeeWiggleMultiplier = 2 + // SignerFn is a signer function callback when a contract requires a method to // sign the transaction before submission. type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error) @@ -258,7 +260,7 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add if gasFeeCap == nil { gasFeeCap = new(big.Int).Add( gasTipCap, - new(big.Int).Mul(head.BaseFee, big.NewInt(2)), + new(big.Int).Mul(head.BaseFee, big.NewInt(basefeeWiggleMultiplier)), ) } if gasFeeCap.Cmp(gasTipCap) < 0 { From e2b5a03ce8e7c5422dd3be686d376d97dbd4a5c1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 196/280] accounts: lint comments (#25726) --- accounts/abi/abi_test.go | 25 ++++--- accounts/abi/bind/backends/simulated_test.go | 73 ++++++++++---------- accounts/abi/reflect.go | 27 ++++---- accounts/abi/utils.go | 15 ++-- accounts/usbwallet/ledger.go | 34 +++++---- 5 files changed, 89 insertions(+), 85 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 42de31b898..08fb9248ba 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -165,8 +165,9 @@ func TestInvalidABI(t *testing.T) { // TestConstructor tests a constructor function. // The test is based on the following contract: -// contract TestConstructor { -// constructor(uint256 a, uint256 b) public{} +// +// contract TestConstructor { +// constructor(uint256 a, uint256 b) public{} // } func TestConstructor(t *testing.T) { json := `[{ "inputs": [{"internalType": "uint256","name": "a","type": "uint256" },{ "internalType": "uint256","name": "b","type": "uint256"}],"stateMutability": "nonpayable","type": "constructor"}]` @@ -727,12 +728,12 @@ func TestBareEvents(t *testing.T) { // TestUnpackEvent is based on this contract: // // contract T { -// event received(address sender, uint amount, bytes memo); -// event receivedAddr(address sender); -// function receive(bytes memo) external payable { -// received(msg.sender, msg.value, memo); -// receivedAddr(msg.sender); -// } +// event received(address sender, uint amount, bytes memo); +// event receivedAddr(address sender); +// function receive(bytes memo) external payable { +// received(msg.sender, msg.value, memo); +// receivedAddr(msg.sender); +// } // } // // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: @@ -1113,8 +1114,9 @@ func TestDoubleDuplicateMethodNames(t *testing.T) { // TestDoubleDuplicateEventNames checks that if send0 already exists, there won't be a name // conflict and that the second send event will be renamed send1. // The test runs the abi of the following contract. -// contract DuplicateEvent { -// event send(uint256 a); +// +// contract DuplicateEvent { +// event send(uint256 a); // event send0(); // event send(); // } @@ -1141,7 +1143,8 @@ func TestDoubleDuplicateEventNames(t *testing.T) { // TestUnnamedEventParam checks that an event with unnamed parameters is // correctly handled. // The test runs the abi of the following contract. -// contract TestEvent { +// +// contract TestEvent { // event send(uint256, uint256); // } func TestUnnamedEventParam(t *testing.T) { diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index f37a57c25c..771f31645d 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -95,7 +95,8 @@ func TestSimulatedBackend(t *testing.T) { var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") -// the following is based on this contract: +// the following is based on this contract: +// // contract T { // event received(address sender, uint amount, bytes memo); // event receivedAddr(address sender); @@ -103,7 +104,7 @@ var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d // function receive(bytes calldata memo) external payable returns (string memory res) { // emit received(msg.sender, msg.value, memo); // emit receivedAddr(msg.sender); -// return "hello world"; +// return "hello world"; // } // } const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` @@ -412,12 +413,13 @@ func TestEstimateGas(t *testing.T) { /* pragma solidity ^0.6.4; contract GasEstimation { - function PureRevert() public { revert(); } - function Revert() public { revert("revert reason");} - function OOG() public { for (uint i = 0; ; i++) {}} - function Assert() public { assert(false);} - function Valid() public {} - }*/ + function PureRevert() public { revert(); } + function Revert() public { revert("revert reason");} + function OOG() public { for (uint i = 0; ; i++) {}} + function Assert() public { assert(false);} + function Valid() public {} + } + */ const contractAbi = "[{\"inputs\":[],\"name\":\"Assert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OOG\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PureRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Revert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Valid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" const contractBin = "0x60806040523480156100115760006000fd5b50610017565b61016e806100266000396000f3fe60806040523480156100115760006000fd5b506004361061005c5760003560e01c806350f6fe3414610062578063aa8b1d301461006c578063b9b046f914610076578063d8b9839114610080578063e09fface1461008a5761005c565b60006000fd5b61006a610094565b005b6100746100ad565b005b61007e6100b5565b005b6100886100c2565b005b610092610135565b005b6000600090505b5b808060010191505061009b565b505b565b60006000fd5b565b600015156100bf57fe5b5b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f72657665727420726561736f6e0000000000000000000000000000000000000081526020015060200191505060405180910390fd5b565b5b56fea2646970667358221220345bbcbb1a5ecf22b53a78eaebf95f8ee0eceff6d10d4b9643495084d2ec934a64736f6c63430006040033" @@ -1029,28 +1031,29 @@ func TestPendingAndCallContract(t *testing.T) { // This test is based on the following contract: /* contract Reverter { - function revertString() public pure{ - require(false, "some error"); - } - function revertNoString() public pure { - require(false, ""); - } - function revertASM() public pure { - assembly { - revert(0x0, 0x0) - } - } - function noRevert() public pure { - assembly { - // Assembles something that looks like require(false, "some error") but is not reverted - mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020) - mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a) - mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000) - return(0x0, 0x64) - } - } -}*/ + function revertString() public pure{ + require(false, "some error"); + } + function revertNoString() public pure { + require(false, ""); + } + function revertASM() public pure { + assembly { + revert(0x0, 0x0) + } + } + function noRevert() public pure { + assembly { + // Assembles something that looks like require(false, "some error") but is not reverted + mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000) + mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020) + mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a) + mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000) + return(0x0, 0x64) + } + } +} +*/ func TestCallContractRevert(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -1176,11 +1179,10 @@ func TestFork(t *testing.T) { /* Example contract to test event emission: -pragma solidity >=0.7.0 <0.9.0; - + pragma solidity >=0.7.0 <0.9.0; contract Callable { - event Called(); - function Call() public { emit Called(); } + event Called(); + function Call() public { emit Called(); } } */ const callableAbi = "[{\"anonymous\":false,\"inputs\":[],\"name\":\"Called\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"Call\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" @@ -1199,8 +1201,7 @@ const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3f // 7. Mine two blocks to trigger a reorg. // 8. Check that the event was removed. // 9. Re-send the transaction and mine a block. -// -// 10. Check that the event was reborn. +// 10. Check that the event was reborn. func TestForkLogsReborn(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index fb3b163c49..c460c1ac92 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -25,9 +25,9 @@ import ( ) // ConvertType converts an interface of a runtime type into a interface of the -// given type -// e.g. turn -// var fields []reflect.StructField +// given type, e.g. turn this code: +// +// var fields []reflect.StructField // // fields = append(fields, reflect.StructField{ // Name: "X", @@ -35,8 +35,9 @@ import ( // Tag: reflect.StructTag("json:\"" + "x" + "\""), // } // -// into -// type TupleT struct { X *big.Int } +// into: +// +// type TupleT struct { X *big.Int } func ConvertType(in interface{}, proto interface{}) interface{} { protoType := reflect.TypeOf(proto) if reflect.TypeOf(in).ConvertibleTo(protoType) { @@ -154,7 +155,7 @@ func setArray(dst, src reflect.Value) error { dst.Set(array) return nil } - return errors.New("Cannot set array, destination not settable") + return errors.New("cannot set array, destination not settable") } func setStruct(dst, src reflect.Value) error { @@ -162,7 +163,7 @@ func setStruct(dst, src reflect.Value) error { srcField := src.Field(i) dstField := dst.Field(i) if !dstField.IsValid() || !srcField.IsValid() { - return fmt.Errorf("Could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField) + return fmt.Errorf("could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField) } if err := set(dstField, srcField); err != nil { return err @@ -172,11 +173,13 @@ func setStruct(dst, src reflect.Value) error { } // mapArgNamesToStructFields maps a slice of argument names to struct fields. -// first round: for each Exportable field that contains a `abi:""` tag -// and this field name exists in the given argument name list, pair them together. -// second round: for each argument name that has not been already linked, -// find what variable is expected to be mapped into, if it exists and has not been -// used, pair them. +// +// first round: for each Exportable field that contains a `abi:""` tag and this field name +// exists in the given argument name list, pair them together. +// +// second round: for each argument name that has not been already linked, find what +// variable is expected to be mapped into, if it exists and has not been used, pair them. +// // Note this function assumes the given value is a struct value. func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) { typ := value.Type() diff --git a/accounts/abi/utils.go b/accounts/abi/utils.go index e24df5b700..b1537ca58d 100644 --- a/accounts/abi/utils.go +++ b/accounts/abi/utils.go @@ -21,15 +21,14 @@ import "fmt" // ResolveNameConflict returns the next available name for a given thing. // This helper can be used for lots of purposes: // -// - In solidity function overloading is supported, this function can fix -// the name conflicts of overloaded functions. -// - In golang binding generation, the parameter(in function, event, error, -// and struct definition) name will be converted to camelcase style which -// may eventually lead to name conflicts. +// - In solidity function overloading is supported, this function can fix +// the name conflicts of overloaded functions. +// - In golang binding generation, the parameter(in function, event, error, +// and struct definition) name will be converted to camelcase style which +// may eventually lead to name conflicts. // -// Name conflicts are mostly resolved by adding number suffix. -// e.g. if the abi contains Methods send, send1 -// ResolveNameConflict would return send2 for input send. +// Name conflicts are mostly resolved by adding number suffix. e.g. if the abi contains +// Methods "send" and "send1", ResolveNameConflict would return "send2" for input "send". func ResolveNameConflict(rawName string, used func(string) bool) string { name := rawName ok := used(name) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 2e051d071d..acf889262a 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -392,30 +392,28 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction // // The signing protocol is defined as follows: // -// CLA | INS | P1 | P2 | Lc | Le -// ----+-----+----+-----------------------------+-----+--- -// E0 | 0C | 00 | implementation version : 00 | variable | variable +// CLA | INS | P1 | P2 | Lc | Le +// ----+-----+----+-----------------------------+-----+--- +// E0 | 0C | 00 | implementation version : 00 | variable | variable // // Where the input is: // -// Description | Length -// -------------------------------------------------+---------- -// Number of BIP 32 derivations to perform (max 10) | 1 byte -// First derivation index (big endian) | 4 bytes -// ... | 4 bytes -// Last derivation index (big endian) | 4 bytes -// domain hash | 32 bytes -// message hash | 32 bytes -// -// +// Description | Length +// -------------------------------------------------+---------- +// Number of BIP 32 derivations to perform (max 10) | 1 byte +// First derivation index (big endian) | 4 bytes +// ... | 4 bytes +// Last derivation index (big endian) | 4 bytes +// domain hash | 32 bytes +// message hash | 32 bytes // // And the output data is: // -// Description | Length -// ------------+--------- -// signature V | 1 byte -// signature R | 32 bytes -// signature S | 32 bytes +// Description | Length +// ------------+--------- +// signature V | 1 byte +// signature R | 32 bytes +// signature S | 32 bytes func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHash []byte, messageHash []byte) ([]byte, error) { // Flatten the derivation path into the Ledger request path := make([]byte, 1+4*len(derivationPath)) From 0389524da8d3c9b7a946ce5d650a32eaf6300a29 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 197/280] accounts/abi: fix typo in error message (#25742) --- accounts/abi/unpack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index a19ff8e387..ecffdf18b4 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -124,7 +124,7 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) return nil, fmt.Errorf("cannot marshal input to array, size is negative (%d)", size) } if start+32*size > len(output) { - return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size) + return nil, fmt.Errorf("abi: cannot marshal into go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size) } // this value will become our slice or our array, depending on the type From fde9a7e270dcbc6ec728b2f06d7a4b7656bb6965 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 198/280] cmd/abigen: redefine appp (#25851) --- cmd/abigen/main.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 1634be8476..cfdde3c10d 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -33,13 +33,6 @@ import ( "github.com/urfave/cli/v2" ) -var ( - // Git SHA1 commit hash of the release (set via linker flags) - gitCommit = "" - - app *cli.App -) - var ( // Flags needed by abigen abiFlag = &cli.StringFlag{ @@ -81,8 +74,9 @@ var ( } ) +var app = flags.NewApp("", "XDC ABI wrapper code generator") + func init() { - app = flags.NewApp(gitCommit, "ethereum checkpoint helper tool") app.Name = "abigen" app.Flags = []cli.Flag{ abiFlag, From 06394ca3c83182224bc0d37616f6f6a4316280f0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 199/280] cmd/abigen: change --exc to exclude by type name (#22620) The abigen exclusion pattern, previously on the form "path:type", now supports wildcards. Examples "*:type" to exclude a named type in all files, or "/path/to/foo.sol:*" all types in foo.sol. --- cmd/abigen/main.go | 20 +++++++----- cmd/abigen/namefilter.go | 58 +++++++++++++++++++++++++++++++++++ cmd/abigen/namefilter_test.go | 38 +++++++++++++++++++++++ 3 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 cmd/abigen/namefilter.go create mode 100644 cmd/abigen/namefilter_test.go diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index cfdde3c10d..3560b4a505 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -152,9 +152,12 @@ func abigen(c *cli.Context) error { types = append(types, kind) } else { // Generate the list of types to exclude from binding - exclude := make(map[string]bool) - for _, kind := range strings.Split(c.String(excFlag.Name), ",") { - exclude[strings.ToLower(kind)] = true + var exclude *nameFilter + if c.IsSet(excFlag.Name) { + var err error + if exclude, err = newNameFilter(strings.Split(c.String(excFlag.Name), ",")...); err != nil { + utils.Fatalf("Failed to parse excludes: %v", err) + } } var contracts map[string]*compiler.Contract @@ -179,7 +182,11 @@ func abigen(c *cli.Context) error { } // Gather all non-excluded contract for binding for name, contract := range contracts { - if exclude[strings.ToLower(name)] { + // fully qualified name is of the form : + nameParts := strings.Split(name, ":") + typeName := nameParts[len(nameParts)-1] + if exclude != nil && exclude.Matches(name) { + fmt.Fprintf(os.Stderr, "excluding: %v\n", name) continue } abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse @@ -189,15 +196,14 @@ func abigen(c *cli.Context) error { abis = append(abis, string(abi)) bins = append(bins, contract.Code) sigs = append(sigs, contract.Hashes) - nameParts := strings.Split(name, ":") - types = append(types, nameParts[len(nameParts)-1]) + types = append(types, typeName) // Derive the library placeholder which is a 34 character prefix of the // hex encoding of the keccak256 hash of the fully qualified library name. // Note that the fully qualified library name is the path of its source // file and the library name separated by ":". libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] // the first 2 chars are 0x - libs[libPattern] = nameParts[len(nameParts)-1] + libs[libPattern] = typeName } } // Extract all aliases from the flags diff --git a/cmd/abigen/namefilter.go b/cmd/abigen/namefilter.go new file mode 100644 index 0000000000..eea5c643c4 --- /dev/null +++ b/cmd/abigen/namefilter.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "strings" +) + +type nameFilter struct { + fulls map[string]bool // path/to/contract.sol:Type + files map[string]bool // path/to/contract.sol:* + types map[string]bool // *:Type +} + +func newNameFilter(patterns ...string) (*nameFilter, error) { + f := &nameFilter{ + fulls: make(map[string]bool), + files: make(map[string]bool), + types: make(map[string]bool), + } + for _, pattern := range patterns { + if err := f.add(pattern); err != nil { + return nil, err + } + } + return f, nil +} + +func (f *nameFilter) add(pattern string) error { + ft := strings.Split(pattern, ":") + if len(ft) != 2 { + // filenames and types must not include ':' symbol + return fmt.Errorf("invalid pattern: %s", pattern) + } + + file, typ := ft[0], ft[1] + if file == "*" { + f.types[typ] = true + return nil + } else if typ == "*" { + f.files[file] = true + return nil + } + f.fulls[pattern] = true + return nil +} + +func (f *nameFilter) Matches(name string) bool { + ft := strings.Split(name, ":") + if len(ft) != 2 { + // If contract names are always of the fully-qualified form + // :, then this case will never happen. + return false + } + + file, typ := ft[0], ft[1] + // full paths > file paths > types + return f.fulls[name] || f.files[file] || f.types[typ] +} diff --git a/cmd/abigen/namefilter_test.go b/cmd/abigen/namefilter_test.go new file mode 100644 index 0000000000..42ba55be5e --- /dev/null +++ b/cmd/abigen/namefilter_test.go @@ -0,0 +1,38 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNameFilter(t *testing.T) { + _, err := newNameFilter("Foo") + require.Error(t, err) + _, err = newNameFilter("too/many:colons:Foo") + require.Error(t, err) + + f, err := newNameFilter("a/path:A", "*:B", "c/path:*") + require.NoError(t, err) + + for _, tt := range []struct { + name string + match bool + }{ + {"a/path:A", true}, + {"unknown/path:A", false}, + {"a/path:X", false}, + {"unknown/path:X", false}, + {"any/path:B", true}, + {"c/path:X", true}, + {"c/path:foo:B", false}, + } { + match := f.Matches(tt.name) + if tt.match { + assert.True(t, match, "expected match") + } else { + assert.False(t, match, "expected no match") + } + } +} From 73947f03b7487a73b603882384682da7b197f9fd Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 200/280] accounts/abi/bind/backends: fix AdjustTime to respect Fork (#25225) --- accounts/abi/bind/backends/simulated.go | 7 ++++++- accounts/abi/bind/backends/simulated_test.go | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 3dc555d603..9a71791da7 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -844,8 +844,13 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { if len(b.pendingBlock.Transactions()) != 0 { return errors.New("could not adjust time on non-empty block") } + // Get the last block + block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash()) + if block == nil { + return fmt.Errorf("could not find parent") + } - blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { + blocks, _ := core.GenerateChain(b.config, block, b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { block.OffsetTime(int64(adjustment.Seconds())) }) stateDB, _ := b.blockchain.State() diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 771f31645d..da0b0947ec 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -1349,3 +1349,23 @@ func TestCommitReturnValue(t *testing.T) { t.Error("Could not retrieve the just created block (side-chain)") } } + +// TestAdjustTimeAfterFork ensures that after a fork, AdjustTime uses the pending fork +// block's parent rather than the canonical head's parent. +func TestAdjustTimeAfterFork(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + + sim.Commit() // h1 + h1 := sim.blockchain.CurrentHeader().Hash() + sim.Commit() // h2 + sim.Fork(context.Background(), h1) + sim.AdjustTime(1 * time.Second) + sim.Commit() + + head := sim.blockchain.CurrentHeader() + if head.Number == common.Big2 && head.ParentHash != h1 { + t.Errorf("failed to build block on fork") + } +} From 98c67ab2d9076597d58438b8022278d044ad0abf Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 201/280] accounts/abi: return toGoType error immediately (#25565) --- accounts/abi/argument.go | 6 +++--- accounts/abi/unpack.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index ed204e0a81..2e48d539e0 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -187,6 +187,9 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { virtualArgs := 0 for index, arg := range nonIndexedArgs { marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data) + if err != nil { + return nil, err + } if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. @@ -204,9 +207,6 @@ func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) { // coded as just like uint256,bool,uint256 virtualArgs += getTypeSize(arg.Type)/32 - 1 } - if err != nil { - return nil, err - } retval = append(retval, marshalledValue) } return retval, nil diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index ecffdf18b4..fb5169fa80 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -163,6 +163,9 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { virtualArgs := 0 for index, elem := range t.TupleElems { marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output) + if err != nil { + return nil, err + } if elem.T == ArrayTy && !isDynamicType(*elem) { // If we have a static array, like [3]uint256, these are coded as // just like uint256,uint256,uint256. @@ -180,9 +183,6 @@ func forTupleUnpack(t Type, output []byte) (interface{}, error) { // coded as just like uint256,bool,uint256 virtualArgs += getTypeSize(*elem)/32 - 1 } - if err != nil { - return nil, err - } retval.Field(index).Set(reflect.ValueOf(marshalledValue)) } return retval.Interface(), nil From c241fc3574dafd7ff80ebed5f3cef093239b4247 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 202/280] eth/filters: fix for eth_getLogs failing with tag (#25922) --- accounts/abi/bind/backends/simulated.go | 27 +++++++++++++++++--- eth/filters/filter.go | 33 +++++++++++++++++++------ eth/filters/filter_system_test.go | 13 +++++++--- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 9a71791da7..0e77a27b24 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -895,11 +895,32 @@ type filterBackend struct { func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } -func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { - if block == rpc.LatestBlockNumber { +func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + switch number { + case rpc.PendingBlockNumber: + if block := fb.backend.pendingBlock; block != nil { + return block.Header(), nil + } + return nil, nil + case rpc.LatestBlockNumber: return fb.bc.CurrentHeader(), nil + case rpc.CommittedBlockNumber: + if fb.bc.Config().XDPoS == nil { + return nil, errors.New("only XDPoS v2 supports committed block lookup") + } + current := fb.bc.CurrentBlock().Header() + if fb.bc.Config().XDPoS.BlockConsensusVersion( + current.Number, + current.Extra, + XDPoS.ExtraFieldCheck, + ) == params.ConsensusEngineVersion2 { + confirmedHash := fb.bc.Engine().(*XDPoS.XDPoS).EngineV2.GetLatestCommittedBlockInfo().Hash + return fb.bc.GetHeaderByHash(confirmedHash), nil + } + return nil, errors.New("only XDPoS v2 can lookup committed block") + default: + return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil } - return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 3defe854f8..3479860b2b 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -119,20 +119,39 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, nil } var ( - head = header.Number.Uint64() - end = uint64(f.end) + err error + head = header.Number.Int64() pending = f.end == rpc.PendingBlockNumber.Int64() ) - if f.begin == rpc.LatestBlockNumber.Int64() { - f.begin = int64(head) + resolveSpecial := func(number int64) (int64, error) { + var hdr *types.Header + switch number { + case rpc.LatestBlockNumber.Int64(): + return head, nil + case rpc.PendingBlockNumber.Int64(): + // we should return head here since we've already captured + // that we need to get the pending logs in the pending boolean above + return head, nil + case rpc.CommittedBlockNumber.Int64(): + hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.CommittedBlockNumber) + if hdr == nil { + return 0, errors.New("committed header not found") + } + default: + return number, nil + } + return hdr.Number.Int64(), nil } - if f.end == rpc.LatestBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() { - end = head + if f.begin, err = resolveSpecial(f.begin); err != nil { + return nil, err + } + if f.end, err = resolveSpecial(f.end); err != nil { + return nil, err } // Gather all indexed logs, and finish with non indexed ones var ( logs []*types.Log - err error + end = uint64(f.end) size, sections = f.sys.backend.BloomStatus() ) if indexed := sections * size; indexed > uint64(f.begin) { diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index b3b07243e0..0aa3e12949 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -57,16 +57,21 @@ func (b *testBackend) ChainDb() ethdb.Database { } func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { - var hash common.Hash - var num uint64 - if blockNr == rpc.LatestBlockNumber { + var ( + hash common.Hash + num uint64 + ) + switch blockNr { + case rpc.LatestBlockNumber: hash = rawdb.ReadHeadBlockHash(b.db) number := rawdb.ReadHeaderNumber(b.db, hash) if number == nil { return nil, nil } num = *number - } else { + case rpc.CommittedBlockNumber: + return nil, nil + default: num = uint64(blockNr) hash = rawdb.ReadCanonicalHash(b.db, num) } From 80f3eaac01ab8470745ff69b8b590de20a384f87 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 203/280] accounts/usbwallet: support Ledger Nano S Plus and FTS (#25933) * usbwallet support Ledger Nano S Plus * accounts/usbwallet: add definitions + ref to ledger docs Co-authored-by: Martin Holst Swende --- accounts/usbwallet/hub.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 4041359ad3..5d33432667 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -71,18 +71,28 @@ type Hub struct { // NewLedgerHub creates a new hardware wallet manager for Ledger devices. func NewLedgerHub() (*Hub, error) { return newHub(LedgerScheme, 0x2c97, []uint16{ + + // Device definitions taken from + // https://github.com/LedgerHQ/ledger-live/blob/38012bc8899e0f07149ea9cfe7e64b2c146bc92b/libs/ledgerjs/packages/devices/src/index.ts + // Original product IDs 0x0000, /* Ledger Blue */ 0x0001, /* Ledger Nano S */ 0x0004, /* Ledger Nano X */ + 0x0005, /* Ledger Nano S Plus */ + 0x0006, /* Ledger Nano FTS */ - // Upcoming product IDs: https://www.ledger.com/2019/05/17/windows-10-update-sunsetting-u2f-tunnel-transport-for-ledger-devices/ 0x0015, /* HID + U2F + WebUSB Ledger Blue */ 0x1015, /* HID + U2F + WebUSB Ledger Nano S */ 0x4015, /* HID + U2F + WebUSB Ledger Nano X */ + 0x5015, /* HID + U2F + WebUSB Ledger Nano S Plus */ + 0x6015, /* HID + U2F + WebUSB Ledger Nano FTS */ + 0x0011, /* HID + WebUSB Ledger Blue */ 0x1011, /* HID + WebUSB Ledger Nano S */ 0x4011, /* HID + WebUSB Ledger Nano X */ + 0x5011, /* HID + WebUSB Ledger Nano S Plus */ + 0x6011, /* HID + WebUSB Ledger Nano FTS */ }, 0xffa0, 0, newLedgerDriver) } From 669b5e081dad3703b3cab1d51fc8f229b942a14c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 204/280] accounts: fix spelling mistakes (#25961) --- accounts/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/manager.go b/accounts/manager.go index a1f3afed2f..7097cbe543 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -257,7 +257,7 @@ func merge(slice []Wallet, wallets ...Wallet) []Wallet { return slice } -// drop is the couterpart of merge, which looks up wallets from within the sorted +// drop is the counterpart of merge, which looks up wallets from within the sorted // cache and removes the ones specified. func drop(slice []Wallet, wallets ...Wallet) []Wallet { for _, wallet := range wallets { From a79d2a2ed3476a1b8c292a8269687a5cb9e38c94 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 205/280] accounts/keystore: faster tests (#25827) This PR removes some optimistic tests -- a'la "do something, wait a while, and hope it has trickled through and continue" -- and instead uses some introspection to ensure that prerequisites are met. --- accounts/keystore/account_cache.go | 8 +++ accounts/keystore/account_cache_test.go | 92 +++++++++++++------------ accounts/keystore/keystore.go | 8 +++ accounts/keystore/keystore_test.go | 65 +++++++++-------- accounts/keystore/watch.go | 9 ++- accounts/keystore/watch_fallback.go | 8 ++- 6 files changed, 112 insertions(+), 78 deletions(-) diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index 19ca637591..ad497d7e0f 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -146,6 +146,14 @@ func (ac *accountCache) deleteByFile(path string) { } } +// watcherStarted returns true if the watcher loop started running (even if it +// has since also ended). +func (ac *accountCache) watcherStarted() bool { + ac.mu.Lock() + defer ac.mu.Unlock() + return ac.watcher.running || ac.watcher.runEnded +} + func removeAccount(slice []accounts.Account, elem accounts.Account) []accounts.Account { for i := range slice { if slice[i] == elem { diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 05caa7a975..6c1bbd82b3 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -17,7 +17,6 @@ package keystore import ( - "errors" "fmt" "math/rand" "os" @@ -51,6 +50,38 @@ var ( } ) +// waitWatcherStarts waits up to 1s for the keystore watcher to start. +func waitWatcherStart(ks *KeyStore) bool { + // On systems where file watch is not supported, just return "ok". + if !ks.cache.watcher.enabled() { + return true + } + // The watcher should start, and then exit. + for t0 := time.Now(); time.Since(t0) < 1*time.Second; time.Sleep(100 * time.Millisecond) { + if ks.cache.watcherStarted() { + return true + } + } + return false +} + +func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { + var list []accounts.Account + for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(200 * time.Millisecond) { + list = ks.Accounts() + if reflect.DeepEqual(list, wantAccounts) { + // ks should have also received change notifications + select { + case <-ks.changes: + default: + return fmt.Errorf("wasn't notified of new accounts") + } + return nil + } + } + return fmt.Errorf("\ngot %v\nwant %v", list, wantAccounts) +} + func TestWatchNewFile(t *testing.T) { t.Parallel() @@ -58,8 +89,9 @@ func TestWatchNewFile(t *testing.T) { // Ensure the watcher is started before adding any files. ks.Accounts() - time.Sleep(1000 * time.Millisecond) - + if !waitWatcherStart(ks) { + t.Fatal("keystore watcher didn't start in time") + } // Move in the files. wantAccounts := make([]accounts.Account, len(cachetestAccounts)) for i := range cachetestAccounts { @@ -73,37 +105,25 @@ func TestWatchNewFile(t *testing.T) { } // ks should see the accounts. - var list []accounts.Account - for d := 200 * time.Millisecond; d < 5*time.Second; d *= 2 { - list = ks.Accounts() - if reflect.DeepEqual(list, wantAccounts) { - // ks should have also received change notifications - select { - case <-ks.changes: - default: - t.Fatalf("wasn't notified of new accounts") - } - return - } - time.Sleep(d) + if err := waitForAccounts(wantAccounts, ks); err != nil { + t.Error(err) } - t.Errorf("got %s, want %s", spew.Sdump(list), spew.Sdump(wantAccounts)) } func TestWatchNoDir(t *testing.T) { t.Parallel() - // Create ks but not the directory that it watches. rand.Seed(time.Now().UnixNano()) dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) - list := ks.Accounts() if len(list) > 0 { t.Error("initial account list not empty:", list) } - time.Sleep(100 * time.Millisecond) - + // The watcher should start, and then exit. + if !waitWatcherStart(ks) { + t.Fatal("keystore watcher didn't start in time") + } // Create the directory and copy a key file into it. os.MkdirAll(dir, 0700) defer os.RemoveAll(dir) @@ -296,24 +316,6 @@ func TestCacheFind(t *testing.T) { } } -func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { - var list []accounts.Account - for d := 200 * time.Millisecond; d < 8*time.Second; d *= 2 { - list = ks.Accounts() - if reflect.DeepEqual(list, wantAccounts) { - // ks should have also received change notifications - select { - case <-ks.changes: - default: - return errors.New("wasn't notified of new accounts") - } - return nil - } - time.Sleep(d) - } - return fmt.Errorf("\ngot %v\nwant %v", list, wantAccounts) -} - // TestUpdatedKeyfileContents tests that updating the contents of a keystore file // is noticed by the watcher, and the account cache is updated accordingly func TestUpdatedKeyfileContents(t *testing.T) { @@ -328,8 +330,9 @@ func TestUpdatedKeyfileContents(t *testing.T) { if len(list) > 0 { t.Error("initial account list not empty:", list) } - time.Sleep(100 * time.Millisecond) - + if !waitWatcherStart(ks) { + t.Fatal("keystore watcher didn't start in time") + } // Create the directory and copy a key file into it. os.MkdirAll(dir, 0700) defer os.RemoveAll(dir) @@ -347,9 +350,8 @@ func TestUpdatedKeyfileContents(t *testing.T) { t.Error(err) return } - // needed so that modTime of `file` is different to its current value after forceCopyFile - time.Sleep(1000 * time.Millisecond) + time.Sleep(time.Second) // Now replace file contents if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil { @@ -365,7 +367,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { } // needed so that modTime of `file` is different to its current value after forceCopyFile - time.Sleep(1000 * time.Millisecond) + time.Sleep(time.Second) // Now replace file contents again if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil { @@ -381,7 +383,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { } // needed so that modTime of `file` is different to its current value after os.WriteFile - time.Sleep(1000 * time.Millisecond) + time.Sleep(time.Second) // Now replace file contents with crap if err := os.WriteFile(file, []byte("foo"), 0600); err != nil { diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 1f46bce34b..42dc45a656 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -509,6 +509,14 @@ func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (account return a, nil } +// isUpdating returns whether the event notification loop is running. +// This method is mainly meant for tests. +func (ks *KeyStore) isUpdating() bool { + ks.mu.RLock() + defer ks.mu.RUnlock() + return ks.updating +} + // zeroKey zeroes a private key in memory. func zeroKey(k *ecdsa.PrivateKey) { b := k.D.Bits() diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index d2042fe6a9..0f91904307 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -113,6 +113,7 @@ func TestSignWithPassphrase(t *testing.T) { } func TestTimedUnlock(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) pass := "foo" @@ -147,6 +148,7 @@ func TestTimedUnlock(t *testing.T) { } func TestOverrideUnlock(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, false) pass := "foo" @@ -187,6 +189,7 @@ func TestOverrideUnlock(t *testing.T) { // This test should fail under -race if signing races the expiration goroutine. func TestSignRace(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, false) // Create a test account. @@ -211,19 +214,33 @@ func TestSignRace(t *testing.T) { t.Errorf("Account did not lock within the timeout") } +// waitForKsUpdating waits until the updating-status of the ks reaches the +// desired wantStatus. +// It waits for a maximum time of maxTime, and returns false if it does not +// finish in time +func waitForKsUpdating(t *testing.T, ks *KeyStore, wantStatus bool, maxTime time.Duration) bool { + t.Helper() + // Wait max 250 ms, then return false + for t0 := time.Now(); time.Since(t0) < maxTime; { + if ks.isUpdating() == wantStatus { + return true + } + time.Sleep(25 * time.Millisecond) + } + return false +} + // Tests that the wallet notifier loop starts and stops correctly based on the // addition and removal of wallet event subscriptions. func TestWalletNotifierLifecycle(t *testing.T) { + t.Parallel() // Create a temporary keystore to test with _, ks := tmpKeyStore(t, false) // Ensure that the notification updater is not running yet time.Sleep(250 * time.Millisecond) - ks.mu.RLock() - updating := ks.updating - ks.mu.RUnlock() - if updating { + if ks.isUpdating() { t.Errorf("wallet notifier running without subscribers") } // Subscribe to the wallet feed and ensure the updater boots up @@ -233,38 +250,26 @@ func TestWalletNotifierLifecycle(t *testing.T) { for i := 0; i < len(subs); i++ { // Create a new subscription subs[i] = ks.Subscribe(updates) - - // Ensure the notifier comes online - time.Sleep(250 * time.Millisecond) - ks.mu.RLock() - updating = ks.updating - ks.mu.RUnlock() - - if !updating { + if !waitForKsUpdating(t, ks, true, 250*time.Millisecond) { t.Errorf("sub %d: wallet notifier not running after subscription", i) } } - // Unsubscribe and ensure the updater terminates eventually - for i := 0; i < len(subs); i++ { + // Close all but one sub + for i := 0; i < len(subs)-1; i++ { // Close an existing subscription subs[i].Unsubscribe() - - // Ensure the notifier shuts down at and only at the last close - for k := 0; k < int(walletRefreshCycle/(250*time.Millisecond))+2; k++ { - ks.mu.RLock() - updating = ks.updating - ks.mu.RUnlock() - - if i < len(subs)-1 && !updating { - t.Fatalf("sub %d: event notifier stopped prematurely", i) - } - if i == len(subs)-1 && !updating { - return - } - time.Sleep(250 * time.Millisecond) - } } - t.Errorf("wallet notifier didn't terminate after unsubscribe") + // Check that it is still running + time.Sleep(250 * time.Millisecond) + + if !ks.isUpdating() { + t.Fatal("event notifier stopped prematurely") + } + // Unsubscribe the last one and ensure the updater terminates eventually. + subs[len(subs)-1].Unsubscribe() + if !waitForKsUpdating(t, ks, false, 4*time.Second) { + t.Errorf("wallet notifier didn't terminate after unsubscribe") + } } type walletEvent struct { diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index b587cb95bd..efc1059bcd 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -28,8 +28,9 @@ import ( type watcher struct { ac *accountCache - starting bool - running bool + running bool // set to true when runloop begins + runEnded bool // set to true when runloop ends + starting bool // set to true prior to runloop starting ev chan notify.EventInfo quit chan struct{} } @@ -42,6 +43,9 @@ func newWatcher(ac *accountCache) *watcher { } } +// enabled returns false on systems not supported. +func (*watcher) enabled() bool { return true } + // starts the watcher loop in the background. // Start a watcher in the background if that's not already in progress. // The caller must hold w.ac.mu. @@ -62,6 +66,7 @@ func (w *watcher) loop() { w.ac.mu.Lock() w.running = false w.starting = false + w.runEnded = true w.ac.mu.Unlock() }() logger := log.New("path", w.ac.keydir) diff --git a/accounts/keystore/watch_fallback.go b/accounts/keystore/watch_fallback.go index e40eca42fe..e3c133b3f6 100644 --- a/accounts/keystore/watch_fallback.go +++ b/accounts/keystore/watch_fallback.go @@ -22,8 +22,14 @@ package keystore -type watcher struct{ running bool } +type watcher struct { + running bool + runEnded bool +} func newWatcher(*accountCache) *watcher { return new(watcher) } func (*watcher) start() {} func (*watcher) close() {} + +// enabled returns false on systems not supported. +func (*watcher) enabled() bool { return false } From 42929796858ae144a179d4a58893a19d2ace374b Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 206/280] accounts/scwallet: fix keycard data signing error (#25331) accounts/scwallet: fix keycard data signing --- accounts/scwallet/wallet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 530bdd4d7b..556cbf325f 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -99,8 +99,8 @@ const ( P1DeriveKeyFromCurrent = uint8(0x10) statusP1WalletStatus = uint8(0x00) statusP1Path = uint8(0x01) - signP1PrecomputedHash = uint8(0x01) - signP2OnlyBlock = uint8(0x81) + signP1PrecomputedHash = uint8(0x00) + signP2OnlyBlock = uint8(0x00) exportP1Any = uint8(0x00) exportP2Pubkey = uint8(0x01) ) From 19085392a26cbb7409d353d8d67e09a0b31242fa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 207/280] accounts/abi: return error on fixed bytes with size larger than 32 bytes (#26075) * fixed bytes with size larger than 32 bytes is not allowed * add testcase --- accounts/abi/type.go | 3 +++ accounts/abi/type_test.go | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index f0c682cebd..d50903e4c1 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -153,6 +153,9 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty if varSize == 0 { typ.T = BytesTy } else { + if varSize > 32 { + return Type{}, fmt.Errorf("unsupported arg type: %s", t) + } typ.T = FixedBytesTy typ.Size = varSize } diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index e6b08b4878..cd2577b793 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -366,3 +366,10 @@ func TestGetTypeSize(t *testing.T) { } } } + +func TestNewFixedBytesOver32(t *testing.T) { + _, err := NewType("bytes4096", "", nil) + if err == nil { + t.Errorf("fixed bytes with size over 32 is not spec'd") + } +} From cd9c09f384f79d1336da1af14eb8c0b8820ee815 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 208/280] accounts/abi.bind: don't fetch head in transact unless required (#25988) If GasFeeCap and GasTipCap are specified, we don't need to retrieve the head block for constructing a transaction --- accounts/abi/bind/base.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index bdc479537d..36472f81fe 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -377,6 +377,8 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i ) if opts.GasPrice != nil { rawTx, err = c.createLegacyTx(opts, contract, input) + } else if opts.GasFeeCap != nil && opts.GasTipCap != nil { + rawTx, err = c.createDynamicTx(opts, contract, input, nil) } else { // Only query for basefee if gasPrice not specified if head, errHead := c.transactor.HeaderByNumber(ensureContext(opts.Context), nil); errHead != nil { From e88251d63a2a3c8f8521fb164852b8638c115b35 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 209/280] accounts/abi: properly quote untrusted data in error message (#26110) * abi: Format data as hex-string instead of string(data) * Update accounts/abi/abi.go Co-authored-by: Martin Holst Swende --- accounts/abi/abi.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index f68d94c961..8d1045c355 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -87,7 +87,7 @@ func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { var args Arguments if method, ok := abi.Methods[name]; ok { if len(data)%32 != 0 { - return nil, fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data) + return nil, fmt.Errorf("abi: improperly formatted output: %q - Bytes: %+v", data, data) } args = method.Outputs } From 4081ed926a4575964bf3dd291d4dbf9fc5248b0a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH 210/280] accounts/keystore: replace inotify with fsnotify (#26176) --- accounts/keystore/watch.go | 33 +++++++++++++++++++++++++-------- go.mod | 2 +- go.sum | 6 ++---- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index efc1059bcd..00deab03e4 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -23,7 +23,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/rjeczalik/notify" + "github.com/fsnotify/fsnotify" ) type watcher struct { @@ -31,14 +31,12 @@ type watcher struct { running bool // set to true when runloop begins runEnded bool // set to true when runloop ends starting bool // set to true prior to runloop starting - ev chan notify.EventInfo quit chan struct{} } func newWatcher(ac *accountCache) *watcher { return &watcher{ ac: ac, - ev: make(chan notify.EventInfo, 10), quit: make(chan struct{}), } } @@ -71,12 +69,19 @@ func (w *watcher) loop() { }() logger := log.New("path", w.ac.keydir) - if err := notify.Watch(w.ac.keydir, w.ev, notify.All); err != nil { - logger.Trace("Failed to watch keystore folder", "err", err) + // Create new watcher. + watcher, err := fsnotify.NewWatcher() + if err != nil { + log.Error("Failed to start filesystem watcher", "err", err) return } - defer notify.Stop(w.ev) - logger.Trace("Started watching keystore folder") + defer watcher.Close() + if err := watcher.Add(w.ac.keydir); err != nil { + logger.Warn("Failed to watch keystore folder", "err", err) + return + } + + logger.Trace("Started watching keystore folder", "folder", w.ac.keydir) defer logger.Trace("Stopped watching keystore folder") w.ac.mu.Lock() @@ -100,12 +105,24 @@ func (w *watcher) loop() { select { case <-w.quit: return - case <-w.ev: + case _, ok := <-watcher.Events: + if !ok { + return + } // Trigger the scan (with delay), if not already triggered if !rescanTriggered { debounce.Reset(debounceDuration) rescanTriggered = true } + // The fsnotify library does provide more granular event-info, it + // would be possible to refresh individual affected files instead + // of scheduling a full rescan. For most cases though, the + // full rescan is quick and obviously simplest. + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Info("Filsystem watcher error", "err", err) case <-debounce.C: w.ac.scanAccounts() rescanTriggered = false diff --git a/go.mod b/go.mod index 2302b43cba..c53a1f35ec 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,6 @@ require ( github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 github.com/pkg/errors v0.9.1 github.com/prometheus/prometheus v1.7.2-0.20170814170113-3101606756c5 - github.com/rjeczalik/notify v0.9.2 github.com/rs/cors v1.7.0 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 github.com/stretchr/testify v1.8.4 @@ -48,6 +47,7 @@ require ( github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e + github.com/fsnotify/fsnotify v1.8.0 github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 github.com/go-yaml/yaml v2.1.0+incompatible github.com/google/gofuzz v1.2.0 diff --git a/go.sum b/go.sum index 3f9f3042bc..13b3389aa1 100644 --- a/go.sum +++ b/go.sum @@ -50,10 +50,11 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY= github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= @@ -184,8 +185,6 @@ github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+ github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= -github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= @@ -244,7 +243,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From cab293859a2fbdcd716987506e530866771efe67 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 211/280] eth/filters: update Backend interface (#26126) --- accounts/abi/bind/backends/simulated.go | 8 ++++++++ eth/filters/filter_system.go | 3 +++ eth/filters/filter_system_test.go | 8 ++++++++ internal/ethapi/backend.go | 17 ++++++++++------- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 0e77a27b24..877851bcc8 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -977,6 +977,14 @@ func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.Matche panic("not supported") } +func (fb *filterBackend) ChainConfig() *params.ChainConfig { + panic("not supported") +} + +func (fb *filterBackend) CurrentHeader() *types.Header { + panic("not supported") +} + func nullSubscription() event.Subscription { return event.NewSubscription(func(quit <-chan struct{}) error { <-quit diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 0525268967..e1167d409d 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -36,6 +36,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/log" + "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/rpc" ) @@ -64,6 +65,8 @@ type Backend interface { GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) PendingBlockAndReceipts() (*types.Block, types.Receipts) + CurrentHeader() *types.Header + ChainConfig() *params.ChainConfig SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 0aa3e12949..a775c62201 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -52,6 +52,14 @@ type testBackend struct { chainFeed event.Feed } +func (b *testBackend) ChainConfig() *params.ChainConfig { + panic("implement me") +} + +func (b *testBackend) CurrentHeader() *types.Header { + panic("implement me") +} + func (b *testBackend) ChainDb() ethdb.Database { return b.db } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index b9be939a6a..560119df78 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -21,21 +21,19 @@ import ( "context" "math/big" + "github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCxlending" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - - "github.com/XinFinOrg/XDPoSChain/XDCx" - "github.com/XinFinOrg/XDPoSChain/accounts" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/bloombits" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/eth/downloader" - "github.com/XinFinOrg/XDPoSChain/eth/filters" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/params" @@ -92,7 +90,6 @@ type Backend interface { OrderTxPoolContent() (map[common.Address]types.OrderTransactions, map[common.Address]types.OrderTransactions) OrderStats() (pending int, queued int) SendLendingTx(ctx context.Context, signedTx *types.LendingTransaction) error - SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription ChainConfig() *params.ChainConfig CurrentBlock() *types.Block @@ -108,10 +105,16 @@ type Backend interface { AreTwoBlockSamePath(newBlock common.Hash, oldBlock common.Hash) bool GetOrderNonce(address common.Hash) (uint64, error) + // This is copied from filters.Backend // eth/filters needs to be initialized from this backend type, so methods needed by // it must also be included here. GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) - filters.Backend + GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) + SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription + SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription + SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription + BloomStatus() (uint64, uint64) + ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) } func GetAPIs(apiBackend Backend, chainReader consensus.ChainReader) []rpc.API { From 4e951ed8fe2dd0b45288f32fb6edf5a1a18ca020 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 212/280] all: use github.com/deckarep/golang-set/v2 (generic set) (#26159) --- accounts/keystore/account_cache.go | 15 +++++++-------- accounts/keystore/file_cache.go | 12 ++++++------ consensus/ethash/consensus.go | 4 ++-- eth/peer.go | 30 +++++++++++++++--------------- go.mod | 2 +- go.sum | 4 ++-- miner/worker.go | 16 ++++++++-------- rpc/server.go | 14 +++++++------- rpc/websocket.go | 8 ++++---- 9 files changed, 52 insertions(+), 53 deletions(-) diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index ad497d7e0f..aec9825bab 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -30,7 +30,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/log" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) // Minimum amount of time between cache reloads. This limit applies if the platform does @@ -79,7 +79,7 @@ func newAccountCache(keydir string) (*accountCache, chan struct{}) { keydir: keydir, byAddr: make(map[common.Address][]accounts.Account), notify: make(chan struct{}, 1), - fileC: fileCache{all: mapset.NewThreadUnsafeSet()}, + fileC: fileCache{all: mapset.NewThreadUnsafeSet[string]()}, } ac.watcher = newWatcher(ac) return ac, ac.notify @@ -283,16 +283,15 @@ func (ac *accountCache) scanAccounts() error { // Process all the file diffs start := time.Now() - for _, p := range creates.ToSlice() { - if a := readAccount(p.(string)); a != nil { + for _, path := range creates.ToSlice() { + if a := readAccount(path); a != nil { ac.add(*a) } } - for _, p := range deletes.ToSlice() { - ac.deleteByFile(p.(string)) + for _, path := range deletes.ToSlice() { + ac.deleteByFile(path) } - for _, p := range updates.ToSlice() { - path := p.(string) + for _, path := range updates.ToSlice() { ac.deleteByFile(path) if a := readAccount(path); a != nil { ac.add(*a) diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index f2bd7efbe6..59c047d1fa 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -24,19 +24,19 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/log" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) // fileCache is a cache of files seen during scan of keystore. type fileCache struct { - all mapset.Set // Set of all files from the keystore folder - lastMod time.Time // Last time instance when a file was modified + all mapset.Set[string] // Set of all files from the keystore folder + lastMod time.Time // Last time instance when a file was modified mu sync.Mutex } // scan performs a new scan on the given directory, compares against the already // cached filenames, and returns file sets: creates, deletes, updates. -func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, error) { +func (fc *fileCache) scan(keyDir string) (mapset.Set[string], mapset.Set[string], mapset.Set[string], error) { t0 := time.Now() // List all the files from the keystore folder @@ -50,8 +50,8 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er defer fc.mu.Unlock() // Iterate all the files and gather their metadata - all := mapset.NewThreadUnsafeSet() - mods := mapset.NewThreadUnsafeSet() + all := mapset.NewThreadUnsafeSet[string]() + mods := mapset.NewThreadUnsafeSet[string]() var newLastMod time.Time for _, fi := range files { diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index e6ecc9f7ab..6cf41dddeb 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -32,7 +32,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) // Ethash proof-of-work protocol constants. @@ -178,7 +178,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo return errTooManyUncles } // Gather the set of past uncles and ancestors - uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header) + uncles, ancestors := mapset.NewSet[common.Hash](), make(map[common.Hash]*types.Header) number, parent := block.NumberU64()-1, block.ParentHash() for i := 0; i < 7; i++ { diff --git a/eth/peer.go b/eth/peer.go index eb7730b99a..458ae56fe4 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -27,7 +27,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/p2p" "github.com/XinFinOrg/XDPoSChain/rlp" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) var ( @@ -69,15 +69,15 @@ type peer struct { td *big.Int lock sync.RWMutex - knownTxs mapset.Set // Set of transaction hashes known to be known by this peer - knownBlocks mapset.Set // Set of block hashes known to be known by this peer + knownTxs mapset.Set[common.Hash] // Set of transaction hashes known to be known by this peer + knownBlocks mapset.Set[common.Hash] // Set of block hashes known to be known by this peer - knownOrderTxs mapset.Set // Set of order transaction hashes known to be known by this peer - knownLendingTxs mapset.Set // Set of lending transaction hashes known to be known by this peer + knownOrderTxs mapset.Set[common.Hash] // Set of order transaction hashes known to be known by this peer + knownLendingTxs mapset.Set[common.Hash] // Set of lending transaction hashes known to be known by this peer - knownVote mapset.Set // Set of BFT Vote known to be known by this peer - knownTimeout mapset.Set // Set of BFT timeout known to be known by this peer - knownSyncInfo mapset.Set // Set of BFT Sync Info known to be known by this peer + knownVote mapset.Set[common.Hash] // Set of BFT Vote known to be known by this peer + knownTimeout mapset.Set[common.Hash] // Set of BFT timeout known to be known by this peer + knownSyncInfo mapset.Set[common.Hash] // Set of BFT Sync Info known to be known by this peer } func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { @@ -88,14 +88,14 @@ func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { rw: rw, version: version, id: fmt.Sprintf("%x", id[:8]), - knownTxs: mapset.NewSet(), - knownBlocks: mapset.NewSet(), - knownOrderTxs: mapset.NewSet(), - knownLendingTxs: mapset.NewSet(), + knownTxs: mapset.NewSet[common.Hash](), + knownBlocks: mapset.NewSet[common.Hash](), + knownOrderTxs: mapset.NewSet[common.Hash](), + knownLendingTxs: mapset.NewSet[common.Hash](), - knownVote: mapset.NewSet(), - knownTimeout: mapset.NewSet(), - knownSyncInfo: mapset.NewSet(), + knownVote: mapset.NewSet[common.Hash](), + knownTimeout: mapset.NewSet[common.Hash](), + knownSyncInfo: mapset.NewSet[common.Hash](), } } diff --git a/go.mod b/go.mod index c53a1f35ec..b84e0ed811 100644 --- a/go.mod +++ b/go.mod @@ -42,7 +42,7 @@ require ( require ( github.com/consensys/gnark-crypto v0.10.0 github.com/crate-crypto/go-kzg-4844 v0.7.0 - github.com/deckarep/golang-set v1.8.0 + github.com/deckarep/golang-set/v2 v2.7.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/ethereum/c-kzg-4844 v0.4.0 diff --git a/go.sum b/go.sum index 13b3389aa1..16558b1e15 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/deckarep/golang-set/v2 v2.7.0 h1:gIloKvD7yH2oip4VLhsv3JyLLFnC0Y2mlusgcvJYW5k= +github.com/deckarep/golang-set/v2 v2.7.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= diff --git a/miner/worker.go b/miner/worker.go index 6514b48811..86822dda23 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -43,7 +43,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) const ( @@ -80,16 +80,16 @@ type Work struct { parentState *state.StateDB tradingState *tradingstate.TradingStateDB lendingState *lendingstate.LendingStateDB - ancestors mapset.Set // ancestor set (used for checking uncle parent validity) - family mapset.Set // family set (used for checking uncle invalidity) - uncles mapset.Set // uncle set - tcount int // tx count in cycle + ancestors mapset.Set[common.Hash] // ancestor set (used for checking uncle parent validity) + family mapset.Set[common.Hash] // family set (used for checking uncle invalidity) + tcount int // tx count in cycle Block *types.Block // the new block header *types.Header txs []*types.Transaction receipts []*types.Receipt + uncles map[common.Hash]*types.Header createdAt time.Time } @@ -575,10 +575,10 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { parentState: state.Copy(), tradingState: XDCxState, lendingState: lendingState, - ancestors: mapset.NewSet(), - family: mapset.NewSet(), - uncles: mapset.NewSet(), + ancestors: mapset.NewSet[common.Hash](), + family: mapset.NewSet[common.Hash](), header: header, + uncles: make(map[common.Hash]*types.Header), createdAt: time.Now(), } diff --git a/rpc/server.go b/rpc/server.go index a1686bd008..5c1670e16f 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -22,7 +22,7 @@ import ( "sync/atomic" "github.com/XinFinOrg/XDPoSChain/log" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" ) const MetadataApi = "rpc" @@ -45,12 +45,12 @@ type Server struct { services serviceRegistry idgen func() ID run int32 - codecs mapset.Set + codecs mapset.Set[*ServerCodec] } // NewServer creates a new server instance with no registered handlers. func NewServer() *Server { - server := &Server{idgen: randomIDGenerator(), codecs: mapset.NewSet(), run: 1} + server := &Server{idgen: randomIDGenerator(), codecs: mapset.NewSet[*ServerCodec](), run: 1} // Register the default service providing meta information about the RPC service such // as the services and methods it offers. rpcService := &RPCService{server} @@ -80,8 +80,8 @@ func (s *Server) ServeCodec(codec ServerCodec, options CodecOption) { } // Add the codec to the set so it can be closed by Stop. - s.codecs.Add(codec) - defer s.codecs.Remove(codec) + s.codecs.Add(&codec) + defer s.codecs.Remove(&codec) c := initClient(codec, s.idgen, &s.services) <-codec.closed() @@ -121,8 +121,8 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { func (s *Server) Stop() { if atomic.CompareAndSwapInt32(&s.run, 1, 0) { log.Debug("RPC server shutting down") - s.codecs.Each(func(c interface{}) bool { - c.(ServerCodec).close() + s.codecs.Each(func(c *ServerCodec) bool { + (*c).close() return true }) } diff --git a/rpc/websocket.go b/rpc/websocket.go index 7c7cae4554..c916b79568 100644 --- a/rpc/websocket.go +++ b/rpc/websocket.go @@ -28,7 +28,7 @@ import ( "time" "github.com/XinFinOrg/XDPoSChain/log" - mapset "github.com/deckarep/golang-set" + mapset "github.com/deckarep/golang-set/v2" "github.com/gorilla/websocket" ) @@ -68,7 +68,7 @@ func (s *Server) WebsocketHandler(allowedOrigins []string) http.Handler { // websocket upgrade process. When a '*' is specified as an allowed origins all // connections are accepted. func wsHandshakeValidator(allowedOrigins []string) func(*http.Request) bool { - origins := mapset.NewSet() + origins := mapset.NewSet[string]() allowAllOrigins := false for _, origin := range allowedOrigins { @@ -121,10 +121,10 @@ func (e wsHandshakeError) Error() string { return s } -func originIsAllowed(allowedOrigins mapset.Set, browserOrigin string) bool { +func originIsAllowed(allowedOrigins mapset.Set[string], browserOrigin string) bool { it := allowedOrigins.Iterator() for origin := range it.C { - if ruleAllowsOrigin(origin.(string), browserOrigin) { + if ruleAllowsOrigin(origin, browserOrigin) { return true } } From b18e0e45b7aad226bd681b82afaf33c0bd4cf9bb Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 213/280] accounts/abi: fix integer encoding/decoding (#26568) This PR fixes this abi encoder/decoder to be more stringent. --- accounts/abi/error_handling.go | 10 +- accounts/abi/unpack.go | 72 ++++++++++----- accounts/abi/unpack_test.go | 162 +++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 22 deletions(-) diff --git a/accounts/abi/error_handling.go b/accounts/abi/error_handling.go index 7add707292..c106e9ac43 100644 --- a/accounts/abi/error_handling.go +++ b/accounts/abi/error_handling.go @@ -23,7 +23,15 @@ import ( ) var ( - errBadBool = errors.New("abi: improperly encoded boolean value") + errBadBool = errors.New("abi: improperly encoded boolean value") + errBadUint8 = errors.New("abi: improperly encoded uint8 value") + errBadUint16 = errors.New("abi: improperly encoded uint16 value") + errBadUint32 = errors.New("abi: improperly encoded uint32 value") + errBadUint64 = errors.New("abi: improperly encoded uint64 value") + errBadInt8 = errors.New("abi: improperly encoded int8 value") + errBadInt16 = errors.New("abi: improperly encoded int16 value") + errBadInt32 = errors.New("abi: improperly encoded int32 value") + errBadInt64 = errors.New("abi: improperly encoded int64 value") ) // formatSliceString formats the reflection kind with the given slice size diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index fb5169fa80..e6478a4e20 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -20,6 +20,7 @@ import ( "encoding/binary" "errors" "fmt" + "math" "math/big" "reflect" @@ -34,43 +35,72 @@ var ( ) // ReadInteger reads the integer based on its kind and returns the appropriate value. -func ReadInteger(typ Type, b []byte) interface{} { +func ReadInteger(typ Type, b []byte) (interface{}, error) { + ret := new(big.Int).SetBytes(b) + if typ.T == UintTy { + u64, isu64 := ret.Uint64(), ret.IsUint64() switch typ.Size { case 8: - return b[len(b)-1] + if !isu64 || u64 > math.MaxUint8 { + return nil, errBadUint8 + } + return byte(u64), nil case 16: - return binary.BigEndian.Uint16(b[len(b)-2:]) + if !isu64 || u64 > math.MaxUint16 { + return nil, errBadUint16 + } + return uint16(u64), nil case 32: - return binary.BigEndian.Uint32(b[len(b)-4:]) + if !isu64 || u64 > math.MaxUint32 { + return nil, errBadUint32 + } + return uint32(u64), nil case 64: - return binary.BigEndian.Uint64(b[len(b)-8:]) + if !isu64 { + return nil, errBadUint64 + } + return u64, nil default: // the only case left for unsigned integer is uint256. - return new(big.Int).SetBytes(b) + return ret, nil } } + + // big.SetBytes can't tell if a number is negative or positive in itself. + // On EVM, if the returned number > max int256, it is negative. + // A number is > max int256 if the bit at position 255 is set. + if ret.Bit(255) == 1 { + ret.Add(MaxUint256, new(big.Int).Neg(ret)) + ret.Add(ret, common.Big1) + ret.Neg(ret) + } + i64, isi64 := ret.Int64(), ret.IsInt64() switch typ.Size { case 8: - return int8(b[len(b)-1]) + if !isi64 || i64 < math.MinInt8 || i64 > math.MaxInt8 { + return nil, errBadInt8 + } + return int8(i64), nil case 16: - return int16(binary.BigEndian.Uint16(b[len(b)-2:])) + if !isi64 || i64 < math.MinInt16 || i64 > math.MaxInt16 { + return nil, errBadInt16 + } + return int16(i64), nil case 32: - return int32(binary.BigEndian.Uint32(b[len(b)-4:])) + if !isi64 || i64 < math.MinInt32 || i64 > math.MaxInt32 { + return nil, errBadInt32 + } + return int32(i64), nil case 64: - return int64(binary.BigEndian.Uint64(b[len(b)-8:])) + if !isi64 { + return nil, errBadInt64 + } + return i64, nil default: // the only case left for integer is int256 - // big.SetBytes can't tell if a number is negative or positive in itself. - // On EVM, if the returned number > max int256, it is negative. - // A number is > max int256 if the bit at position 255 is set. - ret := new(big.Int).SetBytes(b) - if ret.Bit(255) == 1 { - ret.Add(MaxUint256, new(big.Int).Neg(ret)) - ret.Add(ret, common.Big1) - ret.Neg(ret) - } - return ret + + return ret, nil } } @@ -235,7 +265,7 @@ func toGoType(index int, t Type, output []byte) (interface{}, error) { case StringTy: // variable arrays are written at the end of the return bytes return string(output[begin : begin+length]), nil case IntTy, UintTy: - return ReadInteger(t, returnOutput), nil + return ReadInteger(t, returnOutput) case BoolTy: return readBool(returnOutput) case AddressTy: diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 8947211634..fb0e4d2e0b 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/hex" "fmt" + "math" "math/big" "reflect" "strconv" @@ -943,3 +944,164 @@ func TestOOMMaliciousInput(t *testing.T) { } } } + +func TestPackAndUnpackIncompatibleNumber(t *testing.T) { + var encodeABI Arguments + uint256Ty, err := NewType("uint256", "", nil) + if err != nil { + panic(err) + } + encodeABI = Arguments{ + {Type: uint256Ty}, + } + + maxU64, ok := new(big.Int).SetString(strconv.FormatUint(math.MaxUint64, 10), 10) + if !ok { + panic("bug") + } + maxU64Plus1 := new(big.Int).Add(maxU64, big.NewInt(1)) + cases := []struct { + decodeType string + inputValue *big.Int + err error + expectValue interface{} + }{ + { + decodeType: "uint8", + inputValue: big.NewInt(math.MaxUint8 + 1), + err: errBadUint8, + }, + { + decodeType: "uint8", + inputValue: big.NewInt(math.MaxUint8), + err: nil, + expectValue: uint8(math.MaxUint8), + }, + { + decodeType: "uint16", + inputValue: big.NewInt(math.MaxUint16 + 1), + err: errBadUint16, + }, + { + decodeType: "uint16", + inputValue: big.NewInt(math.MaxUint16), + err: nil, + expectValue: uint16(math.MaxUint16), + }, + { + decodeType: "uint32", + inputValue: big.NewInt(math.MaxUint32 + 1), + err: errBadUint32, + }, + { + decodeType: "uint32", + inputValue: big.NewInt(math.MaxUint32), + err: nil, + expectValue: uint32(math.MaxUint32), + }, + { + decodeType: "uint64", + inputValue: maxU64Plus1, + err: errBadUint64, + }, + { + decodeType: "uint64", + inputValue: maxU64, + err: nil, + expectValue: uint64(math.MaxUint64), + }, + { + decodeType: "uint256", + inputValue: maxU64Plus1, + err: nil, + expectValue: maxU64Plus1, + }, + { + decodeType: "int8", + inputValue: big.NewInt(math.MaxInt8 + 1), + err: errBadInt8, + }, + { + decodeType: "int8", + inputValue: big.NewInt(math.MinInt8 - 1), + err: errBadInt8, + }, + { + decodeType: "int8", + inputValue: big.NewInt(math.MaxInt8), + err: nil, + expectValue: int8(math.MaxInt8), + }, + { + decodeType: "int16", + inputValue: big.NewInt(math.MaxInt16 + 1), + err: errBadInt16, + }, + { + decodeType: "int16", + inputValue: big.NewInt(math.MinInt16 - 1), + err: errBadInt16, + }, + { + decodeType: "int16", + inputValue: big.NewInt(math.MaxInt16), + err: nil, + expectValue: int16(math.MaxInt16), + }, + { + decodeType: "int32", + inputValue: big.NewInt(math.MaxInt32 + 1), + err: errBadInt32, + }, + { + decodeType: "int32", + inputValue: big.NewInt(math.MinInt32 - 1), + err: errBadInt32, + }, + { + decodeType: "int32", + inputValue: big.NewInt(math.MaxInt32), + err: nil, + expectValue: int32(math.MaxInt32), + }, + { + decodeType: "int64", + inputValue: new(big.Int).Add(big.NewInt(math.MaxInt64), big.NewInt(1)), + err: errBadInt64, + }, + { + decodeType: "int64", + inputValue: new(big.Int).Sub(big.NewInt(math.MinInt64), big.NewInt(1)), + err: errBadInt64, + }, + { + decodeType: "int64", + inputValue: big.NewInt(math.MaxInt64), + err: nil, + expectValue: int64(math.MaxInt64), + }, + } + for i, testCase := range cases { + packed, err := encodeABI.Pack(testCase.inputValue) + if err != nil { + panic(err) + } + ty, err := NewType(testCase.decodeType, "", nil) + if err != nil { + panic(err) + } + decodeABI := Arguments{ + {Type: ty}, + } + decoded, err := decodeABI.Unpack(packed) + if err != testCase.err { + t.Fatalf("Expected error %v, actual error %v. case %d", testCase.err, err, i) + } + if err != nil { + continue + } + if !reflect.DeepEqual(decoded[0], testCase.expectValue) { + t.Fatalf("Expected value %v, actual value %v", testCase.expectValue, decoded[0]) + } + } +} From 3d90cf7de2c6b22151b7c91a0375908c3fec5396 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 214/280] accounts/keystore: remove deprecated uses of math.rand (#26710) --- accounts/keystore/account_cache_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 6c1bbd82b3..fdb230f2d8 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -113,7 +113,6 @@ func TestWatchNewFile(t *testing.T) { func TestWatchNoDir(t *testing.T) { t.Parallel() // Create ks but not the directory that it watches. - rand.Seed(time.Now().UnixNano()) dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() @@ -322,7 +321,6 @@ func TestUpdatedKeyfileContents(t *testing.T) { t.Parallel() // Create a temporary keystore to test with - rand.Seed(time.Now().UnixNano()) dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) From ba053a546848542c62fa6d2c6fe84aa0d33389b4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 215/280] accounts/usbwallet: mitigate ledger app chunking issue (#26773) This PR mitigates an issue with Ledger's on-device RLP deserialization, see https://github.com/LedgerHQ/app-ethereum/issues/409 Ledger's RLP deserialization code does not validate the length of the RLP list received, and it may prematurely enter the signing flow when a APDU chunk boundary falls immediately before the EIP-155 chain_id when deserializing a transaction. Since the chain_id is uninitialized, it is 0 during this signing flow. This may cause the user to accidentally sign the transaction with chain_id = 0. That signature would be returned from the device 1 packet earlier than expected by the communication loop. The device blocks the second-to-last packet waiting for the signer flow, and then errors on the successive packet (which contains the chain_id, zeroed r, and zeroed s) Since the signature's early arrival causes successive errors during the communication process, geth does not parse the improper signature produced by the device, and therefore no improperly-signed transaction can be created. User funds are not at risk. We mitigate by selecting the highest chunk size that leaves at least 4 bytes in the final chunk. --- accounts/usbwallet/ledger.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index acf889262a..31c8b2387c 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -59,6 +59,8 @@ const ( ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address + + ledgerEip155Size int = 3 // Size of the EIP-155 chain_id,r,s in unsigned transactions ) // errLedgerReplyInvalidHeader is the error message returned by a Ledger data exchange @@ -347,9 +349,15 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction op = ledgerP1InitTransactionData reply []byte ) + + // Chunk size selection to mitigate an underlying RLP deserialization issue on the ledger app. + // https://github.com/LedgerHQ/app-ethereum/issues/409 + chunk := 255 + for ; len(payload)%chunk <= ledgerEip155Size; chunk-- { + } + for len(payload) > 0 { // Calculate the size of the next data chunk - chunk := 255 if chunk > len(payload) { chunk = len(payload) } From 1a07b9bb4994767722aef2c77d0a3a210be877f1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 216/280] accounts/abi: add error-checks (#26914) --- accounts/abi/abi.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 8d1045c355..418becc7de 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -246,7 +246,10 @@ func UnpackRevert(data []byte) (string, error) { if !bytes.Equal(data[:4], revertSelector) { return "", errors.New("invalid data for unpacking") } - typ, _ := NewType("string", "", nil) + typ, err := NewType("string", "", nil) + if err != nil { + return "", err + } unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:]) if err != nil { return "", err From 5de961552ef9e87fecaf2ebf229dd0a33d6aeffe Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 217/280] accounts/abi/bind: handle UnpackLog with zero topics (#26920) Adds error handling for the case that UnpackLog or UnpackLogIntoMap is called with a log that has zero topics. --------- Co-authored-by: Sina Mahmoodi --- accounts/abi/bind/base.go | 17 +++++++++++------ accounts/abi/bind/base_test.go | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 36472f81fe..abd2e7ad45 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -32,12 +32,13 @@ import ( "github.com/XinFinOrg/XDPoSChain/event" ) -var ( - errNoEventSignature = errors.New("no event signature") -) - const basefeeWiggleMultiplier = 2 +var ( + errNoEventSignature = errors.New("no event signature") + errEventSignatureMismatch = errors.New("event signature mismatch") +) + // SignerFn is a signer function callback when a contract requires a method to // sign the transaction before submission. type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error) @@ -494,7 +495,7 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) return errNoEventSignature } if log.Topics[0] != c.abi.Events[event].ID { - return errors.New("event signature mismatch") + return errEventSignatureMismatch } if len(log.Data) > 0 { if err := c.abi.UnpackIntoInterface(out, event, log.Data); err != nil { @@ -512,8 +513,12 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) // UnpackLogIntoMap unpacks a retrieved log into the provided map. func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error { + // Anonymous events are not supported. + if len(log.Topics) == 0 { + return errNoEventSignature + } if log.Topics[0] != c.abi.Events[event].ID { - return fmt.Errorf("event signature mismatch") + return errEventSignatureMismatch } if len(log.Data) > 0 { if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil { diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 97972b352e..d46ab88b83 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -219,6 +219,23 @@ func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { unpackAndCheck(t, bc, expectedReceivedMap, mockLog) } +func TestUnpackAnonymousLogIntoMap(t *testing.T) { + mockLog := newMockLog(nil, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + var received map[string]interface{} + err := bc.UnpackLogIntoMap(received, "received", mockLog) + if err == nil { + t.Error("unpacking anonymous event is not supported") + } + if err.Error() != "no event signature" { + t.Errorf("expected error 'no event signature', got '%s'", err) + } +} + func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) if err != nil { From d9ec687a2cb7d9a0914f0c4f09bcb8eedfff7685 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 218/280] accounts/abi: resolve name conflict for methods starting with a number (#26999) This adds logic to prepend 'M' or 'E' to Solidity identifiers when they would otherwise violate Go identifier naming rules. Closes #26972 --------- Co-authored-by: Martin Holst Swende Co-authored-by: Sina Mahmoodi --- accounts/abi/bind/bind.go | 17 ++++++++++++++++- accounts/abi/bind/bind_test.go | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index dc9a25e69b..5103ab69ff 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -133,12 +133,19 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Normalize the method for capital cases and non-anonymous inputs/outputs normalized := original normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) - // Ensure there is no duplicated identifier var identifiers = callIdentifiers if !original.IsConstant() { identifiers = transactIdentifiers } + // Name shouldn't start with a digit. It will make the generated code invalid. + if len(normalizedName) > 0 && unicode.IsDigit(rune(normalizedName[0])) { + normalizedName = fmt.Sprintf("M%s", normalizedName) + normalizedName = abi.ResolveNameConflict(normalizedName, func(name string) bool { + _, ok := identifiers[name] + return ok + }) + } if identifiers[normalizedName] { return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName) } @@ -182,6 +189,14 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] // Ensure there is no duplicated identifier normalizedName := methodNormalizer[lang](alias(aliases, original.Name)) + // Name shouldn't start with a digit. It will make the generated code invalid. + if len(normalizedName) > 0 && unicode.IsDigit(rune(normalizedName[0])) { + normalizedName = fmt.Sprintf("E%s", normalizedName) + normalizedName = abi.ResolveNameConflict(normalizedName, func(name string) bool { + _, ok := eventIdentifiers[name] + return ok + }) + } if eventIdentifiers[normalizedName] { return "", fmt.Errorf("duplicated identifier \"%s\"(normalized \"%s\"), use --alias for renaming", original.Name, normalizedName) } diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 8b707b92b6..0e4d4b738e 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1991,6 +1991,29 @@ var bindTests = []struct { t.Errorf("error deploying the contract: %v", err) } `, + }, { + name: "NumericMethodName", + contract: ` + // SPDX-License-Identifier: GPL-3.0 + pragma solidity >=0.4.22 <0.9.0; + + contract NumericMethodName { + event _1TestEvent(address _param); + function _1test() public pure {} + function __1test() public pure {} + function __2test() public pure {} + } + `, + bytecode: []string{"0x6080604052348015600f57600080fd5b5060958061001e6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80639d993132146041578063d02767c7146049578063ffa02795146051575b600080fd5b60476059565b005b604f605b565b005b6057605d565b005b565b565b56fea26469706673582212200382ca602dff96a7e2ba54657985e2b4ac423a56abe4a1f0667bc635c4d4371f64736f6c63430008110033"}, + abi: []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_param","type":"address"}],"name":"_1TestEvent","type":"event"},{"inputs":[],"name":"_1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__2test","outputs":[],"stateMutability":"pure","type":"function"}]`}, + imports: ` + "github.com/XinFinOrg/XDPoSChain/common" + `, + tester: ` + if b, err := NewNumericMethodName(common.Address{}, nil); b == nil || err != nil { + t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil) + } +`, }, } From 013c90a4e812a47d5c6839e58f74a0442680c6f1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 219/280] accounts/abi: add ErrorById (#27277) Adds `ErrorById` lookup --- accounts/abi/abi.go | 11 +++++++++++ accounts/abi/abi_test.go | 28 ++++++++++++++++++++++++++++ accounts/abi/error.go | 2 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 418becc7de..e84181a51c 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -222,6 +222,17 @@ func (abi *ABI) EventByID(topic common.Hash) (*Event, error) { return nil, fmt.Errorf("no event with id: %#x", topic.Hex()) } +// ErrorByID looks up an error by the 4-byte id, +// returns nil if none found. +func (abi *ABI) ErrorByID(sigdata [4]byte) (*Error, error) { + for _, errABI := range abi.Errors { + if bytes.Equal(errABI.ID[:4], sigdata[:]) { + return &errABI, nil + } + } + return nil, fmt.Errorf("no error with id: %#x", sigdata[:]) +} + // HasFallback returns an indicator whether a fallback function is included. func (abi *ABI) HasFallback() bool { return abi.Fallback.Type == Fallback diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 08fb9248ba..03de8e88aa 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1089,6 +1089,34 @@ func TestABI_EventById(t *testing.T) { } } +func TestABI_ErrorByID(t *testing.T) { + abi, err := JSON(strings.NewReader(`[ + {"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"MyError1","type":"error"}, + {"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"x","type":"tuple"},{"internalType":"address","name":"y","type":"address"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"z","type":"tuple"}],"name":"MyError2","type":"error"}, + {"inputs":[{"internalType":"uint256[]","name":"x","type":"uint256[]"}],"name":"MyError3","type":"error"} + ]`)) + if err != nil { + t.Fatal(err) + } + for name, m := range abi.Errors { + a := fmt.Sprintf("%v", &m) + var id [4]byte + copy(id[:], m.ID[:4]) + m2, err := abi.ErrorByID(id) + if err != nil { + t.Fatalf("Failed to look up ABI error: %v", err) + } + b := fmt.Sprintf("%v", m2) + if a != b { + t.Errorf("Error %v (id %x) not 'findable' by id in ABI", name, id) + } + } + // test unsuccessful lookups + if _, err = abi.ErrorByID([4]byte{}); err == nil { + t.Error("Expected error: no error with this id") + } +} + // TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name // conflict and that the second transfer method will be renamed transfer1. func TestDoubleDuplicateMethodNames(t *testing.T) { diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 61601007aa..2003073dd8 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -78,7 +78,7 @@ func NewError(name string, inputs Arguments) Error { } } -func (e *Error) String() string { +func (e Error) String() string { return e.str } From d4bf06d689170c02ce014dc19148b194d73833d2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 220/280] accounts: replace noarg fmt.Errorf with errors.New (#27331) * accounts: replace noarg fmt.Errorf with errors.New Signed-off-by: jsvisa * accounts: go autoimport Signed-off-by: jsvisa --------- Signed-off-by: jsvisa --- accounts/abi/bind/backends/simulated.go | 4 ++-- accounts/abi/reflect.go | 2 +- accounts/keystore/account_cache_test.go | 3 ++- accounts/scwallet/securechannel.go | 11 ++++++----- accounts/scwallet/wallet.go | 6 +++--- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 877851bcc8..9fd771913b 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -713,7 +713,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa // Get the last block block, err := b.blockByHash(ctx, b.pendingBlock.ParentHash()) if err != nil { - return fmt.Errorf("could not fetch parent") + return errors.New("could not fetch parent") } // Check transaction validity signer := types.MakeSigner(b.blockchain.Config(), block.Number()) @@ -847,7 +847,7 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error { // Get the last block block := b.blockchain.GetBlockByHash(b.pendingBlock.ParentHash()) if block == nil { - return fmt.Errorf("could not find parent") + return errors.New("could not find parent") } blocks, _ := core.GenerateChain(b.config, block, b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) { diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index c460c1ac92..1863e5bb7d 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -228,7 +228,7 @@ func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[stri structFieldName := ToCamelCase(argName) if structFieldName == "" { - return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") + return nil, errors.New("abi: purely underscored output cannot unpack to struct") } // this abi has already been paired, skip it... unless there exists another, yet unassigned diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index fdb230f2d8..5563f0a986 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -17,6 +17,7 @@ package keystore import ( + "errors" "fmt" "math/rand" "os" @@ -74,7 +75,7 @@ func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { select { case <-ks.changes: default: - return fmt.Errorf("wasn't notified of new accounts") + return errors.New("wasn't notified of new accounts") } return nil } diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index 5c7f59b7e5..5bb9ce9d77 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -24,6 +24,7 @@ import ( "crypto/rand" "crypto/sha256" "crypto/sha512" + "errors" "fmt" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -125,7 +126,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error { // Unpair disestablishes an existing pairing. func (s *SecureChannelSession) Unpair() error { if s.PairingKey == nil { - return fmt.Errorf("cannot unpair: not paired") + return errors.New("cannot unpair: not paired") } _, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{}) @@ -141,7 +142,7 @@ func (s *SecureChannelSession) Unpair() error { // Open initializes the secure channel. func (s *SecureChannelSession) Open() error { if s.iv != nil { - return fmt.Errorf("session already opened") + return errors.New("session already opened") } response, err := s.open() @@ -215,7 +216,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error // transmitEncrypted sends an encrypted message, and decrypts and returns the response. func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) { if s.iv == nil { - return nil, fmt.Errorf("channel not open") + return nil, errors.New("channel not open") } data, err := s.encryptAPDU(data) @@ -254,7 +255,7 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b return nil, err } if !bytes.Equal(s.iv, rmac) { - return nil, fmt.Errorf("invalid MAC in response") + return nil, errors.New("invalid MAC in response") } rapdu := &responseAPDU{} @@ -319,7 +320,7 @@ func unpad(data []byte, terminator byte) ([]byte, error) { return nil, fmt.Errorf("expected end of padding, got %d", data[len(data)-i]) } } - return nil, fmt.Errorf("expected end of padding, got 0") + return nil, errors.New("expected end of padding, got 0") } // updateIV is an internal method that updates the initialization vector after diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 556cbf325f..ee80984208 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -252,7 +252,7 @@ func (w *Wallet) release() error { // with the wallet. func (w *Wallet) pair(puk []byte) error { if w.session.paired() { - return fmt.Errorf("wallet already paired") + return errors.New("wallet already paired") } pairing, err := w.session.pair(puk) if err != nil { @@ -813,7 +813,7 @@ func (s *Session) pair(secret []byte) (smartcardPairing, error) { // unpair deletes an existing pairing. func (s *Session) unpair() error { if !s.verified { - return fmt.Errorf("unpair requires that the PIN be verified") + return errors.New("unpair requires that the PIN be verified") } return s.Channel.Unpair() } @@ -907,7 +907,7 @@ func (s *Session) initialize(seed []byte) error { return err } if status == "Online" { - return fmt.Errorf("card is already initialized, cowardly refusing to proceed") + return errors.New("card is already initialized, cowardly refusing to proceed") } s.Wallet.lock.Lock() From a57f3583fc2715f19d3a14e7d851d4c101d8c2c6 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 221/280] accounts/keystore: handle error for invalid key in DecryptKey (#27432) Co-authored-by: KAI Co-authored-by: Felix Lange --- accounts/keystore/passphrase.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index aad14137d5..eec9cdc805 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -225,10 +225,13 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) { if err != nil { return nil, err } - key := crypto.ToECDSAUnsafe(keyBytes) + key, err := crypto.ToECDSA(keyBytes) + if err != nil { + return nil, fmt.Errorf("invalid key: %w", err) + } id, err := uuid.FromBytes(keyId) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid UUID: %w", err) } return &Key{ Id: id, From f365434a0c6641bbbb74491f4f2d184232d4caee Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 222/280] accounts/keystore: use slices package for sorting (#27485) Co-authored-by: Felix Lange --- accounts/keystore/account_cache.go | 14 +++++++------- accounts/keystore/account_cache_test.go | 4 ++-- accounts/keystore/keystore_test.go | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index aec9825bab..83b7cdabd4 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "sort" "strings" "sync" @@ -38,11 +39,10 @@ import ( // exist yet, the code will attempt to create a watcher at most this often. const minReloadInterval = 2 * time.Second -type accountsByURL []accounts.Account - -func (s accountsByURL) Len() int { return len(s) } -func (s accountsByURL) Less(i, j int) bool { return s[i].URL.Cmp(s[j].URL) < 0 } -func (s accountsByURL) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +// byURL defines the sorting order for accounts. +func byURL(a, b accounts.Account) int { + return a.URL.Cmp(b.URL) +} // AmbiguousAddrError is returned when attempting to unlock // an address for which more than one file exists. @@ -67,7 +67,7 @@ type accountCache struct { keydir string watcher *watcher mu sync.Mutex - all accountsByURL + all []accounts.Account byAddr map[common.Address][]accounts.Account throttle *time.Timer notify chan struct{} @@ -194,7 +194,7 @@ func (ac *accountCache) find(a accounts.Account) (accounts.Account, error) { default: err := &AmbiguousAddrError{Addr: a.Address, Matches: make([]accounts.Account, len(matches))} copy(err.Matches, matches) - sort.Sort(accountsByURL(err.Matches)) + slices.SortFunc(err.Matches, byURL) return accounts.Account{}, err } } diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 5563f0a986..c4f12d6878 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -23,7 +23,7 @@ import ( "os" "path/filepath" "reflect" - "sort" + "slices" "testing" "time" @@ -203,7 +203,7 @@ func TestCacheAddDeleteOrder(t *testing.T) { // Check that the account list is sorted by filename. wantAccounts := make([]accounts.Account, len(accs)) copy(wantAccounts, accs) - sort.Sort(accountsByURL(wantAccounts)) + slices.SortFunc(wantAccounts, byURL) list := cache.accounts() if !reflect.DeepEqual(list, wantAccounts) { t.Fatalf("got accounts: %s\nwant %s", spew.Sdump(accs), spew.Sdump(wantAccounts)) diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 0f91904307..955b290c1e 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -20,7 +20,7 @@ import ( "math/rand" "os" "runtime" - "sort" + "slices" "strings" "sync" "sync/atomic" @@ -425,7 +425,7 @@ func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, walle for _, account := range live { liveList = append(liveList, account) } - sort.Sort(accountsByURL(liveList)) + slices.SortFunc(liveList, byURL) for j, wallet := range wallets { if accs := wallet.Accounts(); len(accs) != 1 { t.Errorf("wallet %d: contains invalid number of accounts: have %d, want 1", j, len(accs)) From 80967d52f60cce511e26b9028b3f3591cecced7f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 223/280] accounts: fix docstrings (#27703) fix function name in comment Signed-off-by: cui fliter --- accounts/abi/type.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index d50903e4c1..2dbd24c85a 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -347,7 +347,7 @@ func (t Type) pack(v reflect.Value) ([]byte, error) { } } -// requireLengthPrefix returns whether the type requires any sort of length +// requiresLengthPrefix returns whether the type requires any sort of length // prefixing. func (t Type) requiresLengthPrefix() bool { return t.T == StringTy || t.T == BytesTy || t.T == SliceTy From 0f737b4725812fd51164a9575d97577474adcbc5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 224/280] core: replace suicide with selfdestruct to improve code consistency (#27716) --- XDCx/tradingstate/statedb.go | 2 +- XDCxlending/lendingstate/statedb.go | 2 +- accounts/abi/bind/backend.go | 2 +- core/state/journal.go | 8 ++++---- core/state/state_object.go | 31 ++++++++++++++++++----------- core/state/state_test.go | 10 +++++----- core/state/statedb.go | 30 +++++++++++++--------------- core/state/statedb_test.go | 7 +++---- core/vm/gas_table.go | 2 +- core/vm/instructions.go | 4 ++-- core/vm/interface.go | 6 +++--- core/vm/operations_acl.go | 2 +- 12 files changed, 55 insertions(+), 51 deletions(-) diff --git a/XDCx/tradingstate/statedb.go b/XDCx/tradingstate/statedb.go index 7520947db1..91010e9bff 100644 --- a/XDCx/tradingstate/statedb.go +++ b/XDCx/tradingstate/statedb.go @@ -89,7 +89,7 @@ func (t *TradingStateDB) Error() error { } // Exist reports whether the given orderId address exists in the state. -// Notably this also returns true for suicided exchanges. +// Notably this also returns true for self-destructed exchanges. func (t *TradingStateDB) Exist(addr common.Hash) bool { return t.getStateExchangeObject(addr) != nil } diff --git a/XDCxlending/lendingstate/statedb.go b/XDCxlending/lendingstate/statedb.go index a1b3899803..146cf4a8c8 100644 --- a/XDCxlending/lendingstate/statedb.go +++ b/XDCxlending/lendingstate/statedb.go @@ -84,7 +84,7 @@ func (ls *LendingStateDB) Error() error { } // Exist reports whether the given tradeId address exists in the state. -// Notably this also returns true for suicided lenddinges. +// Notably this also returns true for self-destructed lenddinges. func (ls *LendingStateDB) Exist(addr common.Hash) bool { return ls.getLendingExchange(addr) != nil } diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index b067b7da2a..5a00933abf 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -29,7 +29,7 @@ import ( var ( // ErrNoCode is returned by call and transact operations for which the requested // recipient contract to operate on does not exist in the state db or does not - // have any code associated with it (i.e. suicided). + // have any code associated with it (i.e. self-destructed). ErrNoCode = errors.New("no contract code at given address") // ErrNoPendingState is raised when attempting to perform a pending state action diff --git a/core/state/journal.go b/core/state/journal.go index d8f748fa64..2be83be064 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -41,9 +41,9 @@ type ( resetObjectChange struct { prev *stateObject } - suicideChange struct { + selfDestructChange struct { account *common.Address - prev bool // whether account had already suicided + prev bool // whether account had already self-destructed prevbalance *big.Int } @@ -104,10 +104,10 @@ func (ch resetObjectChange) undo(s *StateDB) { s.setStateObject(ch.prev) } -func (ch suicideChange) undo(s *StateDB) { +func (ch selfDestructChange) undo(s *StateDB) { obj := s.getStateObject(*ch.account) if obj != nil { - obj.suicided = ch.prev + obj.selfDestructed = ch.prev obj.setBalance(ch.prevbalance) } } diff --git a/core/state/state_object.go b/core/state/state_object.go index d49ae247ce..ef436ca34f 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -61,10 +61,10 @@ func (s Storage) Copy() Storage { // Account values can be accessed and modified through the object. // Finally, call CommitTrie to write the modified storage trie into a database. type stateObject struct { - address common.Address - addrHash common.Hash // hash of ethereum address of the account - data Account db *StateDB + address common.Address // address of ethereum account + addrHash common.Hash // hash of ethereum address of the account + data Account // Account data with all mutations applied in the scope of block // DB error. // State objects are used by the consensus core and VM which are @@ -82,13 +82,20 @@ type stateObject struct { fakeStorage Storage // Fake storage which constructed by caller for debugging purpose. // Cache flags. - // When an object is marked suicided it will be delete from the trie - // during the "update" phase of the state transition. dirtyCode bool // true if the code was updated - suicided bool - touched bool - deleted bool - onDirty func(addr common.Address) // Callback method to mark a state object newly dirty + + // Flag whether the account was marked as self-destructed. The self-destructed + // account is still accessible in the scope of same transaction. + selfDestructed bool + + // Flag whether the account was marked as deleted. A self-destructed account + // or an account that is considered as empty will be marked as deleted at + // the end of transaction and no longer accessible anymore. + deleted bool + + touched bool + + onDirty func(addr common.Address) // Callback method to mark a state object newly dirty } // empty returns whether the account is considered empty. @@ -136,8 +143,8 @@ func (s *stateObject) setError(err error) { } } -func (s *stateObject) markSuicided() { - s.suicided = true +func (s *stateObject) markSelfdestructed() { + s.selfDestructed = true if s.onDirty != nil { s.onDirty(s.Address()) s.onDirty = nil @@ -363,7 +370,7 @@ func (s *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) * stateObject.code = s.code stateObject.dirtyStorage = s.dirtyStorage.Copy() stateObject.cachedStorage = s.dirtyStorage.Copy() - stateObject.suicided = s.suicided + stateObject.selfDestructed = s.selfDestructed stateObject.dirtyCode = s.dirtyCode stateObject.deleted = s.deleted return stateObject diff --git a/core/state/state_test.go b/core/state/state_test.go index c4b49628d2..257f029a8b 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -18,11 +18,11 @@ package state import ( "bytes" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" "math/big" "testing" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/ethdb" checker "gopkg.in/check.v1" @@ -152,7 +152,7 @@ func TestSnapshot2(t *testing.T) { so0.SetBalance(big.NewInt(42)) so0.SetNonce(43) so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) - so0.suicided = false + so0.selfDestructed = false so0.deleted = false state.setStateObject(so0) @@ -164,7 +164,7 @@ func TestSnapshot2(t *testing.T) { so1.SetBalance(big.NewInt(52)) so1.SetNonce(53) so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) - so1.suicided = true + so1.selfDestructed = true so1.deleted = true state.setStateObject(so1) @@ -224,8 +224,8 @@ func compareStateObjects(so0, so1 *stateObject, t *testing.T) { } } - if so0.suicided != so1.suicided { - t.Fatalf("suicided mismatch: have %v, want %v", so0.suicided, so1.suicided) + if so0.selfDestructed != so1.selfDestructed { + t.Fatalf("self-destructed mismatch: have %v, want %v", so0.selfDestructed, so1.selfDestructed) } if so0.deleted != so1.deleted { t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted) diff --git a/core/state/statedb.go b/core/state/statedb.go index d357e6e1bf..9003f58fde 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -214,7 +214,7 @@ func (s *StateDB) AddRefund(gas uint64) { } // Exist reports whether the given account address exists in the state. -// Notably this also returns true for suicided accounts. +// Notably this also returns true for self-destructed accounts. func (s *StateDB) Exist(addr common.Address) bool { return s.getStateObject(addr) != nil } @@ -336,10 +336,10 @@ func (s *StateDB) StorageTrie(addr common.Address) Trie { return cpy.updateTrie(s.db) } -func (s *StateDB) HasSuicided(addr common.Address) bool { +func (s *StateDB) HasSelfDestructed(addr common.Address) bool { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.suicided + return stateObject.selfDestructed } return false } @@ -401,25 +401,23 @@ func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common } } -// Suicide marks the given account as suicided. +// SelfDestruct marks the given account as selfdestructed. // This clears the account balance. // // The account's state object is still available until the state is committed, -// getStateObject will return a non-nil account after Suicide. -func (s *StateDB) Suicide(addr common.Address) bool { +// getStateObject will return a non-nil account after SelfDestruct. +func (s *StateDB) SelfDestruct(addr common.Address) { stateObject := s.getStateObject(addr) if stateObject == nil { - return false + return } - s.journal = append(s.journal, suicideChange{ + s.journal = append(s.journal, selfDestructChange{ account: &addr, - prev: stateObject.suicided, + prev: stateObject.selfDestructed, prevbalance: new(big.Int).Set(stateObject.Balance()), }) - stateObject.markSuicided() + stateObject.markSelfdestructed() stateObject.data.Balance = new(big.Int) - - return true } // SetTransientState sets transient storage for a given account. It @@ -679,7 +677,7 @@ func (s *StateDB) GetRefund() uint64 { func (s *StateDB) Finalise(deleteEmptyObjects bool) { for addr := range s.stateObjectsDirty { stateObject := s.stateObjects[addr] - if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { + if stateObject.selfDestructed || (deleteEmptyObjects && stateObject.empty()) { s.deleteStateObject(stateObject) } else { stateObject.updateRoot(s.db) @@ -710,7 +708,7 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) { s.txIndex = ti } -// DeleteSuicides flags the suicided objects for deletion so that it +// DeleteSuicides flags the self-destructed objects for deletion so that it // won't be referenced again when called / queried up on. // // DeleteSuicides should not be used for consensus related updates @@ -724,7 +722,7 @@ func (s *StateDB) DeleteSuicides() { // If the object has been removed by a suicide // flag the object as deleted. - if stateObject.suicided { + if stateObject.selfDestructed { stateObject.deleted = true } delete(s.stateObjectsDirty, addr) @@ -745,7 +743,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) for addr, stateObject := range s.stateObjects { _, isDirty := s.stateObjectsDirty[addr] switch { - case stateObject.suicided || (isDirty && deleteEmptyObjects && stateObject.empty()): + case stateObject.selfDestructed || (isDirty && deleteEmptyObjects && stateObject.empty()): // If the object has been removed, don't bother syncing it // and just mark it for deletion in the trie. s.deleteStateObject(stateObject) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 5166224b35..a4af4661e4 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -29,7 +29,6 @@ import ( "testing/quick" check "gopkg.in/check.v1" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -261,9 +260,9 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { }, }, { - name: "Suicide", + name: "SelfDestruct", fn: func(a testAction, s *StateDB) { - s.Suicide(addr) + s.SelfDestruct(addr) }, }, { @@ -405,7 +404,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { } // Check basic accessor methods. checkeq("Exist", state.Exist(addr), checkstate.Exist(addr)) - checkeq("HasSuicided", state.HasSuicided(addr), checkstate.HasSuicided(addr)) + checkeq("HasSelfDestructed", state.HasSelfDestructed(addr), checkstate.HasSelfDestructed(addr)) checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr)) checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr)) checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 748d1f3ddd..1f9424aed5 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -469,7 +469,7 @@ func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me } } - if !evm.StateDB.HasSuicided(contract.Address()) { + if !evm.StateDB.HasSelfDestructed(contract.Address()) { evm.StateDB.AddRefund(params.SelfdestructRefundGas) } return gas, nil diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 6a0ddea1b1..2802c62bcf 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -415,7 +415,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // If the precompile account is not transferred any amount on a private or // customized chain, the return value will be zero. // -// (5) Caller tries to get the code hash for an account which is marked as suicided +// (5) Caller tries to get the code hash for an account which is marked as self-destructed // // in the current transaction, the code hash of this account should be returned. // @@ -837,7 +837,7 @@ func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext beneficiary := scope.Stack.pop() balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) - interpreter.evm.StateDB.Suicide(scope.Contract.Address()) + interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address()) if interpreter.evm.Config.Debug { interpreter.evm.Config.Tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance) interpreter.evm.Config.Tracer.CaptureExit([]byte{}, 0, nil) diff --git a/core/vm/interface.go b/core/vm/interface.go index c6c3ee1cfd..105be10b71 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -51,11 +51,11 @@ type StateDB interface { GetTransientState(addr common.Address, key common.Hash) common.Hash SetTransientState(addr common.Address, key, value common.Hash) - Suicide(common.Address) bool - HasSuicided(common.Address) bool + SelfDestruct(common.Address) + HasSelfDestructed(common.Address) bool // Exist reports whether the given account exists in state. - // Notably this should also return true for suicided accounts. + // Notably this should also return true for self-destructed accounts. Exist(common.Address) bool // Empty returns whether the given account is empty. Empty // is defined according to EIP161 (balance = nonce = code = 0). diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index dfef062856..6894f795db 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -235,7 +235,7 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { gas += params.CreateBySelfdestructGas } - if refundsEnabled && !evm.StateDB.HasSuicided(contract.Address()) { + if refundsEnabled && !evm.StateDB.HasSelfDestructed(contract.Address()) { evm.StateDB.AddRefund(params.SelfdestructRefundGas) } return gas, nil From e1c7317374975e3bf7f36cb640a7053d3b46c1e7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 225/280] all: remove trailing whitespace (#27741) --- accounts/abi/bind/template.go | 16 ++++++++-------- accounts/abi/error.go | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index c1c041f234..7033ff04d1 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -324,7 +324,7 @@ var ( if err != nil { return *outstruct, err } - {{range $i, $t := .Normalized.Outputs}} + {{range $i, $t := .Normalized.Outputs}} outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} return *outstruct, err @@ -334,7 +334,7 @@ var ( } {{range $i, $t := .Normalized.Outputs}} out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} - + return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err {{end}} } @@ -377,7 +377,7 @@ var ( } {{end}} - {{if .Fallback}} + {{if .Fallback}} // Fallback is a paid mutator transaction binding the contract fallback function. // // Solidity: {{.Fallback.Original.String}} @@ -391,16 +391,16 @@ var ( func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) } - + // Fallback is a paid mutator transaction binding the contract fallback function. - // + // // Solidity: {{.Fallback.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) } {{end}} - {{if .Receive}} + {{if .Receive}} // Receive is a paid mutator transaction binding the contract receive function. // // Solidity: {{.Receive.Original.String}} @@ -414,9 +414,9 @@ var ( func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) } - + // Receive is a paid mutator transaction binding the contract receive function. - // + // // Solidity: {{.Receive.Original.String}} func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 2003073dd8..8881850315 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -32,7 +32,7 @@ type Error struct { str string // Sig contains the string signature according to the ABI spec. - // e.g. error foo(uint32 a, int b) = "foo(uint32,int256)" + // e.g. error foo(uint32 a, int b) = "foo(uint32,int256)" // Please note that "int" is substitute for its canonical representation "int256" Sig string From 3bce105c95325a490f55a3435b0823cfb7fe0b4e Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 226/280] accounts: use atomic type (#27857) --- accounts/keystore/keystore_test.go | 6 +++--- accounts/usbwallet/hub.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 955b290c1e..265ceb927c 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -398,19 +398,19 @@ func TestImportRace(t *testing.T) { t.Fatalf("failed to export account: %v", acc) } _, ks2 := tmpKeyStore(t, true) - var atom uint32 + var atom atomic.Uint32 var wg sync.WaitGroup wg.Add(2) for i := 0; i < 2; i++ { go func() { defer wg.Done() if _, err := ks2.Import(json, "new", "new"); err != nil { - atomic.AddUint32(&atom, 1) + atom.Add(1) } }() } wg.Wait() - if atom != 1 { + if atom.Load() != 1 { t.Errorf("Import is racy") } } diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 5d33432667..66948a23d8 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -63,9 +63,9 @@ type Hub struct { stateLock sync.RWMutex // Protects the internals of the hub from racey access // TODO(karalabe): remove if hotplug lands on Windows - commsPend int // Number of operations blocking enumeration - commsLock sync.Mutex // Lock protecting the pending counter and enumeration - enumFails uint32 // Number of times enumeration has failed + commsPend int // Number of operations blocking enumeration + commsLock sync.Mutex // Lock protecting the pending counter and enumeration + enumFails atomic.Uint32 // Number of times enumeration has failed } // NewLedgerHub creates a new hardware wallet manager for Ledger devices. @@ -151,7 +151,7 @@ func (hub *Hub) refreshWallets() { return } // If USB enumeration is continually failing, don't keep trying indefinitely - if atomic.LoadUint32(&hub.enumFails) > 2 { + if hub.enumFails.Load() > 2 { return } // Retrieve the current list of USB wallet devices @@ -172,7 +172,7 @@ func (hub *Hub) refreshWallets() { } infos, err := usb.Enumerate(hub.vendorID, 0) if err != nil { - failcount := atomic.AddUint32(&hub.enumFails, 1) + failcount := hub.enumFails.Add(1) if runtime.GOOS == "linux" { // See rationale before the enumeration why this is needed and only on Linux. hub.commsLock.Unlock() @@ -181,7 +181,7 @@ func (hub *Hub) refreshWallets() { "vendor", hub.vendorID, "failcount", failcount, "err", err) return } - atomic.StoreUint32(&hub.enumFails, 0) + hub.enumFails.Store(0) for _, info := range infos { for _, id := range hub.productIDs { From d2cfa789dae17a65114ab5786c595c76e335d11a Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 227/280] account/abi: convert if-else-if chain to tagged switch (#27869) account/abi: conver if-else-if chain to tagged switch --- accounts/abi/method.go | 7 ++++--- accounts/abi/method_test.go | 7 ++++--- accounts/abi/unpack.go | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/accounts/abi/method.go b/accounts/abi/method.go index c67a8a1e78..37c6859543 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -127,11 +127,12 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str state = state + " " } identity := fmt.Sprintf("function %v", rawName) - if funType == Fallback { + switch funType { + case Fallback: identity = "fallback" - } else if funType == Receive { + case Receive: identity = "receive" - } else if funType == Constructor { + case Constructor: identity = "constructor" } str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", ")) diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go index eb6c65f69b..f3dbe52d18 100644 --- a/accounts/abi/method_test.go +++ b/accounts/abi/method_test.go @@ -84,11 +84,12 @@ func TestMethodString(t *testing.T) { for _, test := range table { var got string - if test.method == "fallback" { + switch test.method { + case "fallback": got = abi.Fallback.String() - } else if test.method == "receive" { + case "receive": got = abi.Receive.String() - } else { + default: got = abi.Methods[test.method].String() } if got != test.expectation { diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index e6478a4e20..9be04bac14 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -160,13 +160,14 @@ func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) // this value will become our slice or our array, depending on the type var refSlice reflect.Value - if t.T == SliceTy { + switch t.T { + case SliceTy: // declare our slice refSlice = reflect.MakeSlice(t.GetType(), size, size) - } else if t.T == ArrayTy { + case ArrayTy: // declare our array refSlice = reflect.New(t.GetType()).Elem() - } else { + default: return nil, errors.New("abi: invalid type in array/slice unpacking stage") } From 4c7507af85107aa035ef503bd6a58912644f6665 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 228/280] account/abi: handle solidity panic revert (#27868) See https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require --- accounts/abi/abi.go | 66 ++++++++++++++++++++++++++++++++-------- accounts/abi/abi_test.go | 64 +++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 43 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index e84181a51c..7716206be7 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "io" + "math/big" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -246,24 +247,65 @@ func (abi *ABI) HasReceive() bool { // revertSelector is a special function selector for revert reason unpacking. var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] +// panicSelector is a special function selector for panic reason unpacking. +var panicSelector = crypto.Keccak256([]byte("Panic(uint256)"))[:4] + +// panicReasons map is for readable panic codes +// see this linkage for the deails +// https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require +// the reason string list is copied from ether.js +// https://github.com/ethers-io/ethers.js/blob/fa3a883ff7c88611ce766f58bdd4b8ac90814470/src.ts/abi/interface.ts#L207-L218 +var panicReasons = map[uint64]string{ + 0x00: "generic panic", + 0x01: "assert(false)", + 0x11: "arithmetic underflow or overflow", + 0x12: "division or modulo by zero", + 0x21: "enum overflow", + 0x22: "invalid encoded storage byte array accessed", + 0x31: "out-of-bounds array access; popping on an empty array", + 0x32: "out-of-bounds access of an array or bytesN", + 0x41: "out of memory", + 0x51: "uninitialized function", +} + // UnpackRevert resolves the abi-encoded revert reason. According to the solidity // spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert, -// the provided revert reason is abi-encoded as if it were a call to a function -// `Error(string)`. So it's a special tool for it. +// the provided revert reason is abi-encoded as if it were a call to function +// `Error(string)` or `Panic(uint256)`. So it's a special tool for it. func UnpackRevert(data []byte) (string, error) { if len(data) < 4 { return "", errors.New("invalid data for unpacking") } - if !bytes.Equal(data[:4], revertSelector) { + switch { + case bytes.Equal(data[:4], revertSelector): + typ, err := NewType("string", "", nil) + if err != nil { + return "", err + } + unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:]) + if err != nil { + return "", err + } + return unpacked[0].(string), nil + case bytes.Equal(data[:4], panicSelector): + typ, err := NewType("uint256", "", nil) + if err != nil { + return "", err + } + unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:]) + if err != nil { + return "", err + } + pCode := unpacked[0].(*big.Int) + // uint64 safety check for future + // but the code is not bigger than MAX(uint64) now + if pCode.IsUint64() { + if reason, ok := panicReasons[pCode.Uint64()]; ok { + return reason, nil + } + } + return fmt.Sprintf("unknown panic code: %#x", pCode), nil + default: return "", errors.New("invalid data for unpacking") } - typ, err := NewType("string", "", nil) - if err != nil { - return "", err - } - unpacked, err := (Arguments{{Type: typ}}).Unpack(data[4:]) - if err != nil { - return "", err - } - return unpacked[0].(string), nil } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 03de8e88aa..bd3bce17ad 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -992,37 +992,6 @@ func TestABI_MethodById(t *testing.T) { } } -func TestUnpackRevert(t *testing.T) { - t.Parallel() - - var cases = []struct { - input string - expect string - expectErr error - }{ - {"", "", errors.New("invalid data for unpacking")}, - {"08c379a1", "", errors.New("invalid data for unpacking")}, - {"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil}, - } - for index, c := range cases { - t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) { - got, err := UnpackRevert(common.Hex2Bytes(c.input)) - if c.expectErr != nil { - if err == nil { - t.Fatalf("Expected non-nil error") - } - if err.Error() != c.expectErr.Error() { - t.Fatalf("Expected error mismatch, want %v, got %v", c.expectErr, err) - } - return - } - if c.expect != got { - t.Fatalf("Output mismatch, want %v, got %v", c.expect, got) - } - }) - } -} - func TestABI_EventById(t *testing.T) { tests := []struct { name string @@ -1193,3 +1162,36 @@ func TestUnnamedEventParam(t *testing.T) { t.Fatalf("Could not find input") } } + +func TestUnpackRevert(t *testing.T) { + t.Parallel() + + var cases = []struct { + input string + expect string + expectErr error + }{ + {"", "", errors.New("invalid data for unpacking")}, + {"08c379a1", "", errors.New("invalid data for unpacking")}, + {"08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000", "revert reason", nil}, + {"4e487b710000000000000000000000000000000000000000000000000000000000000000", "generic panic", nil}, + {"4e487b7100000000000000000000000000000000000000000000000000000000000000ff", "unknown panic code: 0xff", nil}, + } + for index, c := range cases { + t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) { + got, err := UnpackRevert(common.Hex2Bytes(c.input)) + if c.expectErr != nil { + if err == nil { + t.Fatalf("Expected non-nil error") + } + if err.Error() != c.expectErr.Error() { + t.Fatalf("Expected error mismatch, want %v, got %v", c.expectErr, err) + } + return + } + if c.expect != got { + t.Fatalf("Output mismatch, want %v, got %v", c.expect, got) + } + }) + } +} From 3e880ef27d42e78c1c3d85e70defae21ada4a503 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 229/280] cmd/clef: suppress fsnotify error if keydir not exists (#28160) As the keydir will be automatically created after an account is created, no error message if the watcher is failed. --- accounts/keystore/watch.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index 00deab03e4..abff2fe1d1 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -20,6 +20,7 @@ package keystore import ( + "os" "time" "github.com/XinFinOrg/XDPoSChain/log" @@ -77,7 +78,9 @@ func (w *watcher) loop() { } defer watcher.Close() if err := watcher.Add(w.ac.keydir); err != nil { - logger.Warn("Failed to watch keystore folder", "err", err) + if !os.IsNotExist(err) { + logger.Warn("Failed to watch keystore folder", "err", err) + } return } From 0efc73d66480a027514582f0cace301a2cece9a1 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 230/280] accounts: handle genesis state missing (#28171) --- accounts/abi/bind/backends/simulated.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 9fd771913b..ca0f1dd672 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -254,7 +254,6 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, if err != nil { return nil, err } - return stateDB.GetCode(contract), nil } @@ -267,7 +266,6 @@ func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Addres if err != nil { return nil, err } - return stateDB.GetBalance(contract), nil } @@ -280,7 +278,6 @@ func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, if err != nil { return 0, err } - return stateDB.GetNonce(contract), nil } @@ -293,7 +290,6 @@ func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Addres if err != nil { return nil, err } - val := stateDB.GetState(contract, key) return val[:], nil } @@ -732,8 +728,10 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa } block.AddTxWithChain(b.blockchain, tx) }) - stateDB, _ := b.blockchain.State() - + stateDB, err := b.blockchain.State() + if err != nil { + return err + } b.pendingBlock = blocks[0] b.pendingState, _ = state.New(b.pendingBlock.Root(), stateDB.Database()) b.pendingReceipts = receipts[0] From 57598e18259fe2f2fcaff6950319c270c58cb213 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 231/280] accounts/abi/bind/backend: use requested header for gas prices and gas limits (#28280) --- accounts/abi/bind/backends/simulated.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index ca0f1dd672..e0dcc88024 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -674,7 +674,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM } // Ensure message is initialized properly. if call.Gas == 0 { - call.Gas = 50000000 + call.Gas = 10 * head.GasLimit } if call.Value == nil { call.Value = new(big.Int) From 382855b191f2d6d736c502132b8dc93a25c991f0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 232/280] accounts, cmd: fix typos (#28300) --- accounts/scwallet/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md index 4313d9c6b2..28079c4743 100644 --- a/accounts/scwallet/README.md +++ b/accounts/scwallet/README.md @@ -8,7 +8,7 @@ ## Preparing the smartcard - **WARNING: FOILLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** + **WARNING: FOLLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get _at least_ version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.2.1/keycard_v2.2.1.cap) From b6c33b9a14d429144ce2bcb471de2a6f8ebe6dd7 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 233/280] internal/ethapi, accounts/abi/bind: use `errors.Is` for error comparison (#28348) Co-authored-by: lightclient --- accounts/abi/bind/backends/simulated.go | 2 +- internal/ethapi/api.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index e0dcc88024..37828a5696 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -622,7 +622,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs return 0, err } if failed { - if result != nil && result.Err != vm.ErrOutOfGas { + if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) { if len(result.Revert()) > 0 { return 0, newRevertError(result) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index dd15b4fa5d..bf17b10169 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1545,7 +1545,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr } if failed { - if result != nil && result.Err != vm.ErrOutOfGas { + if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) { if len(result.Revert()) > 0 { return 0, newRevertError(result) } From df8760535554553a79cb4e1f94494a9783263bce Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 234/280] api/bind: add CallOpts.BlockHash to allow calling contracts at a specific block hash (#28084) * api/bind: Add CallOpts.BlockHash to allow calling contracts at a specific block hash. * ethclient: Add BalanceAtHash, NonceAtHash and StorageAtHash functions --- accounts/abi/bind/backend.go | 27 ++++++-- accounts/abi/bind/backends/simulated.go | 43 ++++++++++++- accounts/abi/bind/backends/simulated_test.go | 56 ++++++++++++++++- accounts/abi/bind/base.go | 18 ++++++ accounts/abi/bind/base_test.go | 65 ++++++++++++++++++++ ethclient/ethclient_test.go | 24 ++++---- 6 files changed, 213 insertions(+), 20 deletions(-) diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 5a00933abf..e3831893da 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -21,7 +21,7 @@ import ( "errors" "math/big" - "github.com/XinFinOrg/XDPoSChain" + ethereum "github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core/types" ) @@ -36,6 +36,10 @@ var ( // on a backend that doesn't implement PendingContractCaller. ErrNoPendingState = errors.New("backend does not support pending state") + // ErrNoBlockHashState is raised when attempting to perform a block hash action + // on a backend that doesn't implement BlockHashContractCaller. + ErrNoBlockHashState = errors.New("backend does not support block hash state") + // ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves // an empty contract behind. ErrNoCodeAfterDeploy = errors.New("no contract code after deployment") @@ -50,7 +54,7 @@ type ContractCaller interface { // CallContract executes an Ethereum contract call with the specified data as the // input. - CallContract(ctx context.Context, call XDPoSChain.CallMsg, blockNumber *big.Int) ([]byte, error) + CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) } // PendingContractCaller defines methods to perform contract calls on the pending state. @@ -61,7 +65,18 @@ type PendingContractCaller interface { PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) // PendingCallContract executes an Ethereum contract call against the pending state. - PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error) + PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) +} + +// BlockHashContractCaller defines methods to perform contract calls on a specific block hash. +// Call will try to discover this interface when access to a block by hash is requested. +// If the backend does not support the block hash state, Call returns ErrNoBlockHashState. +type BlockHashContractCaller interface { + // CodeAtHash returns the code of the given account in the state at the specified block hash. + CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) + + // CallContractAtHash executes an Ethereum contract all against the state at the specified block hash. + CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) } // ContractTransactor defines the methods needed to allow operating with a contract @@ -92,7 +107,7 @@ type ContractTransactor interface { // There is no guarantee that this is the true gas limit requirement as other // transactions may be added or removed by miners, but it should provide a basis // for setting a reasonable default. - EstimateGas(ctx context.Context, call XDPoSChain.CallMsg) (gas uint64, err error) + EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) // SendTransaction injects the transaction into the pending pool for execution. SendTransaction(ctx context.Context, tx *types.Transaction) error @@ -105,11 +120,11 @@ type ContractFilterer interface { // returning all the results in one batch. // // TODO(karalabe): Deprecate when the subscription one can return past data too. - FilterLogs(ctx context.Context, query XDPoSChain.FilterQuery) ([]types.Log, error) + FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) // SubscribeFilterLogs creates a background log filtering operation, returning // a subscription immediately, which can be used to stream the found events. - SubscribeFilterLogs(ctx context.Context, query XDPoSChain.FilterQuery, ch chan<- types.Log) (XDPoSChain.Subscription, error) + SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) } // DeployBackend wraps the operations needed by WaitMined and WaitDeployed. diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 37828a5696..9fde5ce863 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -58,6 +58,7 @@ var _ bind.ContractBackend = (*SimulatedBackend)(nil) var ( errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block") + errBlockHashUnsupported = errors.New("simulatedBackend cannot access blocks by hash other than the latest block") errBlockDoesNotExist = errors.New("block does not exist in blockchain") errTransactionDoesNotExist = errors.New("transaction does not exist") ) @@ -257,6 +258,24 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, return stateDB.GetCode(contract), nil } +// CodeAtHash returns the code associated with a certain account in the blockchain. +func (b *SimulatedBackend) CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + header, err := b.headerByHash(blockHash) + if err != nil { + return nil, err + } + + stateDB, err := b.blockchain.StateAt(header.Root) + if err != nil { + return nil, err + } + + return stateDB.GetCode(contract), nil +} + // BalanceAt returns the wei balance of a certain account in the blockchain. func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) { b.mu.Lock() @@ -388,7 +407,11 @@ func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) ( func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { b.mu.Lock() defer b.mu.Unlock() + return b.headerByHash(hash) +} +// headerByHash retrieves a header from the database by hash without Lock. +func (b *SimulatedBackend) headerByHash(hash common.Hash) (*types.Header, error) { if hash == b.pendingBlock.Hash() { return b.pendingBlock.Header(), nil } @@ -504,11 +527,27 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 { return nil, errBlockNumberUnsupported } - state, err := b.blockchain.State() + return b.callContractAtHead(ctx, call) +} + +// CallContractAtHash executes a contract call on a specific block hash. +func (b *SimulatedBackend) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) { + b.mu.Lock() + defer b.mu.Unlock() + + if blockHash != b.blockchain.CurrentBlock().Hash() { + return nil, errBlockHashUnsupported + } + return b.callContractAtHead(ctx, call) +} + +// callContractAtHead executes a contract call against the latest block state. +func (b *SimulatedBackend) callContractAtHead(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { + stateDB, err := b.blockchain.State() if err != nil { return nil, err } - res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state) + res, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), stateDB) if err != nil { return nil, err } diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index da0b0947ec..fa48635807 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -966,6 +966,43 @@ func TestCodeAt(t *testing.T) { } } +func TestCodeAtHash(t *testing.T) { + testAddr := crypto.PubkeyToAddress(testKey.PublicKey) + sim := simTestBackend(testAddr) + defer sim.Close() + bgCtx := context.Background() + code, err := sim.CodeAtHash(bgCtx, testAddr, sim.blockchain.CurrentHeader().Hash()) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) != 0 { + t.Errorf("got code for account that does not have contract code") + } + + parsed, err := abi.JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) + contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) + if err != nil { + t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) + } + + blockHash := sim.Commit() + code, err = sim.CodeAtHash(bgCtx, contractAddr, blockHash) + if err != nil { + t.Errorf("could not get code at test addr: %v", err) + } + if len(code) == 0 { + t.Errorf("did not get code for account that has contract code") + } + // ensure code received equals code deployed + if !bytes.Equal(code, common.FromHex(deployedCode)) { + t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) + } +} + // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: // // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} @@ -1008,7 +1045,7 @@ func TestPendingAndCallContract(t *testing.T) { t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) } - sim.Commit() + blockHash := sim.Commit() // make sure you can call the contract res, err = sim.CallContract(bgCtx, ethereum.CallMsg{ @@ -1026,6 +1063,23 @@ func TestPendingAndCallContract(t *testing.T) { if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) } + + // make sure you can call the contract by hash + res, err = sim.CallContractAtHash(bgCtx, ethereum.CallMsg{ + From: testAddr, + To: &addr, + Data: input, + }, blockHash) + if err != nil { + t.Errorf("could not call receive method on contract: %v", err) + } + if len(res) == 0 { + t.Errorf("result of contract call was empty: %v", res) + } + + if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { + t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) + } } // This test is based on the following contract: diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index abd2e7ad45..5dbe445eb2 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -48,6 +48,7 @@ type CallOpts struct { Pending bool // Whether to operate on the pending state or the last known one From common.Address // Optional the sender address, otherwise the first account is used BlockNumber *big.Int // Optional the block number on which the call should be performed + BlockHash common.Hash // Optional the block hash on which the call should be performed Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } @@ -189,6 +190,23 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return ErrNoCode } } + } else if opts.BlockHash != (common.Hash{}) { + bh, ok := c.caller.(BlockHashContractCaller) + if !ok { + return ErrNoBlockHashState + } + output, err = bh.CallContractAtHash(ctx, msg, opts.BlockHash) + if err != nil { + return err + } + if len(output) == 0 { + // Make sure we have a contract to operate on, and bail out otherwise. + if code, err = bh.CodeAtHash(ctx, c.address, opts.BlockHash); err != nil { + return err + } else if len(code) == 0 { + return ErrNoCode + } + } } else { output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) if err != nil { diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index d46ab88b83..200686b547 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -114,6 +114,26 @@ func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ether return mc.pendingCallContractBytes, mc.pendingCallContractErr } +type mockBlockHashCaller struct { + *mockCaller + codeAtHashBytes []byte + codeAtHashErr error + codeAtHashCalled bool + callContractAtHashCalled bool + callContractAtHashBytes []byte + callContractAtHashErr error +} + +func (mc *mockBlockHashCaller) CodeAtHash(ctx context.Context, contract common.Address, hash common.Hash) ([]byte, error) { + mc.codeAtHashCalled = true + return mc.codeAtHashBytes, mc.codeAtHashErr +} + +func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, hash common.Hash) ([]byte, error) { + mc.callContractAtHashCalled = true + return mc.callContractAtHashBytes, mc.callContractAtHashErr +} + func TestPassingBlockNumber(t *testing.T) { mc := &mockPendingCaller{ mockCaller: &mockCaller{ @@ -388,6 +408,15 @@ func TestCall(t *testing.T) { Pending: true, }, method: method, + }, { + name: "ok hash", + mc: &mockBlockHashCaller{ + codeAtHashBytes: []byte{0}, + }, + opts: &bind.CallOpts{ + BlockHash: common.Hash{0xaa}, + }, + method: method, }, { name: "pack error, no method", mc: new(mockCaller), @@ -401,6 +430,14 @@ func TestCall(t *testing.T) { }, method: method, wantErrExact: bind.ErrNoPendingState, + }, { + name: "interface error, blockHash but not a BlockHashContractCaller", + mc: new(mockCaller), + opts: &bind.CallOpts{ + BlockHash: common.Hash{0xaa}, + }, + method: method, + wantErrExact: bind.ErrNoBlockHashState, }, { name: "pending call canceled", mc: &mockPendingCaller{ @@ -448,6 +485,34 @@ func TestCall(t *testing.T) { mc: new(mockCaller), method: method, wantErrExact: bind.ErrNoCode, + }, { + name: "call contract at hash error", + mc: &mockBlockHashCaller{ + callContractAtHashErr: context.DeadlineExceeded, + }, + opts: &bind.CallOpts{ + BlockHash: common.Hash{0xaa}, + }, + method: method, + wantErrExact: context.DeadlineExceeded, + }, { + name: "code at error", + mc: &mockBlockHashCaller{ + codeAtHashErr: errors.New(""), + }, + opts: &bind.CallOpts{ + BlockHash: common.Hash{0xaa}, + }, + method: method, + wantErr: true, + }, { + name: "no code at hash", + mc: new(mockBlockHashCaller), + opts: &bind.CallOpts{ + BlockHash: common.Hash{0xaa}, + }, + method: method, + wantErrExact: bind.ErrNoCode, }, { name: "unpack error missing arg", mc: &mockCaller{ diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 316cb01055..afbd469cfa 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -16,19 +16,21 @@ package ethclient -import "github.com/XinFinOrg/XDPoSChain" +import ( + ethereum "github.com/XinFinOrg/XDPoSChain" +) // Verify that Client implements the ethereum interfaces. var ( - _ = XDPoSChain.ChainReader(&Client{}) - _ = XDPoSChain.TransactionReader(&Client{}) - _ = XDPoSChain.ChainStateReader(&Client{}) - _ = XDPoSChain.ChainSyncReader(&Client{}) - _ = XDPoSChain.ContractCaller(&Client{}) - _ = XDPoSChain.GasEstimator(&Client{}) - _ = XDPoSChain.GasPricer(&Client{}) - _ = XDPoSChain.LogFilterer(&Client{}) - _ = XDPoSChain.PendingStateReader(&Client{}) + _ = ethereum.ChainReader(&Client{}) + _ = ethereum.TransactionReader(&Client{}) + _ = ethereum.ChainStateReader(&Client{}) + _ = ethereum.ChainSyncReader(&Client{}) + _ = ethereum.ContractCaller(&Client{}) + _ = ethereum.GasEstimator(&Client{}) + _ = ethereum.GasPricer(&Client{}) + _ = ethereum.LogFilterer(&Client{}) + _ = ethereum.PendingStateReader(&Client{}) // _ = ethereum.PendingStateEventer(&Client{}) - _ = XDPoSChain.PendingContractCaller(&Client{}) + _ = ethereum.PendingContractCaller(&Client{}) ) From 5081ad72f5abb578156eb11340257e3324427418 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:15 +0800 Subject: [PATCH 235/280] accounts: move fuzzers into native packages (#28467) --- accounts/abi/abifuzzer_test.go | 178 +++++++++++++++++++++ accounts/keystore/keystore_fuzzing_test.go | 34 ++++ tests/fuzzers/abi/abifuzzer_test.go | 50 ------ 3 files changed, 212 insertions(+), 50 deletions(-) create mode 100644 accounts/abi/abifuzzer_test.go create mode 100644 accounts/keystore/keystore_fuzzing_test.go delete mode 100644 tests/fuzzers/abi/abifuzzer_test.go diff --git a/accounts/abi/abifuzzer_test.go b/accounts/abi/abifuzzer_test.go new file mode 100644 index 0000000000..4b67947815 --- /dev/null +++ b/accounts/abi/abifuzzer_test.go @@ -0,0 +1,178 @@ +// Copyright 2020 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 . + +package abi + +import ( + "fmt" + "reflect" + "strings" + "testing" + + fuzz "github.com/google/gofuzz" +) + +// TestReplicate can be used to replicate crashers from the fuzzing tests. +// Just replace testString with the data in .quoted +func TestReplicate(t *testing.T) { + //t.Skip("Test only useful for reproducing issues") + fuzzAbi([]byte("\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00")) + //fuzzAbi([]byte("asdfasdfkadsf;lasdf;lasd;lfk")) +} + +// FuzzABI is the main entrypoint for fuzzing +func FuzzABI(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + fuzzAbi(data) + }) +} + +var ( + names = []string{"_name", "name", "NAME", "name_", "__", "_name_", "n"} + stateMut = []string{"pure", "view", "payable"} + pays = []string{"true", "false"} + vNames = []string{"a", "b", "c", "d", "e", "f", "g"} + varNames = append(vNames, names...) + varTypes = []string{"bool", "address", "bytes", "string", + "uint8", "int8", "uint8", "int8", "uint16", "int16", + "uint24", "int24", "uint32", "int32", "uint40", "int40", "uint48", "int48", "uint56", "int56", + "uint64", "int64", "uint72", "int72", "uint80", "int80", "uint88", "int88", "uint96", "int96", + "uint104", "int104", "uint112", "int112", "uint120", "int120", "uint128", "int128", "uint136", "int136", + "uint144", "int144", "uint152", "int152", "uint160", "int160", "uint168", "int168", "uint176", "int176", + "uint184", "int184", "uint192", "int192", "uint200", "int200", "uint208", "int208", "uint216", "int216", + "uint224", "int224", "uint232", "int232", "uint240", "int240", "uint248", "int248", "uint256", "int256", + "bytes1", "bytes2", "bytes3", "bytes4", "bytes5", "bytes6", "bytes7", "bytes8", "bytes9", "bytes10", "bytes11", + "bytes12", "bytes13", "bytes14", "bytes15", "bytes16", "bytes17", "bytes18", "bytes19", "bytes20", "bytes21", + "bytes22", "bytes23", "bytes24", "bytes25", "bytes26", "bytes27", "bytes28", "bytes29", "bytes30", "bytes31", + "bytes32", "bytes"} +) + +func unpackPack(abi ABI, method string, input []byte) ([]interface{}, bool) { + if out, err := abi.Unpack(method, input); err == nil { + _, err := abi.Pack(method, out...) + if err != nil { + // We have some false positives as we can unpack these type successfully, but not pack them + if err.Error() == "abi: cannot use []uint8 as type [0]int8 as argument" || + err.Error() == "abi: cannot use uint8 as type int8 as argument" { + return out, false + } + panic(err) + } + return out, true + } + return nil, false +} + +func packUnpack(abi ABI, method string, input *[]interface{}) bool { + if packed, err := abi.Pack(method, input); err == nil { + outptr := reflect.New(reflect.TypeOf(input)) + err := abi.UnpackIntoInterface(outptr.Interface(), method, packed) + if err != nil { + panic(err) + } + out := outptr.Elem().Interface() + if !reflect.DeepEqual(input, out) { + panic(fmt.Sprintf("unpackPack is not equal, \ninput : %x\noutput: %x", input, out)) + } + return true + } + return false +} + +type arg struct { + name string + typ string +} + +func createABI(name string, stateMutability, payable *string, inputs []arg) (ABI, error) { + sig := fmt.Sprintf(`[{ "type" : "function", "name" : "%v" `, name) + if stateMutability != nil { + sig += fmt.Sprintf(`, "stateMutability": "%v" `, *stateMutability) + } + if payable != nil { + sig += fmt.Sprintf(`, "payable": %v `, *payable) + } + if len(inputs) > 0 { + sig += `, "inputs" : [ {` + for i, inp := range inputs { + sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ) + if i+1 < len(inputs) { + sig += "," + } + } + sig += "} ]" + sig += `, "outputs" : [ {` + for i, inp := range inputs { + sig += fmt.Sprintf(`"name" : "%v", "type" : "%v" `, inp.name, inp.typ) + if i+1 < len(inputs) { + sig += "," + } + } + sig += "} ]" + } + sig += `}]` + //fmt.Printf("sig: %s\n", sig) + return JSON(strings.NewReader(sig)) +} + +func fuzzAbi(input []byte) { + var ( + fuzzer = fuzz.NewFromGoFuzz(input) + name = oneOf(fuzzer, names) + stateM = oneOfOrNil(fuzzer, stateMut) + payable = oneOfOrNil(fuzzer, pays) + arguments []arg + ) + for i := 0; i < upTo(fuzzer, 10); i++ { + argName := oneOf(fuzzer, varNames) + argTyp := oneOf(fuzzer, varTypes) + switch upTo(fuzzer, 10) { + case 0: // 10% chance to make it a slice + argTyp += "[]" + case 1: // 10% chance to make it an array + argTyp += fmt.Sprintf("[%d]", 1+upTo(fuzzer, 30)) + default: + } + arguments = append(arguments, arg{name: argName, typ: argTyp}) + } + abi, err := createABI(name, stateM, payable, arguments) + if err != nil { + //fmt.Printf("err: %v\n", err) + panic(err) + } + structs, _ := unpackPack(abi, name, input) + _ = packUnpack(abi, name, &structs) +} + +func upTo(fuzzer *fuzz.Fuzzer, max int) int { + var i int + fuzzer.Fuzz(&i) + if i < 0 { + return (-1 - i) % max + } + return i % max +} + +func oneOf(fuzzer *fuzz.Fuzzer, options []string) string { + return options[upTo(fuzzer, len(options))] +} + +func oneOfOrNil(fuzzer *fuzz.Fuzzer, options []string) *string { + if i := upTo(fuzzer, len(options)+1); i < len(options) { + return &options[i] + } + return nil +} diff --git a/accounts/keystore/keystore_fuzzing_test.go b/accounts/keystore/keystore_fuzzing_test.go new file mode 100644 index 0000000000..793b46336a --- /dev/null +++ b/accounts/keystore/keystore_fuzzing_test.go @@ -0,0 +1,34 @@ +// Copyright 2023 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 . + +package keystore + +import ( + "testing" +) + +func FuzzPassword(f *testing.F) { + f.Fuzz(func(t *testing.T, password string) { + ks := NewKeyStore(t.TempDir(), LightScryptN, LightScryptP) + a, err := ks.NewAccount(password) + if err != nil { + t.Fatal(err) + } + if err := ks.Unlock(a, password); err != nil { + t.Fatal(err) + } + }) +} diff --git a/tests/fuzzers/abi/abifuzzer_test.go b/tests/fuzzers/abi/abifuzzer_test.go deleted file mode 100644 index c72577e9ee..0000000000 --- a/tests/fuzzers/abi/abifuzzer_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2020 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 . - -package abi - -import ( - "testing" -) - -// TestReplicate can be used to replicate crashers from the fuzzing tests. -// Just replace testString with the data in .quoted -func TestReplicate(t *testing.T) { - testString := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00000000000" + - "00000000000000000000" + - "00000000000000000000" + - "00000001" - - data := []byte(testString) - runFuzzer(data) -} - -// TestGenerateCorpus can be used to add corpus for the fuzzer. -// Just replace corpusHex with the hexEncoded output you want to add to the fuzzer. -func TestGenerateCorpus(t *testing.T) { - /* - corpusHex := "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - data := common.FromHex(corpusHex) - checksum := sha1.Sum(data) - outf := fmt.Sprintf("corpus/%x", checksum) - if err := ioutil.WriteFile(outf, data, 0777); err != nil { - panic(err) - } - */ -} From 390daf98e4ee71c74b78d75ed7192ffb3fdca0d8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 236/280] accounts: fix errors checked by go-staticcheck ST1005 (#28532) --- accounts/abi/pack.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index 42b314c734..91e2d82e8f 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -57,7 +57,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) { reflectValue = mustArrayToByteSlice(reflectValue) } if reflectValue.Type() != reflect.TypeOf([]byte{}) { - return []byte{}, errors.New("Bytes type is neither slice nor array") + return []byte{}, errors.New("bytes type is neither slice nor array") } return packBytesSlice(reflectValue.Bytes(), reflectValue.Len()), nil case FixedBytesTy, FunctionTy: @@ -66,7 +66,7 @@ func packElement(t Type, reflectValue reflect.Value) ([]byte, error) { } return common.RightPadBytes(reflectValue.Bytes(), 32), nil default: - return []byte{}, fmt.Errorf("Could not pack element, unknown type: %v", t.T) + return []byte{}, fmt.Errorf("could not pack element, unknown type: %v", t.T) } } From 919cbf6032933bdc395a18495446070b3da4a1ad Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 237/280] accounts/abi: improve readability of method-to-string conversion (#28530) refactor: improve readability of NewMethod print --- accounts/abi/method.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 37c6859543..4ee7eae651 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -117,15 +117,6 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str sig = fmt.Sprintf("%v(%v)", rawName, strings.Join(types, ",")) id = crypto.Keccak256([]byte(sig))[:4] } - // Extract meaningful state mutability of solidity method. - // If it's default value, never print it. - state := mutability - if state == "nonpayable" { - state = "" - } - if state != "" { - state = state + " " - } identity := fmt.Sprintf("function %v", rawName) switch funType { case Fallback: @@ -135,7 +126,14 @@ func NewMethod(name string, rawName string, funType FunctionType, mutability str case Constructor: identity = "constructor" } - str := fmt.Sprintf("%v(%v) %sreturns(%v)", identity, strings.Join(inputNames, ", "), state, strings.Join(outputNames, ", ")) + var str string + // Extract meaningful state mutability of solidity method. + // If it's empty string or default value "nonpayable", never print it. + if mutability == "" || mutability == "nonpayable" { + str = fmt.Sprintf("%v(%v) returns(%v)", identity, strings.Join(inputNames, ", "), strings.Join(outputNames, ", ")) + } else { + str = fmt.Sprintf("%v(%v) %s returns(%v)", identity, strings.Join(inputNames, ", "), mutability, strings.Join(outputNames, ", ")) + } return Method{ Name: name, From e78abe0e44a19c793033b5b7334cf9410d9fcc60 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 238/280] accounts/scwallet: replace strings.SplitN(arg, sep, 2) with strings.Cut(arg, sep) (#28446) --- accounts/scwallet/wallet.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index ee80984208..a919394c63 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -776,16 +776,16 @@ func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationP return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) } - parts := strings.SplitN(account.URL.Path, "/", 2) - if len(parts) != 2 { + url, path, found := strings.Cut(account.URL.Path, "/") + if !found { return nil, fmt.Errorf("invalid URL format: %s", account.URL) } - if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) { + if url != fmt.Sprintf("%x", w.PublicKey[1:3]) { return nil, fmt.Errorf("URL %s is not for this wallet", account.URL) } - return accounts.ParseDerivationPath(parts[1]) + return accounts.ParseDerivationPath(path) } // Session represents a secured communication session with the wallet. From ccda15ef5d0695d2ed47b9947f99eb2f776ba552 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 239/280] accounts, cmd: fix typos (#28526) --- accounts/abi/argument.go | 4 ++-- accounts/abi/bind/util_test.go | 4 ++-- accounts/abi/unpack_test.go | 4 ++-- accounts/keystore/passphrase_test.go | 2 +- accounts/keystore/watch.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 2e48d539e0..fa5461895a 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -80,7 +80,7 @@ func (arguments Arguments) isTuple() bool { func (arguments Arguments) Unpack(data []byte) ([]interface{}, error) { if len(data) == 0 { if len(arguments.NonIndexed()) != 0 { - return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected") + return nil, errors.New("abi: attempting to unmarshal an empty string while arguments are expected") } return make([]interface{}, 0), nil } @@ -95,7 +95,7 @@ func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) } if len(data) == 0 { if len(arguments.NonIndexed()) != 0 { - return errors.New("abi: attempting to unmarshall an empty string while arguments are expected") + return errors.New("abi: attempting to unmarshal an empty string while arguments are expected") } return nil // Nothing to unmarshal, return } diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 04d70729ba..aae1a2f875 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -128,7 +128,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { backend.Commit() notContentCreation := errors.New("tx is not contract creation") if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() { - t.Errorf("error missmatch: want %q, got %q, ", notContentCreation, err) + t.Errorf("error mismatch: want %q, got %q, ", notContentCreation, err) } // Create a transaction that is not mined. @@ -138,7 +138,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { go func() { contextCanceled := errors.New("context canceled") if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != contextCanceled.Error() { - t.Errorf("error missmatch: want %q, got %q, ", contextCanceled, err) + t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err) } }() diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index fb0e4d2e0b..b27311ae0b 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -206,13 +206,13 @@ var unpackTests = []unpackTest{ def: `[{"type":"bool"}]`, enc: "", want: false, - err: "abi: attempting to unmarshall an empty string while arguments are expected", + err: "abi: attempting to unmarshal an empty string while arguments are expected", }, { def: `[{"type":"bytes32","indexed":true},{"type":"uint256","indexed":false}]`, enc: "", want: false, - err: "abi: attempting to unmarshall an empty string while arguments are expected", + err: "abi: attempting to unmarshal an empty string while arguments are expected", }, { def: `[{"type":"bool","indexed":true},{"type":"uint64","indexed":true}]`, diff --git a/accounts/keystore/passphrase_test.go b/accounts/keystore/passphrase_test.go index d843de3b94..748c3e822c 100644 --- a/accounts/keystore/passphrase_test.go +++ b/accounts/keystore/passphrase_test.go @@ -54,7 +54,7 @@ func TestKeyEncryptDecrypt(t *testing.T) { // Recrypt with a new password and start over password += "new data appended" // nolint: gosec if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil { - t.Errorf("test %d: failed to recrypt key %v", i, err) + t.Errorf("test %d: failed to re-encrypt key %v", i, err) } } } diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go index abff2fe1d1..a3952fd23f 100644 --- a/accounts/keystore/watch.go +++ b/accounts/keystore/watch.go @@ -125,7 +125,7 @@ func (w *watcher) loop() { if !ok { return } - log.Info("Filsystem watcher error", "err", err) + log.Info("Filesystem watcher error", "err", err) case <-debounce.C: w.ac.scanAccounts() rescanTriggered = false From 4d07efe6b6d67f91b7284783be3363bc143aab40 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 240/280] cdm/abigen: run tests in parallel (#28546) --- cmd/abigen/namefilter_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/abigen/namefilter_test.go b/cmd/abigen/namefilter_test.go index 42ba55be5e..ccee712018 100644 --- a/cmd/abigen/namefilter_test.go +++ b/cmd/abigen/namefilter_test.go @@ -8,6 +8,7 @@ import ( ) func TestNameFilter(t *testing.T) { + t.Parallel() _, err := newNameFilter("Foo") require.Error(t, err) _, err = newNameFilter("too/many:colons:Foo") From ea6606ad1c3be7cea9a450f371b4859c8bf3a1ab Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 241/280] accounts/abi: context info on unpack-errors (#28529) adds contextual information to errors returned by unpack --- accounts/abi/error.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index 8881850315..94d55f1f91 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -18,7 +18,6 @@ package abi import ( "bytes" - "errors" "fmt" "strings" @@ -84,10 +83,10 @@ func (e Error) String() string { func (e *Error) Unpack(data []byte) (interface{}, error) { if len(data) < 4 { - return "", errors.New("invalid data for unpacking") + return "", fmt.Errorf("insufficient data for unpacking: have %d, want at least 4", len(data)) } if !bytes.Equal(data[:4], e.ID[:4]) { - return "", errors.New("invalid data for unpacking") + return "", fmt.Errorf("invalid identifier, have %#x want %#x", data[:4], e.ID[:4]) } return e.Inputs.Unpack(data[4:]) } From f8042036093c01ec1af632e50606980937b271ff Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 242/280] accounts/keystore: speed up tests (#28461) --- accounts/keystore/account_cache_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index c4f12d6878..3e684e6a0e 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -68,7 +68,7 @@ func waitWatcherStart(ks *KeyStore) bool { func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { var list []accounts.Account - for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(200 * time.Millisecond) { + for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(100 * time.Millisecond) { list = ks.Accounts() if reflect.DeepEqual(list, wantAccounts) { // ks should have also received change notifications @@ -350,7 +350,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { return } // needed so that modTime of `file` is different to its current value after forceCopyFile - time.Sleep(time.Second) + os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second)) // Now replace file contents if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil { @@ -366,7 +366,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { } // needed so that modTime of `file` is different to its current value after forceCopyFile - time.Sleep(time.Second) + os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second)) // Now replace file contents again if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil { @@ -382,7 +382,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { } // needed so that modTime of `file` is different to its current value after os.WriteFile - time.Sleep(time.Second) + os.Chtimes(file, time.Now().Add(-time.Second), time.Now().Add(-time.Second)) // Now replace file contents with crap if err := os.WriteFile(file, []byte("foo"), 0600); err != nil { From 0b30a3de3848100394647681e6fc49f2eef2ee62 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 243/280] accounts/abi/bind: fix typo (#28630) --- accounts/abi/bind/util_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index aae1a2f875..6e4f8cc13f 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -126,9 +126,9 @@ func TestWaitDeployedCornerCases(t *testing.T) { defer cancel() backend.SendTransaction(ctx, tx) backend.Commit() - notContentCreation := errors.New("tx is not contract creation") - if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContentCreation.Error() { - t.Errorf("error mismatch: want %q, got %q, ", notContentCreation, err) + notContractCreation := errors.New("tx is not contract creation") + if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContractCreation.Error() { + t.Errorf("error mismatch: want %q, got %q, ", notContractCreation, err) } // Create a transaction that is not mined. From c032eed8f80d4186252e47cd3f9447411f7851be Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 244/280] accounts/abi/bind: fixed typos (#28634) * Update auth.go * Update backend.go * Update bind.go * Update bind_test.go --- accounts/abi/bind/auth.go | 2 +- accounts/abi/bind/backend.go | 2 +- accounts/abi/bind/bind.go | 2 +- accounts/abi/bind/bind_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 83e663a057..0f4279d98d 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -55,7 +55,7 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { } // NewKeyStoreTransactor is a utility method to easily create a transaction signer from -// an decrypted key from a keystore. +// a decrypted key from a keystore. // // Deprecated: Use NewKeyStoreTransactorWithChainID instead. func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) { diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index e3831893da..b681d65e79 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -75,7 +75,7 @@ type BlockHashContractCaller interface { // CodeAtHash returns the code of the given account in the state at the specified block hash. CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) - // CallContractAtHash executes an Ethereum contract all against the state at the specified block hash. + // CallContractAtHash executes an Ethereum contract call against the state at the specified block hash. CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 5103ab69ff..865f4e7ea0 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -364,7 +364,7 @@ func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string { // parameters that are not value types i.e. arrays and structs are not // stored directly but instead a keccak256-hash of an encoding is stored. // - // We only convert stringS and bytes to hash, still need to deal with + // We only convert strings and bytes to hash, still need to deal with // array(both fixed-size and dynamic-size) and struct. if bound == "string" || bound == "[]byte" { bound = "common.Hash" diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 0e4d4b738e..4bbc4feb6a 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1629,7 +1629,7 @@ var bindTests = []struct { } sim.Commit() - // This test the existence of the free retreiver call for view and pure functions + // This test the existence of the free retriever call for view and pure functions if num, err := pav.PureFunc(nil); err != nil { t.Fatalf("Failed to call anonymous field retriever: %v", err) } else if num.Cmp(big.NewInt(42)) != 0 { From 4a54407eb9608c71a07d4c2f02ccf1d5b7aad882 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 245/280] accounts: run tests in parallel (#28544) --- accounts/abi/abi_test.go | 24 ++ accounts/abi/abifuzzer_test.go | 1 + accounts/abi/bind/backends/simulated_test.go | 29 ++ accounts/abi/bind/base_test.go | 287 ++++++++++--------- accounts/abi/bind/bind_test.go | 1 + accounts/abi/bind/util_test.go | 2 + accounts/abi/event_test.go | 6 + accounts/abi/method_test.go | 2 + accounts/abi/pack_test.go | 5 + accounts/abi/reflect_test.go | 4 + accounts/abi/topics_test.go | 9 + accounts/abi/type_test.go | 5 + accounts/abi/unpack_test.go | 12 + accounts/accounts_test.go | 1 + accounts/hd_test.go | 2 + accounts/keystore/account_cache_test.go | 3 + accounts/keystore/keystore_test.go | 7 + accounts/keystore/passphrase_test.go | 1 + accounts/keystore/plain_test.go | 4 + 19 files changed, 267 insertions(+), 138 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index bd3bce17ad..263738b318 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -120,6 +120,7 @@ var methods = map[string]Method{ } func TestReader(t *testing.T) { + t.Parallel() abi := ABI{ Methods: methods, } @@ -151,6 +152,7 @@ func TestReader(t *testing.T) { } func TestInvalidABI(t *testing.T) { + t.Parallel() json := `[{ "type" : "function", "name" : "", "constant" : fals }]` _, err := JSON(strings.NewReader(json)) if err == nil { @@ -170,6 +172,7 @@ func TestInvalidABI(t *testing.T) { // constructor(uint256 a, uint256 b) public{} // } func TestConstructor(t *testing.T) { + t.Parallel() json := `[{ "inputs": [{"internalType": "uint256","name": "a","type": "uint256" },{ "internalType": "uint256","name": "b","type": "uint256"}],"stateMutability": "nonpayable","type": "constructor"}]` method := NewMethod("", "", Constructor, "nonpayable", false, false, []Argument{{"a", Uint256, false}, {"b", Uint256, false}}, nil) // Test from JSON @@ -199,6 +202,7 @@ func TestConstructor(t *testing.T) { } func TestTestNumbers(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) @@ -236,6 +240,7 @@ func TestTestNumbers(t *testing.T) { } func TestMethodSignature(t *testing.T) { + t.Parallel() m := NewMethod("foo", "foo", Function, "", false, false, []Argument{{"bar", String, false}, {"baz", String, false}}, nil) exp := "foo(string,string)" if m.Sig != exp { @@ -274,6 +279,7 @@ func TestMethodSignature(t *testing.T) { } func TestOverloadedMethodSignature(t *testing.T) { + t.Parallel() json := `[{"constant":true,"inputs":[{"name":"i","type":"uint256"},{"name":"j","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"i","type":"uint256"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"}],"name":"bar","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"i","type":"uint256"},{"indexed":false,"name":"j","type":"uint256"}],"name":"bar","type":"event"}]` abi, err := JSON(strings.NewReader(json)) if err != nil { @@ -297,6 +303,7 @@ func TestOverloadedMethodSignature(t *testing.T) { } func TestCustomErrors(t *testing.T) { + t.Parallel() json := `[{ "inputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ],"name": "MyError", "type": "error"} ]` abi, err := JSON(strings.NewReader(json)) if err != nil { @@ -311,6 +318,7 @@ func TestCustomErrors(t *testing.T) { } func TestMultiPack(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) @@ -349,6 +357,7 @@ func ExampleJSON() { } func TestInputVariableInputLength(t *testing.T) { + t.Parallel() const definition = `[ { "type" : "function", "name" : "strOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "string" } ] }, { "type" : "function", "name" : "bytesOne", "constant" : true, "inputs" : [ { "name" : "str", "type" : "bytes" } ] }, @@ -477,6 +486,7 @@ func TestInputVariableInputLength(t *testing.T) { } func TestInputFixedArrayAndVariableInputLength(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Error(err) @@ -651,6 +661,7 @@ func TestInputFixedArrayAndVariableInputLength(t *testing.T) { } func TestDefaultFunctionParsing(t *testing.T) { + t.Parallel() const definition = `[{ "name" : "balance", "type" : "function" }]` abi, err := JSON(strings.NewReader(definition)) @@ -664,6 +675,7 @@ func TestDefaultFunctionParsing(t *testing.T) { } func TestBareEvents(t *testing.T) { + t.Parallel() const definition = `[ { "type" : "event", "name" : "balance" }, { "type" : "event", "name" : "anon", "anonymous" : true}, @@ -740,6 +752,7 @@ func TestBareEvents(t *testing.T) { // // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestUnpackEvent(t *testing.T) { + t.Parallel() const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` abi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -778,6 +791,7 @@ func TestUnpackEvent(t *testing.T) { } func TestUnpackEventIntoMap(t *testing.T) { + t.Parallel() const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sender","type":"address"}],"name":"receivedAddr","type":"event"}]` abi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -828,6 +842,7 @@ func TestUnpackEventIntoMap(t *testing.T) { } func TestUnpackMethodIntoMap(t *testing.T) { + t.Parallel() const abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"receive","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]` abi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -878,6 +893,7 @@ func TestUnpackMethodIntoMap(t *testing.T) { } func TestUnpackIntoMapNamingConflict(t *testing.T) { + t.Parallel() // Two methods have the same name var abiJSON = `[{"constant":false,"inputs":[{"name":"memo","type":"bytes"}],"name":"get","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"send","outputs":[{"name":"amount","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"get","outputs":[{"name":"hash","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"}]` abi, err := JSON(strings.NewReader(abiJSON)) @@ -961,6 +977,7 @@ func TestUnpackIntoMapNamingConflict(t *testing.T) { } func TestABI_MethodById(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) @@ -993,6 +1010,7 @@ func TestABI_MethodById(t *testing.T) { } func TestABI_EventById(t *testing.T) { + t.Parallel() tests := []struct { name string json string @@ -1059,6 +1077,7 @@ func TestABI_EventById(t *testing.T) { } func TestABI_ErrorByID(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(`[ {"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"MyError1","type":"error"}, {"inputs":[{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"x","type":"tuple"},{"internalType":"address","name":"y","type":"address"},{"components":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"string","name":"b","type":"string"},{"internalType":"address","name":"c","type":"address"}],"internalType":"struct MyError.MyStruct","name":"z","type":"tuple"}],"name":"MyError2","type":"error"}, @@ -1089,6 +1108,7 @@ func TestABI_ErrorByID(t *testing.T) { // TestDoubleDuplicateMethodNames checks that if transfer0 already exists, there won't be a name // conflict and that the second transfer method will be renamed transfer1. func TestDoubleDuplicateMethodNames(t *testing.T) { + t.Parallel() abiJSON := `[{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transfer0","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"},{"name":"customFallback","type":"string"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` contractAbi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -1118,6 +1138,7 @@ func TestDoubleDuplicateMethodNames(t *testing.T) { // event send(); // } func TestDoubleDuplicateEventNames(t *testing.T) { + t.Parallel() abiJSON := `[{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "a","type": "uint256"}],"name": "send","type": "event"},{"anonymous": false,"inputs": [],"name": "send0","type": "event"},{ "anonymous": false, "inputs": [],"name": "send","type": "event"}]` contractAbi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -1145,6 +1166,7 @@ func TestDoubleDuplicateEventNames(t *testing.T) { // event send(uint256, uint256); // } func TestUnnamedEventParam(t *testing.T) { + t.Parallel() abiJSON := `[{ "anonymous": false, "inputs": [{ "indexed": false,"internalType": "uint256", "name": "","type": "uint256"},{"indexed": false,"internalType": "uint256","name": "","type": "uint256"}],"name": "send","type": "event"}]` contractAbi, err := JSON(strings.NewReader(abiJSON)) if err != nil { @@ -1178,7 +1200,9 @@ func TestUnpackRevert(t *testing.T) { {"4e487b7100000000000000000000000000000000000000000000000000000000000000ff", "unknown panic code: 0xff", nil}, } for index, c := range cases { + index, c := index, c t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) { + t.Parallel() got, err := UnpackRevert(common.Hex2Bytes(c.input)) if c.expectErr != nil { if err == nil { diff --git a/accounts/abi/abifuzzer_test.go b/accounts/abi/abifuzzer_test.go index 4b67947815..dbf6ab6c54 100644 --- a/accounts/abi/abifuzzer_test.go +++ b/accounts/abi/abifuzzer_test.go @@ -28,6 +28,7 @@ import ( // TestReplicate can be used to replicate crashers from the fuzzing tests. // Just replace testString with the data in .quoted func TestReplicate(t *testing.T) { + t.Parallel() //t.Skip("Test only useful for reproducing issues") fuzzAbi([]byte("\x20\x20\x20\x20\x20\x20\x20\x20\x80\x00\x00\x00\x20\x20\x20\x20\x00")) //fuzzAbi([]byte("asdfasdfkadsf;lasdf;lasd;lfk")) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index fa48635807..4ffdf7a77f 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -38,6 +38,7 @@ import ( ) func TestSimulatedBackend(t *testing.T) { + t.Parallel() var gasLimit uint64 = 8000029 key, _ := crypto.GenerateKey() // nolint: gosec auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) @@ -127,6 +128,7 @@ func simTestBackend(testAddr common.Address) *SimulatedBackend { } func TestNewSimulatedBackend(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(100000000000000000) sim := simTestBackend(testAddr) @@ -140,6 +142,7 @@ func TestNewSimulatedBackend(t *testing.T) { } func TestAdjustTime(t *testing.T) { + t.Parallel() sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -157,6 +160,7 @@ func TestAdjustTime(t *testing.T) { } func TestNewAdjustTimeFail(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -200,6 +204,7 @@ func TestNewAdjustTimeFail(t *testing.T) { } func TestBalanceAt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) expectedBal := big.NewInt(100000000000000000) sim := simTestBackend(testAddr) @@ -217,6 +222,7 @@ func TestBalanceAt(t *testing.T) { } func TestBlockByHash(t *testing.T) { + t.Parallel() sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -238,6 +244,7 @@ func TestBlockByHash(t *testing.T) { } func TestBlockByNumber(t *testing.T) { + t.Parallel() sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, ) @@ -273,6 +280,7 @@ func TestBlockByNumber(t *testing.T) { } func TestNonceAt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -326,6 +334,7 @@ func TestNonceAt(t *testing.T) { } func TestSendTransaction(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -360,6 +369,7 @@ func TestSendTransaction(t *testing.T) { } func TestTransactionByHash(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -410,6 +420,7 @@ func TestTransactionByHash(t *testing.T) { } func TestEstimateGas(t *testing.T) { + t.Parallel() /* pragma solidity ^0.6.4; contract GasEstimation { @@ -531,6 +542,7 @@ func TestEstimateGas(t *testing.T) { } func TestEstimateGasWithPrice(t *testing.T) { + t.Parallel() key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) @@ -589,6 +601,7 @@ func TestEstimateGasWithPrice(t *testing.T) { } func TestHeaderByHash(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -610,6 +623,7 @@ func TestHeaderByHash(t *testing.T) { } func TestHeaderByNumber(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -656,6 +670,7 @@ func TestHeaderByNumber(t *testing.T) { } func TestTransactionCount(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -709,6 +724,7 @@ func TestTransactionCount(t *testing.T) { } func TestTransactionInBlock(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -775,6 +791,7 @@ func TestTransactionInBlock(t *testing.T) { } func TestPendingNonceAt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -840,6 +857,7 @@ func TestPendingNonceAt(t *testing.T) { } func TestTransactionReceipt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) @@ -874,6 +892,7 @@ func TestTransactionReceipt(t *testing.T) { } func TestSuggestGasPrice(t *testing.T) { + t.Parallel() sim := NewSimulatedBackend( core.GenesisAlloc{}, 10000000, @@ -894,6 +913,7 @@ func TestSuggestGasPrice(t *testing.T) { } func TestPendingCodeAt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -930,6 +950,7 @@ func TestPendingCodeAt(t *testing.T) { } func TestCodeAt(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -967,6 +988,7 @@ func TestCodeAt(t *testing.T) { } func TestCodeAtHash(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1007,6 +1029,7 @@ func TestCodeAtHash(t *testing.T) { // // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} func TestPendingAndCallContract(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1109,6 +1132,7 @@ contract Reverter { } */ func TestCallContractRevert(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1204,6 +1228,7 @@ func TestCallContractRevert(t *testing.T) { // Since Commit() was called 2n+1 times in total, // having a chain length of just n+1 means that a reorg occurred. func TestFork(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1257,6 +1282,7 @@ const callableBin = "6080604052348015600f57600080fd5b5060998061001e6000396000f3f // 9. Re-send the transaction and mine a block. // 10. Check that the event was reborn. func TestForkLogsReborn(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1330,6 +1356,7 @@ func TestForkLogsReborn(t *testing.T) { // 5. Mine a block, Re-send the transaction and mine another one. // 6. Check that the TX is now included in block 2. func TestForkResendTx(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1366,6 +1393,7 @@ func TestForkResendTx(t *testing.T) { } func TestCommitReturnValue(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() @@ -1407,6 +1435,7 @@ func TestCommitReturnValue(t *testing.T) { // TestAdjustTimeAfterFork ensures that after a fork, AdjustTime uses the pending fork // block's parent rather than the canonical head's parent. func TestAdjustTimeAfterFork(t *testing.T) { + t.Parallel() testAddr := crypto.PubkeyToAddress(testKey.PublicKey) sim := simTestBackend(testAddr) defer sim.Close() diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 200686b547..2780583c6d 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -135,6 +135,7 @@ func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethe } func TestPassingBlockNumber(t *testing.T) { + t.Parallel() mc := &mockPendingCaller{ mockCaller: &mockCaller{ codeAtBytes: []byte{1, 2, 3}, @@ -171,7 +172,153 @@ func TestPassingBlockNumber(t *testing.T) { } } +const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158" + +func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { + t.Parallel() + hash := crypto.Keccak256Hash([]byte("testName")) + topics := []common.Hash{ + crypto.Keccak256Hash([]byte("received(string,address,uint256,bytes)")), + hash, + } + mockLog := newMockLog(topics, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + expectedReceivedMap := map[string]interface{}{ + "name": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + +func TestUnpackAnonymousLogIntoMap(t *testing.T) { + t.Parallel() + mockLog := newMockLog(nil, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + var received map[string]interface{} + err := bc.UnpackLogIntoMap(received, "received", mockLog) + if err == nil { + t.Error("unpacking anonymous event is not supported") + } + if err.Error() != "no event signature" { + t.Errorf("expected error 'no event signature', got '%s'", err) + } +} + +func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { + t.Parallel() + sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) + if err != nil { + t.Fatal(err) + } + hash := crypto.Keccak256Hash(sliceBytes) + topics := []common.Hash{ + crypto.Keccak256Hash([]byte("received(string[],address,uint256,bytes)")), + hash, + } + mockLog := newMockLog(topics, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + expectedReceivedMap := map[string]interface{}{ + "names": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + +func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { + t.Parallel() + arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")}) + if err != nil { + t.Fatal(err) + } + hash := crypto.Keccak256Hash(arrBytes) + topics := []common.Hash{ + crypto.Keccak256Hash([]byte("received(address[2],address,uint256,bytes)")), + hash, + } + mockLog := newMockLog(topics, common.HexToHash("0x0")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + expectedReceivedMap := map[string]interface{}{ + "addresses": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + +func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { + t.Parallel() + mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2") + addrBytes := mockAddress.Bytes() + hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)")) + functionSelector := hash[:4] + functionTyBytes := append(addrBytes, functionSelector...) + var functionTy [24]byte + copy(functionTy[:], functionTyBytes[0:24]) + topics := []common.Hash{ + crypto.Keccak256Hash([]byte("received(function,address,uint256,bytes)")), + common.BytesToHash(functionTyBytes), + } + mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + expectedReceivedMap := map[string]interface{}{ + "function": functionTy, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + +func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { + t.Parallel() + bytes := []byte{1, 2, 3, 4, 5} + hash := crypto.Keccak256Hash(bytes) + topics := []common.Hash{ + crypto.Keccak256Hash([]byte("received(bytes,address,uint256,bytes)")), + hash, + } + mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) + + abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` + parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) + bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) + + expectedReceivedMap := map[string]interface{}{ + "content": hash, + "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), + "amount": big.NewInt(1), + "memo": []byte{88}, + } + unpackAndCheck(t, bc, expectedReceivedMap, mockLog) +} + + func TestTransactGasFee(t *testing.T) { + t.Parallel() assert := assert.New(t) // GasTipCap and GasFeeCap @@ -216,144 +363,6 @@ func TestTransactGasFee(t *testing.T) { assert.True(mt.suggestGasPriceCalled) } -const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158" - -func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { - hash := crypto.Keccak256Hash([]byte("testName")) - topics := []common.Hash{ - crypto.Keccak256Hash([]byte("received(string,address,uint256,bytes)")), - hash, - } - mockLog := newMockLog(topics, common.HexToHash("0x0")) - - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - expectedReceivedMap := map[string]interface{}{ - "name": hash, - "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), - "amount": big.NewInt(1), - "memo": []byte{88}, - } - unpackAndCheck(t, bc, expectedReceivedMap, mockLog) -} - -func TestUnpackAnonymousLogIntoMap(t *testing.T) { - mockLog := newMockLog(nil, common.HexToHash("0x0")) - - abiString := `[{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - var received map[string]interface{} - err := bc.UnpackLogIntoMap(received, "received", mockLog) - if err == nil { - t.Error("unpacking anonymous event is not supported") - } - if err.Error() != "no event signature" { - t.Errorf("expected error 'no event signature', got '%s'", err) - } -} - -func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { - sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) - if err != nil { - t.Fatal(err) - } - hash := crypto.Keccak256Hash(sliceBytes) - topics := []common.Hash{ - crypto.Keccak256Hash([]byte("received(string[],address,uint256,bytes)")), - hash, - } - mockLog := newMockLog(topics, common.HexToHash("0x0")) - - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - expectedReceivedMap := map[string]interface{}{ - "names": hash, - "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), - "amount": big.NewInt(1), - "memo": []byte{88}, - } - unpackAndCheck(t, bc, expectedReceivedMap, mockLog) -} - -func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { - arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")}) - if err != nil { - t.Fatal(err) - } - hash := crypto.Keccak256Hash(arrBytes) - topics := []common.Hash{ - crypto.Keccak256Hash([]byte("received(address[2],address,uint256,bytes)")), - hash, - } - mockLog := newMockLog(topics, common.HexToHash("0x0")) - - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - expectedReceivedMap := map[string]interface{}{ - "addresses": hash, - "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), - "amount": big.NewInt(1), - "memo": []byte{88}, - } - unpackAndCheck(t, bc, expectedReceivedMap, mockLog) -} - -func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { - mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2") - addrBytes := mockAddress.Bytes() - hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)")) - functionSelector := hash[:4] - functionTyBytes := append(addrBytes, functionSelector...) - var functionTy [24]byte - copy(functionTy[:], functionTyBytes[0:24]) - topics := []common.Hash{ - crypto.Keccak256Hash([]byte("received(function,address,uint256,bytes)")), - common.BytesToHash(functionTyBytes), - } - mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - expectedReceivedMap := map[string]interface{}{ - "function": functionTy, - "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), - "amount": big.NewInt(1), - "memo": []byte{88}, - } - unpackAndCheck(t, bc, expectedReceivedMap, mockLog) -} - -func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { - bytes := []byte{1, 2, 3, 4, 5} - hash := crypto.Keccak256Hash(bytes) - topics := []common.Hash{ - crypto.Keccak256Hash([]byte("received(bytes,address,uint256,bytes)")), - hash, - } - mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) - - abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]` - parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) - bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) - - expectedReceivedMap := map[string]interface{}{ - "content": hash, - "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), - "amount": big.NewInt(1), - "memo": []byte{88}, - } - unpackAndCheck(t, bc, expectedReceivedMap, mockLog) -} - func unpackAndCheck(t *testing.T, bc *bind.BoundContract, expected map[string]interface{}, mockLog types.Log) { received := make(map[string]interface{}) if err := bc.UnpackLogIntoMap(received, "received", mockLog); err != nil { @@ -385,6 +394,7 @@ func newMockLog(topics []common.Hash, txHash common.Hash) types.Log { } func TestCall(t *testing.T) { + t.Parallel() var method, methodWithArg = "something", "somethingArrrrg" tests := []struct { name, method string @@ -560,6 +570,7 @@ func TestCall(t *testing.T) { // TestCrashers contains some strings which previously caused the abi codec to crash. func TestCrashers(t *testing.T) { + t.Parallel() abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"_1"}]}]}]`)) abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"&"}]}]}]`)) abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"----"}]}]}]`)) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 4bbc4feb6a..22b7f41d3a 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -2020,6 +2020,7 @@ var bindTests = []struct { // Tests that packages generated by the binder can be successfully compiled and // the requested tester run against it. func TestGolangBindings(t *testing.T) { + t.Parallel() // Skip the test if no Go command can be found gocmd := runtime.GOROOT() + "/bin/go" if !common.FileExist(gocmd) { diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 6e4f8cc13f..cf50ec4737 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -54,6 +54,7 @@ var waitDeployedTests = map[string]struct { } func TestWaitDeployed(t *testing.T) { + t.Parallel() config := *params.TestXDPoSMockChainConfig config.Eip1559Block = big.NewInt(0) for name, test := range waitDeployedTests { @@ -104,6 +105,7 @@ func TestWaitDeployed(t *testing.T) { } func TestWaitDeployedCornerCases(t *testing.T) { + t.Parallel() config := *params.TestXDPoSMockChainConfig config.Eip1559Block = big.NewInt(0) backend := backends.NewXDCSimulatedBackend( diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 7181026607..ed22bf9905 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -81,6 +81,7 @@ var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241" func TestEventId(t *testing.T) { + t.Parallel() var table = []struct { definition string expectations map[string]common.Hash @@ -112,6 +113,7 @@ func TestEventId(t *testing.T) { } func TestEventString(t *testing.T) { + t.Parallel() var table = []struct { definition string expectations map[string]string @@ -146,6 +148,7 @@ func TestEventString(t *testing.T) { // TestEventMultiValueWithArrayUnpack verifies that array fields will be counted after parsing array. func TestEventMultiValueWithArrayUnpack(t *testing.T) { + t.Parallel() definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": false, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` abi, err := JSON(strings.NewReader(definition)) require.NoError(t, err) @@ -161,6 +164,7 @@ func TestEventMultiValueWithArrayUnpack(t *testing.T) { } func TestEventTupleUnpack(t *testing.T) { + t.Parallel() type EventTransfer struct { Value *big.Int } @@ -351,6 +355,7 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass // TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder. func TestEventUnpackIndexed(t *testing.T) { + t.Parallel() definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]` type testStruct struct { Value1 uint8 // indexed @@ -368,6 +373,7 @@ func TestEventUnpackIndexed(t *testing.T) { // TestEventIndexedWithArrayUnpack verifies that decoder will not overflow when static array is indexed input. func TestEventIndexedWithArrayUnpack(t *testing.T) { + t.Parallel() definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8[2]"},{"indexed": false, "name":"value2", "type":"string"}]}]` type testStruct struct { Value1 [2]uint8 // indexed diff --git a/accounts/abi/method_test.go b/accounts/abi/method_test.go index f3dbe52d18..d0d81db216 100644 --- a/accounts/abi/method_test.go +++ b/accounts/abi/method_test.go @@ -35,6 +35,7 @@ const methoddata = ` ]` func TestMethodString(t *testing.T) { + t.Parallel() var table = []struct { method string expectation string @@ -99,6 +100,7 @@ func TestMethodString(t *testing.T) { } func TestMethodSig(t *testing.T) { + t.Parallel() var cases = []struct { method string expect string diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index bdb85d9d70..90f1348c50 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -32,8 +32,11 @@ import ( // TestPack tests the general pack/unpack tests in packing_test.go func TestPack(t *testing.T) { + t.Parallel() for i, test := range packUnpackTests { + i, test := i, test t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Parallel() encb, err := hex.DecodeString(test.packed) if err != nil { t.Fatalf("invalid hex %s: %v", test.packed, err) @@ -57,6 +60,7 @@ func TestPack(t *testing.T) { } func TestMethodPack(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) if err != nil { t.Fatal(err) @@ -177,6 +181,7 @@ func TestMethodPack(t *testing.T) { } func TestPackNumber(t *testing.T) { + t.Parallel() tests := []struct { value reflect.Value packed []byte diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index 76ef1ad2aa..6c7ae57087 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -170,8 +170,11 @@ var reflectTests = []reflectTest{ } func TestReflectNameToStruct(t *testing.T) { + t.Parallel() for _, test := range reflectTests { + test := test t.Run(test.name, func(t *testing.T) { + t.Parallel() m, err := mapArgNamesToStructFields(test.args, reflect.ValueOf(test.struc)) if len(test.err) > 0 { if err == nil || err.Error() != test.err { @@ -192,6 +195,7 @@ func TestReflectNameToStruct(t *testing.T) { } func TestConvertType(t *testing.T) { + t.Parallel() // Test Basic Struct type T struct { X *big.Int diff --git a/accounts/abi/topics_test.go b/accounts/abi/topics_test.go index 1ebf3eb7c2..44c1651c46 100644 --- a/accounts/abi/topics_test.go +++ b/accounts/abi/topics_test.go @@ -26,6 +26,7 @@ import ( ) func TestMakeTopics(t *testing.T) { + t.Parallel() type args struct { query [][]interface{} } @@ -117,7 +118,9 @@ func TestMakeTopics(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() got, err := MakeTopics(tt.args.query...) if (err != nil) != tt.wantErr { t.Errorf("makeTopics() error = %v, wantErr %v", err, tt.wantErr) @@ -347,10 +350,13 @@ func setupTopicsTests() []topicTest { } func TestParseTopics(t *testing.T) { + t.Parallel() tests := setupTopicsTests() for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() 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) @@ -364,10 +370,13 @@ func TestParseTopics(t *testing.T) { } func TestParseTopicsIntoMap(t *testing.T) { + t.Parallel() tests := setupTopicsTests() for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { + t.Parallel() 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) diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index cd2577b793..2b43fd7f8b 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -31,6 +31,7 @@ type typeWithoutStringer Type // Tests that all allowed types get recognized by the type parser. func TestTypeRegexp(t *testing.T) { + t.Parallel() tests := []struct { blob string components []ArgumentMarshaling @@ -117,6 +118,7 @@ func TestTypeRegexp(t *testing.T) { } func TestTypeCheck(t *testing.T) { + t.Parallel() for i, test := range []struct { typ string components []ArgumentMarshaling @@ -308,6 +310,7 @@ func TestTypeCheck(t *testing.T) { } func TestInternalType(t *testing.T) { + t.Parallel() components := []ArgumentMarshaling{{Name: "a", Type: "int64"}} internalType := "struct a.b[]" kind := Type{ @@ -332,6 +335,7 @@ func TestInternalType(t *testing.T) { } func TestGetTypeSize(t *testing.T) { + t.Parallel() var testCases = []struct { typ string components []ArgumentMarshaling @@ -368,6 +372,7 @@ func TestGetTypeSize(t *testing.T) { } func TestNewFixedBytesOver32(t *testing.T) { + t.Parallel() _, err := NewType("bytes4096", "", nil) if err == nil { t.Errorf("fixed bytes with size over 32 is not spec'd") diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index b27311ae0b..31f2067baa 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -33,6 +33,7 @@ import ( // TestUnpack tests the general pack/unpack tests in packing_test.go func TestUnpack(t *testing.T) { + t.Parallel() for i, test := range packUnpackTests { t.Run(strconv.Itoa(i)+" "+test.def, func(t *testing.T) { //Unpack @@ -224,6 +225,7 @@ var unpackTests = []unpackTest{ // TestLocalUnpackTests runs test specially designed only for unpacking. // All test cases that can be used to test packing and unpacking should move to packing_test.go func TestLocalUnpackTests(t *testing.T) { + t.Parallel() for i, test := range unpackTests { t.Run(strconv.Itoa(i), func(t *testing.T) { //Unpack @@ -251,6 +253,7 @@ func TestLocalUnpackTests(t *testing.T) { } func TestUnpackIntoInterfaceSetDynamicArrayOutput(t *testing.T) { + t.Parallel() abi, err := JSON(strings.NewReader(`[{"constant":true,"inputs":[],"name":"testDynamicFixedBytes15","outputs":[{"name":"","type":"bytes15[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"testDynamicFixedBytes32","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"}]`)) if err != nil { t.Fatal(err) @@ -321,6 +324,7 @@ func methodMultiReturn(require *require.Assertions) (ABI, []byte, methodMultiOut } func TestMethodMultiReturn(t *testing.T) { + t.Parallel() type reversed struct { String string Int *big.Int @@ -400,6 +404,7 @@ func TestMethodMultiReturn(t *testing.T) { } func TestMultiReturnWithArray(t *testing.T) { + t.Parallel() const definition = `[{"name" : "multi", "type": "function", "outputs": [{"type": "uint64[3]"}, {"type": "uint64"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { @@ -423,6 +428,7 @@ func TestMultiReturnWithArray(t *testing.T) { } func TestMultiReturnWithStringArray(t *testing.T) { + t.Parallel() const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "uint256[3]"},{"name": "","type": "address"},{"name": "","type": "string[2]"},{"name": "","type": "bool"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { @@ -453,6 +459,7 @@ func TestMultiReturnWithStringArray(t *testing.T) { } func TestMultiReturnWithStringSlice(t *testing.T) { + t.Parallel() const definition = `[{"name" : "multi", "type": "function", "outputs": [{"name": "","type": "string[]"},{"name": "","type": "uint256[]"}]}]` abi, err := JSON(strings.NewReader(definition)) if err != nil { @@ -485,6 +492,7 @@ func TestMultiReturnWithStringSlice(t *testing.T) { } func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { + t.Parallel() // Similar to TestMultiReturnWithArray, but with a special case in mind: // values of nested static arrays count towards the size as well, and any element following // after such nested array argument should be read with the correct offset, @@ -525,6 +533,7 @@ func TestMultiReturnWithDeeplyNestedArray(t *testing.T) { } func TestUnmarshal(t *testing.T) { + t.Parallel() const definition = `[ { "name" : "int", "type": "function", "outputs": [ { "type": "uint256" } ] }, { "name" : "bool", "type": "function", "outputs": [ { "type": "bool" } ] }, @@ -774,6 +783,7 @@ func TestUnmarshal(t *testing.T) { } func TestUnpackTuple(t *testing.T) { + t.Parallel() const simpleTuple = `[{"name":"tuple","type":"function","outputs":[{"type":"tuple","name":"ret","components":[{"type":"int256","name":"a"},{"type":"int256","name":"b"}]}]}]` abi, err := JSON(strings.NewReader(simpleTuple)) if err != nil { @@ -876,6 +886,7 @@ func TestUnpackTuple(t *testing.T) { } func TestOOMMaliciousInput(t *testing.T) { + t.Parallel() oomTests := []unpackTest{ { def: `[{"type": "uint8[]"}]`, @@ -946,6 +957,7 @@ func TestOOMMaliciousInput(t *testing.T) { } func TestPackAndUnpackIncompatibleNumber(t *testing.T) { + t.Parallel() var encodeABI Arguments uint256Ty, err := NewType("uint256", "", nil) if err != nil { diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go index babbbc85c5..caee0a4d7d 100644 --- a/accounts/accounts_test.go +++ b/accounts/accounts_test.go @@ -24,6 +24,7 @@ import ( ) func TestTextHash(t *testing.T) { + t.Parallel() hash := TextHash([]byte("Hello Joe")) want := hexutil.MustDecode("0xa080337ae51c4e064c189e113edd0ba391df9206e2f49db658bb32cf2911730b") if !bytes.Equal(hash, want) { diff --git a/accounts/hd_test.go b/accounts/hd_test.go index 0743bbe666..118ec5187b 100644 --- a/accounts/hd_test.go +++ b/accounts/hd_test.go @@ -25,6 +25,7 @@ import ( // Tests that HD derivation paths can be correctly parsed into our internal binary // representation. func TestHDPathParsing(t *testing.T) { + t.Parallel() tests := []struct { input string output DerivationPath @@ -89,6 +90,7 @@ func testDerive(t *testing.T, next func() DerivationPath, expected []string) { } func TestHdPathIteration(t *testing.T) { + t.Parallel() testDerive(t, DefaultIterator(DefaultBaseDerivationPath), []string{ "m/44'/60'/0'/0/0", "m/44'/60'/0'/0/1", diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 3e684e6a0e..4d68d48320 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -152,6 +152,7 @@ func TestWatchNoDir(t *testing.T) { } func TestCacheInitialReload(t *testing.T) { + t.Parallel() cache, _ := newAccountCache(cachetestDir) accounts := cache.accounts() if !reflect.DeepEqual(accounts, cachetestAccounts) { @@ -160,6 +161,7 @@ func TestCacheInitialReload(t *testing.T) { } func TestCacheAddDeleteOrder(t *testing.T) { + t.Parallel() cache, _ := newAccountCache("testdata/no-such-dir") cache.watcher.running = true // prevent unexpected reloads @@ -244,6 +246,7 @@ func TestCacheAddDeleteOrder(t *testing.T) { } func TestCacheFind(t *testing.T) { + t.Parallel() dir := filepath.Join("testdata", "dir") cache, _ := newAccountCache(dir) cache.watcher.running = true // prevent unexpected reloads diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 265ceb927c..0762a95582 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -36,6 +36,7 @@ import ( var testSigData = make([]byte, 32) func TestKeyStore(t *testing.T) { + t.Parallel() dir, ks := tmpKeyStore(t, true) a, err := ks.NewAccount("foo") @@ -70,6 +71,7 @@ func TestKeyStore(t *testing.T) { } func TestSign(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) pass := "" // not used but required by API @@ -86,6 +88,7 @@ func TestSign(t *testing.T) { } func TestSignWithPassphrase(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) pass := "passwd" @@ -280,6 +283,7 @@ type walletEvent struct { // Tests that wallet notifications and correctly fired when accounts are added // or deleted from the keystore. func TestWalletNotifications(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, false) // Subscribe to the wallet feed and collect events. @@ -341,6 +345,7 @@ func TestWalletNotifications(t *testing.T) { // TestImportECDSA tests the import functionality of a keystore. func TestImportECDSA(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) key, err := crypto.GenerateKey() if err != nil { @@ -359,6 +364,7 @@ func TestImportECDSA(t *testing.T) { // TestImportExport tests the import and export functionality of a keystore. func TestImportExport(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) acc, err := ks.NewAccount("old") if err != nil { @@ -388,6 +394,7 @@ func TestImportExport(t *testing.T) { // TestImportRace tests the keystore on races. // This test should fail under -race if importing races. func TestImportRace(t *testing.T) { + t.Parallel() _, ks := tmpKeyStore(t, true) acc, err := ks.NewAccount("old") if err != nil { diff --git a/accounts/keystore/passphrase_test.go b/accounts/keystore/passphrase_test.go index 748c3e822c..798e8341ec 100644 --- a/accounts/keystore/passphrase_test.go +++ b/accounts/keystore/passphrase_test.go @@ -30,6 +30,7 @@ const ( // Tests that a json key file can be decrypted and encrypted in multiple rounds. func TestKeyEncryptDecrypt(t *testing.T) { + t.Parallel() keyjson, err := os.ReadFile("testdata/very-light-scrypt.json") if err != nil { t.Fatal(err) diff --git a/accounts/keystore/plain_test.go b/accounts/keystore/plain_test.go index 97fe8d3e25..6f94d382ec 100644 --- a/accounts/keystore/plain_test.go +++ b/accounts/keystore/plain_test.go @@ -40,6 +40,7 @@ func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { } func TestKeyStorePlain(t *testing.T) { + t.Parallel() _, ks := tmpKeyStoreIface(t, false) pass := "" // not used but required by API @@ -60,6 +61,7 @@ func TestKeyStorePlain(t *testing.T) { } func TestKeyStorePassphrase(t *testing.T) { + t.Parallel() _, ks := tmpKeyStoreIface(t, true) pass := "foo" @@ -80,6 +82,7 @@ func TestKeyStorePassphrase(t *testing.T) { } func TestKeyStorePassphraseDecryptionFail(t *testing.T) { + t.Parallel() _, ks := tmpKeyStoreIface(t, true) pass := "foo" @@ -93,6 +96,7 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) { } func TestImportPreSaleKey(t *testing.T) { + t.Parallel() dir, ks := tmpKeyStoreIface(t, true) // file content of a presale key file generated with: From 8133f96d5f08d974e52d04426cc105da30da3723 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 246/280] all: fix typos in comments (#28662) Co-authored-by: Felix Lange --- accounts/abi/abi.go | 2 +- accounts/abi/bind/auth.go | 2 +- accounts/abi/bind/base.go | 4 ++-- accounts/abi/bind/bind.go | 2 +- accounts/abi/topics.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 7716206be7..bed27c21a2 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -251,7 +251,7 @@ var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4] var panicSelector = crypto.Keccak256([]byte("Panic(uint256)"))[:4] // panicReasons map is for readable panic codes -// see this linkage for the deails +// see this linkage for the details // https://docs.soliditylang.org/en/v0.8.21/control-structures.html#panic-via-assert-and-error-via-require // the reason string list is copied from ether.js // https://github.com/ethers-io/ethers.js/blob/fa3a883ff7c88611ce766f58bdd4b8ac90814470/src.ts/abi/interface.ts#L207-L218 diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 0f4279d98d..48f0601621 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -116,7 +116,7 @@ func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.I } // NewKeyStoreTransactorWithChainID is a utility method to easily create a transaction signer from -// an decrypted key from a keystore. +// a decrypted key from a keystore. func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accounts.Account, chainID *big.Int) (*TransactOpts, error) { if chainID == nil { return nil, ErrNoChainID diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 5dbe445eb2..f1bdfbbd33 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -238,7 +238,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in if err != nil { return nil, err } - // todo(rjl493456442) check the method is payable or not, + // todo(rjl493456442) check whether the method is payable or not, // reject invalid transaction at the first place return c.transact(opts, &c.address, input) } @@ -246,7 +246,7 @@ func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...in // RawTransact initiates a transaction with the given raw calldata as the input. // It's usually used to initiate transactions for invoking **Fallback** function. func (c *BoundContract) RawTransact(opts *TransactOpts, calldata []byte) (*types.Transaction, error) { - // todo(rjl493456442) check the method is payable or not, + // todo(rjl493456442) check whether the method is payable or not, // reject invalid transaction at the first place return c.transact(opts, &c.address, calldata) } diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 865f4e7ea0..92fd330406 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -79,7 +79,7 @@ func isKeyWord(arg string) bool { // Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant // to be used as is in client code, but rather as an intermediate struct which -// enforces compile time type safety and naming convention opposed to having to +// enforces compile time type safety and naming convention as opposed to having to // manually maintain hard coded strings that break on runtime. func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) { var ( diff --git a/accounts/abi/topics.go b/accounts/abi/topics.go index 119ef06d24..0865d454e0 100644 --- a/accounts/abi/topics.go +++ b/accounts/abi/topics.go @@ -75,7 +75,7 @@ func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) { copy(topic[:], hash[:]) default: - // todo(rjl493456442) according solidity documentation, indexed event + // todo(rjl493456442) according to solidity documentation, indexed event // parameters that are not value types i.e. arrays and structs are not // stored directly but instead a keccak256-hash of an encoding is stored. // From 36bf7311cd291b72e7d41f4ab20cbce7f2d09099 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 247/280] accounts: properly close managed wallets when closing manager (#28710) --- accounts/manager.go | 3 +++ accounts/usbwallet/wallet.go | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/accounts/manager.go b/accounts/manager.go index 7097cbe543..f525052c82 100644 --- a/accounts/manager.go +++ b/accounts/manager.go @@ -98,6 +98,9 @@ func NewManager(config *Config, backends ...Backend) *Manager { // Close terminates the account manager's internal notification processes. func (am *Manager) Close() error { + for _, w := range am.wallets { + w.Close() + } errc := make(chan error) am.quit <- errc return <-errc diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 4377f16af7..ca296f4cb6 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -483,6 +483,10 @@ func (w *wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun w.stateLock.Lock() defer w.stateLock.Unlock() + if w.device == nil { + return accounts.Account{}, accounts.ErrWalletClosed + } + if _, ok := w.paths[address]; !ok { w.accounts = append(w.accounts, account) w.paths[address] = make(accounts.DerivationPath, len(path)) From 0e7679dc6a800ca863dd5a6d07cad7a3cfe83713 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 248/280] accounts,signer: fix typos in comments (#28730) --- accounts/keystore/passphrase.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index eec9cdc805..c64628c6ea 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -136,7 +136,7 @@ func (ks keyStorePassphrase) JoinPath(filename string) string { return filepath.Join(ks.keysDirPath, filename) } -// Encryptdata encrypts the data given as 'data' with the password 'auth'. +// EncryptDataV3 encrypts the data given as 'data' with the password 'auth'. func EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) { salt := make([]byte, 32) if _, err := io.ReadFull(rand.Reader, salt); err != nil { From b5f6104d5dfe2400a4db154303574eb25829e644 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 249/280] accounts/abi: fix bigInt topic encoding (#28764) --- accounts/abi/topics.go | 4 ++-- accounts/abi/topics_test.go | 25 ++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/accounts/abi/topics.go b/accounts/abi/topics.go index 0865d454e0..4f347ac0ce 100644 --- a/accounts/abi/topics.go +++ b/accounts/abi/topics.go @@ -24,6 +24,7 @@ import ( "reflect" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" ) @@ -41,8 +42,7 @@ func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) { case common.Address: copy(topic[common.HashLength-common.AddressLength:], rule[:]) case *big.Int: - blob := rule.Bytes() - copy(topic[common.HashLength-len(blob):], blob) + copy(topic[:], math.U256Bytes(rule)) case bool: if rule { topic[common.HashLength-1] = 1 diff --git a/accounts/abi/topics_test.go b/accounts/abi/topics_test.go index 44c1651c46..4f97cf7155 100644 --- a/accounts/abi/topics_test.go +++ b/accounts/abi/topics_test.go @@ -17,6 +17,7 @@ package abi import ( + "math" "math/big" "reflect" "testing" @@ -55,9 +56,27 @@ func TestMakeTopics(t *testing.T) { false, }, { - "support *big.Int types in topics", - args{[][]interface{}{{big.NewInt(1).Lsh(big.NewInt(2), 254)}}}, - [][]common.Hash{{common.Hash{128}}}, + "support positive *big.Int types in topics", + args{[][]interface{}{ + {big.NewInt(1)}, + {big.NewInt(1).Lsh(big.NewInt(2), 254)}, + }}, + [][]common.Hash{ + {common.HexToHash("0000000000000000000000000000000000000000000000000000000000000001")}, + {common.Hash{128}}, + }, + false, + }, + { + "support negative *big.Int types in topics", + args{[][]interface{}{ + {big.NewInt(-1)}, + {big.NewInt(math.MinInt64)}, + }}, + [][]common.Hash{ + {common.MaxHash}, + {common.HexToHash("ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000")}, + }, false, }, { From c1913bb22a074cc7b9b98c9e68042b40cb449faa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 250/280] accounts/abi/bind/backends: replace NewSimulatedBackend with NewXDCSimulatedBackend --- accounts/abi/bind/backends/simulated.go | 2 +- accounts/abi/bind/backends/simulated_test.go | 33 ++++++++++++----- contracts/randomize/randomize_test.go | 1 + contracts/tests/Inherited_test.go | 11 ++++-- contracts/trc21issuer/trc21issuer_test.go | 38 ++++++++++++-------- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 9fde5ce863..e24636ac68 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -144,7 +144,7 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi return backend } -// NewSimulatedBackend creates a new binding backend based on the given database +// SimulOldNewSimulatedBackendatedBackend creates a new binding backend based on the given database // and uses a simulated blockchain for testing purposes. // A simulated backend always uses chainID 1337. func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 4ffdf7a77f..b8848a6e8d 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -143,8 +143,10 @@ func TestNewSimulatedBackend(t *testing.T) { func TestAdjustTime(t *testing.T) { t.Parallel() - sim := NewSimulatedBackend( - core.GenesisAlloc{}, 10000000, + sim := NewXDCSimulatedBackend( + core.GenesisAlloc{}, + 10000000, + params.TestXDPoSMockChainConfig, ) defer sim.Close() @@ -223,8 +225,10 @@ func TestBalanceAt(t *testing.T) { func TestBlockByHash(t *testing.T) { t.Parallel() - sim := NewSimulatedBackend( - core.GenesisAlloc{}, 10000000, + sim := NewXDCSimulatedBackend( + core.GenesisAlloc{}, + 10000000, + params.TestXDPoSMockChainConfig, ) defer sim.Close() bgCtx := context.Background() @@ -245,8 +249,10 @@ func TestBlockByHash(t *testing.T) { func TestBlockByNumber(t *testing.T) { t.Parallel() - sim := NewSimulatedBackend( - core.GenesisAlloc{}, 10000000, + sim := NewXDCSimulatedBackend( + core.GenesisAlloc{}, + 10000000, + params.TestXDPoSMockChainConfig, ) defer sim.Close() bgCtx := context.Background() @@ -439,7 +445,11 @@ func TestEstimateGas(t *testing.T) { // opts := bind.NewKeyedTransactor(key) opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := NewXDCSimulatedBackend( + core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, + 10000000, + params.TestXDPoSMockChainConfig, + ) defer sim.Close() parsed, _ := abi.JSON(strings.NewReader(contractAbi)) @@ -546,7 +556,11 @@ func TestEstimateGasWithPrice(t *testing.T) { key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) - sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000) + sim := NewXDCSimulatedBackend( + core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, + 10000000, + params.TestXDPoSMockChainConfig, +) defer sim.Close() recipient := common.HexToAddress("deadbeef") @@ -893,9 +907,10 @@ func TestTransactionReceipt(t *testing.T) { func TestSuggestGasPrice(t *testing.T) { t.Parallel() - sim := NewSimulatedBackend( + sim := NewXDCSimulatedBackend( core.GenesisAlloc{}, 10000000, + params.TestXDPoSMockChainConfig, ) defer sim.Close() bgCtx := context.Background() diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go index fd117681f1..08c38e375d 100644 --- a/contracts/randomize/randomize_test.go +++ b/contracts/randomize/randomize_test.go @@ -73,6 +73,7 @@ func TestRandomize(t *testing.T) { func TestSendTxRandomizeSecretAndOpening(t *testing.T) { genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} + // TODO(daniel): replace NewSimulatedBackend with NewXDCSimulatedBackend backend := backends.NewSimulatedBackend(genesis, 42000000) backend.Commit() signer := types.HomesteadSigner{} diff --git a/contracts/tests/Inherited_test.go b/contracts/tests/Inherited_test.go index a60fa6344f..da9178ad1b 100644 --- a/contracts/tests/Inherited_test.go +++ b/contracts/tests/Inherited_test.go @@ -12,6 +12,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" + "github.com/XinFinOrg/XDPoSChain/params" ) var ( @@ -26,9 +27,13 @@ func TestPriceFeed(t *testing.T) { common.TIPXDCXCancellationFee = big.NewInt(0) // init genesis - contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ - mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, - }, 42000000) + contractBackend := backends.NewXDCSimulatedBackend( + core.GenesisAlloc{ + mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, + }, + 42000000, + params.TestXDPoSMockChainConfig, + ) transactOpts := bind.NewKeyedTransactor(mainKey) // deploy payer swap SMC addr, contract, err := DeployMyInherited(transactOpts, contractBackend) diff --git a/contracts/trc21issuer/trc21issuer_test.go b/contracts/trc21issuer/trc21issuer_test.go index aeebb7b7ad..04d98f41fb 100644 --- a/contracts/trc21issuer/trc21issuer_test.go +++ b/contracts/trc21issuer/trc21issuer_test.go @@ -10,6 +10,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/params" ) var ( @@ -29,29 +30,35 @@ var ( ) func TestFeeTxWithTRC21Token(t *testing.T) { - // init genesis - contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{ - mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, - }, 42000000) + contractBackend := backends.NewXDCSimulatedBackend( + core.GenesisAlloc{ + mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, + }, + 42000000, + params.TestXDPoSMockChainConfig, + ) transactOpts := bind.NewKeyedTransactor(mainKey) + // deploy payer swap SMC trc21IssuerAddr, trc21Issuer, err := DeployTRC21Issuer(transactOpts, contractBackend, minApply) - - //set contract address to config - common.TRC21IssuerSMC = trc21IssuerAddr if err != nil { - t.Fatal("can't deploy smart contract: ", err) + t.Fatal("can't deploy TRC21Issuer contract, err:", err) } contractBackend.Commit() + + // set contract address to config + common.TRC21IssuerSMC = trc21IssuerAddr cap := big.NewInt(0).Mul(big.NewInt(10000000), big.NewInt(10000000000000)) TRC21fee := big.NewInt(100) - // deploy a TRC21 SMC + + // deploy a TRC21 SMC trc21TokenAddr, trc21, err := DeployTRC21(transactOpts, contractBackend, "TEST", "XDC", 18, cap, TRC21fee) if err != nil { - t.Fatal("can't deploy smart contract: ", err) + t.Fatal("can't deploy TRC21 contract, err:", err) } contractBackend.Commit() + // add trc21 address to list token trc21Issuer trc21Issuer.TransactOpts.Value = minApply _, err = trc21Issuer.Apply(trc21TokenAddr) @@ -60,19 +67,20 @@ func TestFeeTxWithTRC21Token(t *testing.T) { } contractBackend.Commit() - //check trc21 SMC balance + // check trc21 SMC balance balance, err := contractBackend.BalanceAt(context.TODO(), trc21IssuerAddr, nil) if err != nil || balance.Cmp(minApply) != 0 { t.Fatal("can't get balance in trc21Issuer SMC: ", err, "got", balance, "wanted", minApply) } - //check balance fee + // check balance fee balanceIssuerFee, err := trc21Issuer.GetTokenCapacity(trc21TokenAddr) if err != nil || balanceIssuerFee.Cmp(minApply) != 0 { t.Fatal("can't get balance token fee in smart contract: ", err, "got", balanceIssuerFee, "wanted", minApply) } trc21Issuer.TransactOpts.Value = big.NewInt(0) airDropAmount := big.NewInt(1000000000) + // airdrop token trc21 to a address no XDC tx, err := trc21.Transfer(airdropAddr, airDropAmount) if err != nil { @@ -100,7 +108,7 @@ func TestFeeTxWithTRC21Token(t *testing.T) { if balanceIssuerFee.Cmp(remainFee) != 0 { t.Fatal("check balance token fee in smart contract: got", balanceIssuerFee, "wanted", remainFee) } - //check trc21 SMC balance + // check trc21 SMC balance balance, err = contractBackend.BalanceAt(context.TODO(), trc21IssuerAddr, nil) if err != nil || balance.Cmp(remainFee) != 0 { t.Fatal("can't get balance token fee in smart contract: ", err, "got", balanceIssuerFee, "wanted", remainFee) @@ -137,12 +145,12 @@ func TestFeeTxWithTRC21Token(t *testing.T) { } fee = common.GetGasFee(receipt.Logs[0].BlockNumber, receipt.GasUsed) remainFee = big.NewInt(0).Sub(remainFee, fee) - //check balance fee + // check balance fee balanceIssuerFee, err = trc21Issuer.GetTokenCapacity(trc21TokenAddr) if err != nil || balanceIssuerFee.Cmp(remainFee) != 0 { t.Fatal("can't get balance token fee in smart contract: ", err, "got", balanceIssuerFee, "wanted", remainFee) } - //check trc21 SMC balance + // check trc21 SMC balance balance, err = contractBackend.BalanceAt(context.TODO(), trc21IssuerAddr, nil) if err != nil || balance.Cmp(remainFee) != 0 { t.Fatal("can't get balance token fee in smart contract: ", err, "got", balanceIssuerFee, "wanted", remainFee) From 0a0784d324a45fed9d3a235e520aaa3e1fdc75d5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 251/280] acounts/usbwallet: fix typo (#28815) acounts:fix typo --- accounts/usbwallet/ledger.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 31c8b2387c..c10eec5e0e 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -279,7 +279,7 @@ func (w *ledgerDriver) ledgerDerive(derivationPath []uint32) (common.Address, er } hexstr := reply[1 : 1+int(reply[0])] - // Decode the hex sting into an Ethereum address and return + // Decode the hex string into an Ethereum address and return var address common.Address if _, err = hex.Decode(address[:], hexstr); err != nil { return common.Address{}, err From 2dfb1cf7d304e67268443e920a15b64810f87ef8 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 252/280] accounts: fix typos (#28881) --- accounts/abi/abi.go | 2 +- accounts/scwallet/hub.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index bed27c21a2..a0f63518ab 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -29,7 +29,7 @@ import ( ) // The ABI holds information about a contract's context and available -// invokable methods. It will allow you to type check function calls and +// invocable methods. It will allow you to type check function calls and // packs data accordingly. type ABI struct { Constructor Method diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index 9f5c32570d..50b5433765 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -241,7 +241,7 @@ func (hub *Hub) refreshWallets() { card.Disconnect(pcsc.LeaveCard) continue } - // Card connected, start tracking in amongs the wallets + // Card connected, start tracking among the wallets hub.wallets[reader] = wallet events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) } From 745c276ed3670379775f9271c52db42e90edb8ff Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 253/280] fix: update outdated link to trezor docs (#28966) fix: update link to trezor --- accounts/usbwallet/trezor/trezor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/usbwallet/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go index a259c1dce9..af4d2d0d0a 100644 --- a/accounts/usbwallet/trezor/trezor.go +++ b/accounts/usbwallet/trezor/trezor.go @@ -16,7 +16,7 @@ // This file contains the implementation for interacting with the Trezor hardware // wallets. The wire protocol spec can be found on the SatoshiLabs website: -// https://wiki.trezor.io/Developers_guide-Message_Workflows +// https://docs.trezor.io/trezor-firmware/common/message-workflows.html // !!! STAHP !!! // From b6f3007af1ac9d13c23772c32b80c991293c39bc Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 254/280] core: move genesis alloc types to core/types (#29003) --- accounts/abi/bind/backends/simulated.go | 4 +- accounts/abi/bind/backends/simulated_test.go | 21 ++-- accounts/abi/bind/bind_test.go | 96 +++++++++---------- accounts/abi/bind/util_test.go | 5 +- cmd/puppeth/genesis.go | 19 ++-- cmd/puppeth/wizard_genesis.go | 21 ++-- consensus/tests/api_test.go | 4 +- consensus/tests/engine_v1_tests/helper.go | 4 +- consensus/tests/engine_v2_tests/helper.go | 8 +- contracts/blocksigner/blocksigner_test.go | 4 +- contracts/randomize/randomize_test.go | 5 +- contracts/tests/Inherited_test.go | 4 +- contracts/trc21issuer/trc21issuer_test.go | 4 +- contracts/utils_test.go | 3 +- contracts/validator/validator_test.go | 9 +- core/bench_test.go | 5 +- core/blockchain_test.go | 18 ++-- core/chain_makers_test.go | 2 +- core/gen_genesis.go | 9 +- core/genesis.go | 85 ++++------------ core/genesis_test.go | 6 +- core/state_processor_test.go | 8 +- core/types/account.go | 88 +++++++++++++++++ .../gen_account.go} | 44 ++++----- eth/filters/filter_system_test.go | 2 +- eth/gasprice/gasprice_test.go | 2 +- eth/helper_test.go | 2 +- eth/tracers/tracers_test.go | 18 ++-- les/helper_test.go | 2 +- light/odr_test.go | 2 +- light/trie_test.go | 3 +- light/txpool_test.go | 2 +- tests/block_test_util.go | 4 +- tests/state_test_util.go | 4 +- tests/vm_test_util.go | 5 +- 35 files changed, 279 insertions(+), 243 deletions(-) create mode 100644 core/types/account.go rename core/{gen_genesis_account.go => types/gen_account.go} (61%) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index e24636ac68..3f73d01cf2 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -102,7 +102,7 @@ func SimulateWalletAddressAndSignFn() (common.Address, func(account accounts.Acc } // NewXDCSimulatedBackend creates a new backend for testing purpose. -func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfig *params.ChainConfig) *SimulatedBackend { +func NewXDCSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64, chainConfig *params.ChainConfig) *SimulatedBackend { database := rawdb.NewMemoryDatabase() genesis := core.Genesis{ GasLimit: gasLimit, // need this big, support initial smart contract @@ -147,7 +147,7 @@ func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfi // SimulOldNewSimulatedBackendatedBackend creates a new binding backend based on the given database // and uses a simulated blockchain for testing purposes. // A simulated backend always uses chainID 1337. -func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { +func NewSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBackend { database := rawdb.NewMemoryDatabase() genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc} genesis.MustCommit(database) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index b8848a6e8d..187582fd89 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -31,7 +31,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -42,8 +41,8 @@ func TestSimulatedBackend(t *testing.T) { var gasLimit uint64 = 8000029 key, _ := crypto.GenerateKey() // nolint: gosec auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - genAlloc := make(core.GenesisAlloc) - genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)} + genAlloc := make(types.GenesisAlloc) + genAlloc[auth.From] = types.Account{Balance: big.NewInt(9223372036854775807)} config := *params.TestXDPoSMockChainConfig config.Eip1559Block = big.NewInt(0) @@ -119,7 +118,7 @@ func simTestBackend(testAddr common.Address) *SimulatedBackend { config := *params.TestXDPoSMockChainConfig config.Eip1559Block = big.NewInt(0) return NewXDCSimulatedBackend( - core.GenesisAlloc{ + types.GenesisAlloc{ testAddr: {Balance: big.NewInt(100000000000000000)}, }, 10000000, @@ -144,7 +143,7 @@ func TestNewSimulatedBackend(t *testing.T) { func TestAdjustTime(t *testing.T) { t.Parallel() sim := NewXDCSimulatedBackend( - core.GenesisAlloc{}, + types.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig, ) @@ -226,7 +225,7 @@ func TestBalanceAt(t *testing.T) { func TestBlockByHash(t *testing.T) { t.Parallel() sim := NewXDCSimulatedBackend( - core.GenesisAlloc{}, + types.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig, ) @@ -250,7 +249,7 @@ func TestBlockByHash(t *testing.T) { func TestBlockByNumber(t *testing.T) { t.Parallel() sim := NewXDCSimulatedBackend( - core.GenesisAlloc{}, + types.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig, ) @@ -446,7 +445,7 @@ func TestEstimateGas(t *testing.T) { opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) sim := NewXDCSimulatedBackend( - core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, + types.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether)}}, 10000000, params.TestXDPoSMockChainConfig, ) @@ -557,10 +556,10 @@ func TestEstimateGasWithPrice(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) sim := NewXDCSimulatedBackend( - core.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, + types.GenesisAlloc{addr: {Balance: big.NewInt(params.Ether*2 + 2e17)}}, 10000000, params.TestXDPoSMockChainConfig, -) + ) defer sim.Close() recipient := common.HexToAddress("deadbeef") @@ -908,7 +907,7 @@ func TestTransactionReceipt(t *testing.T) { func TestSuggestGasPrice(t *testing.T) { t.Parallel() sim := NewXDCSimulatedBackend( - core.GenesisAlloc{}, + types.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig, ) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 22b7f41d3a..3bd3d86948 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -290,7 +290,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -299,7 +299,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy an interaction tester contract and call a transaction on it @@ -346,7 +346,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -355,7 +355,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a tuple tester contract and execute a structured call on it @@ -393,7 +393,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -402,7 +402,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a tuple tester contract and execute a structured call on it @@ -452,7 +452,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -461,7 +461,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a slice tester contract and execute a n array call on it @@ -501,7 +501,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -510,7 +510,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a default method invoker contract and execute its default method @@ -568,7 +568,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -577,7 +577,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a structs method invoker contract and execute its default method @@ -615,12 +615,12 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" `, ` // Create a simulator and wrap a non-deployed contract - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000), params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{}, uint64(10000000000), params.TestXDPoSMockChainConfig) defer sim.Close() nonexistent, err := NewNonExistent(common.Address{}, sim) @@ -654,12 +654,12 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" `, ` // Create a simulator and wrap a non-deployed contract - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() nonexistent, err := NewNonExistentStruct(common.Address{}, sim) @@ -701,7 +701,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -710,7 +710,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a funky gas pattern contract @@ -753,7 +753,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -762,7 +762,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a sender tester contract and execute a structured call on it @@ -830,7 +830,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -838,7 +838,7 @@ var bindTests = []struct { // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a underscorer tester contract and execute a structured call on it @@ -924,7 +924,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -933,7 +933,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy an eventer contract @@ -1115,7 +1115,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1124,7 +1124,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() //deploy the test contract @@ -1253,7 +1253,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1262,7 +1262,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() _, _, contract, err := DeployTuple(auth, sim) @@ -1393,7 +1393,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1402,7 +1402,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // deploy the test contract @@ -1484,7 +1484,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" `, ` @@ -1493,7 +1493,7 @@ var bindTests = []struct { addr := crypto.PubkeyToAddress(key.PublicKey) // Deploy registrar contract - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) @@ -1548,7 +1548,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" `, ` @@ -1556,7 +1556,7 @@ var bindTests = []struct { addr := crypto.PubkeyToAddress(key.PublicKey) // Deploy registrar contract - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) @@ -1610,7 +1610,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1619,7 +1619,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() // Deploy a tester contract and execute a structured call on it @@ -1672,7 +1672,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1680,7 +1680,7 @@ var bindTests = []struct { key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) - sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(10000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) defer sim.Close() opts, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) @@ -1761,7 +1761,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1769,7 +1769,7 @@ var bindTests = []struct { var ( key, _ = crypto.GenerateKey() user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim = backends.NewXDCSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) ) defer sim.Close() @@ -1831,7 +1831,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1839,7 +1839,7 @@ var bindTests = []struct { var ( key, _ = crypto.GenerateKey() user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim = backends.NewXDCSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) ) defer sim.Close() @@ -1883,7 +1883,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1891,7 +1891,7 @@ var bindTests = []struct { var ( key, _ = crypto.GenerateKey() user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim = backends.NewXDCSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) ) defer sim.Close() @@ -1931,7 +1931,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1939,7 +1939,7 @@ var bindTests = []struct { var ( key, _ = crypto.GenerateKey() user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim = backends.NewXDCSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) ) defer sim.Close() @@ -1971,7 +1971,7 @@ var bindTests = []struct { "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" `, @@ -1979,7 +1979,7 @@ var bindTests = []struct { var ( key, _ = crypto.GenerateKey() user, _ = bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) - sim = backends.NewXDCSimulatedBackend(core.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + sim = backends.NewXDCSimulatedBackend(types.GenesisAlloc{user.From: {Balance: big.NewInt(1000000000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) ) _, tx, _, err := DeployRangeKeyword(user, sim) if err != nil { diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index cf50ec4737..89deb2c559 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -26,7 +26,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -59,7 +58,7 @@ func TestWaitDeployed(t *testing.T) { config.Eip1559Block = big.NewInt(0) for name, test := range waitDeployedTests { backend := backends.NewXDCSimulatedBackend( - core.GenesisAlloc{ + types.GenesisAlloc{ crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(100000000000000000)}, }, 10000000, @@ -109,7 +108,7 @@ func TestWaitDeployedCornerCases(t *testing.T) { config := *params.TestXDPoSMockChainConfig config.Eip1559Block = big.NewInt(0) backend := backends.NewXDCSimulatedBackend( - core.GenesisAlloc{ + types.GenesisAlloc{ crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(100000000000000000)}, }, 10000000, diff --git a/cmd/puppeth/genesis.go b/cmd/puppeth/genesis.go index 6aef1cf27e..a27891ced0 100644 --- a/cmd/puppeth/genesis.go +++ b/cmd/puppeth/genesis.go @@ -25,6 +25,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" ) @@ -344,15 +345,15 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin // pyEthereumGenesisSpec represents the genesis specification format used by the // Python Ethereum implementation. type pyEthereumGenesisSpec struct { - Nonce hexutil.Bytes `json:"nonce"` - Timestamp hexutil.Uint64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit hexutil.Uint64 `json:"gasLimit"` - Difficulty *hexutil.Big `json:"difficulty"` - Mixhash common.Hash `json:"mixhash"` - Coinbase common.Address `json:"coinbase"` - Alloc core.GenesisAlloc `json:"alloc"` - ParentHash common.Hash `json:"parentHash"` + Nonce hexutil.Bytes `json:"nonce"` + Timestamp hexutil.Uint64 `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extraData"` + GasLimit hexutil.Uint64 `json:"gasLimit"` + Difficulty *hexutil.Big `json:"difficulty"` + Mixhash common.Hash `json:"mixhash"` + Coinbase common.Address `json:"coinbase"` + Alloc types.GenesisAlloc `json:"alloc"` + ParentHash common.Hash `json:"parentHash"` } // newPyEthereumGenesisSpec converts a go-ethereum genesis block into a Parity specific diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index af52abc8e4..e2dbdbc623 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -26,6 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" @@ -49,7 +50,7 @@ func (w *wizard) makeGenesis() { Timestamp: uint64(time.Now().Unix()), GasLimit: 4700000, Difficulty: big.NewInt(524288), - Alloc: make(core.GenesisAlloc), + Alloc: make(types.GenesisAlloc), Config: ¶ms.ChainConfig{ HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), @@ -202,7 +203,7 @@ func (w *wizard) makeGenesis() { // Validator Smart Contract Code pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr := crypto.PubkeyToAddress(pKey.PublicKey) - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) transactOpts := bind.NewKeyedTransactor(pKey) validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner) @@ -225,7 +226,7 @@ func (w *wizard) makeGenesis() { return true } contractBackend.ForEachStorageAt(ctx, validatorAddress, nil, f) - genesis.Alloc[common.MasternodeVotingSMCBinary] = core.GenesisAccount{ + genesis.Alloc[common.MasternodeVotingSMCBinary] = types.Account{ Balance: validatorCap.Mul(validatorCap, big.NewInt(int64(len(validatorCaps)))), Code: code, Storage: storage, @@ -259,7 +260,7 @@ func (w *wizard) makeGenesis() { fBalance := big.NewInt(0) // 16m fBalance.Add(fBalance, big.NewInt(16*1000*1000)) fBalance.Mul(fBalance, big.NewInt(1000000000000000000)) - genesis.Alloc[common.FoudationAddrBinary] = core.GenesisAccount{ + genesis.Alloc[common.FoudationAddrBinary] = types.Account{ Balance: fBalance, Code: code, Storage: storage, @@ -275,7 +276,7 @@ func (w *wizard) makeGenesis() { code, _ = contractBackend.CodeAt(ctx, blockSignerAddress, nil) storage = make(map[common.Hash]common.Hash) contractBackend.ForEachStorageAt(ctx, blockSignerAddress, nil, f) - genesis.Alloc[common.BlockSignersBinary] = core.GenesisAccount{ + genesis.Alloc[common.BlockSignersBinary] = types.Account{ Balance: big.NewInt(0), Code: code, Storage: storage, @@ -291,7 +292,7 @@ func (w *wizard) makeGenesis() { code, _ = contractBackend.CodeAt(ctx, randomizeAddress, nil) storage = make(map[common.Hash]common.Hash) contractBackend.ForEachStorageAt(ctx, randomizeAddress, nil, f) - genesis.Alloc[common.RandomizeSMCBinary] = core.GenesisAccount{ + genesis.Alloc[common.RandomizeSMCBinary] = types.Account{ Balance: big.NewInt(0), Code: code, Storage: storage, @@ -330,7 +331,7 @@ func (w *wizard) makeGenesis() { subBalance.Add(subBalance, big.NewInt(int64(len(signers))*50*1000)) subBalance.Mul(subBalance, big.NewInt(1000000000000000000)) balance.Sub(balance, subBalance) // 12m - i * 50k - genesis.Alloc[common.TeamAddrBinary] = core.GenesisAccount{ + genesis.Alloc[common.TeamAddrBinary] = types.Account{ Balance: balance, Code: code, Storage: storage, @@ -342,7 +343,7 @@ func (w *wizard) makeGenesis() { baseBalance := big.NewInt(0) // 55m baseBalance.Add(baseBalance, big.NewInt(55*1000*1000)) baseBalance.Mul(baseBalance, big.NewInt(1000000000000000000)) - genesis.Alloc[swapAddr] = core.GenesisAccount{ + genesis.Alloc[swapAddr] = types.Account{ Balance: baseBalance, } @@ -355,7 +356,7 @@ func (w *wizard) makeGenesis() { for { // Read the address of the account to fund if address := w.readAddress(); address != nil { - genesis.Alloc[*address] = core.GenesisAccount{ + genesis.Alloc[*address] = types.Account{ Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows) } continue @@ -364,7 +365,7 @@ func (w *wizard) makeGenesis() { } // Add a batch of precompile balances to avoid them getting deleted for i := int64(0); i < 2; i++ { - genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(0)} + genesis.Alloc[common.BigToAddress(big.NewInt(i))] = types.Account{Balance: big.NewInt(0)} } // Query the user for some custom extras fmt.Println() diff --git a/consensus/tests/api_test.go b/consensus/tests/api_test.go index 64cbf80431..395fd7f60c 100644 --- a/consensus/tests/api_test.go +++ b/consensus/tests/api_test.go @@ -6,7 +6,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" "github.com/stretchr/testify/assert" @@ -18,7 +18,7 @@ var ( ) func TestConfigApi(t *testing.T) { - bc := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + bc := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, }, 10000000, params.TestXDPoSMockChainConfig) diff --git a/consensus/tests/engine_v1_tests/helper.go b/consensus/tests/engine_v1_tests/helper.go index e1a66d1308..c63c325ee2 100644 --- a/consensus/tests/engine_v1_tests/helper.go +++ b/consensus/tests/engine_v1_tests/helper.go @@ -74,7 +74,7 @@ func RandStringBytes(n int) string { func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.SimulatedBackend { // initial helper backend - contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackendForSC := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, }, 10000000, chainConfig) @@ -143,7 +143,7 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.S } // create test backend with smart contract in it - contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackend2 := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)}, diff --git a/consensus/tests/engine_v2_tests/helper.go b/consensus/tests/engine_v2_tests/helper.go index 01a607b033..89439f8119 100644 --- a/consensus/tests/engine_v2_tests/helper.go +++ b/consensus/tests/engine_v2_tests/helper.go @@ -115,7 +115,7 @@ func voteTX(gasLimit uint64, nonce uint64, addr string) (*types.Transaction, err func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.SimulatedBackend { // initial helper backend - contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackendForSC := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, }, 10000000, chainConfig) @@ -184,7 +184,7 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.S } // create test backend with smart contract in it - contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackend2 := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)}, @@ -198,7 +198,7 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.S func getMultiCandidatesBackend(t *testing.T, chainConfig *params.ChainConfig, n int) *backends.SimulatedBackend { assert.GreaterOrEqual(t, n, 4) // initial helper backend, give a very large gas limit - contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackendForSC := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ voterAddr: {Balance: new(big.Int).SetUint64(10000000000)}, }, 1000000000, chainConfig) @@ -268,7 +268,7 @@ func getMultiCandidatesBackend(t *testing.T, chainConfig *params.ChainConfig, n } // create test backend with smart contract in it - contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackend2 := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)}, acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)}, diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go index d1f8cbc0f4..d4e1bcc394 100644 --- a/contracts/blocksigner/blocksigner_test.go +++ b/contracts/blocksigner/blocksigner_test.go @@ -26,7 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" ) @@ -37,7 +37,7 @@ var ( ) func TestBlockSigner(t *testing.T) { - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) transactOpts := bind.NewKeyedTransactor(key) blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99)) diff --git a/contracts/randomize/randomize_test.go b/contracts/randomize/randomize_test.go index 08c38e375d..8588bd8fe3 100644 --- a/contracts/randomize/randomize_test.go +++ b/contracts/randomize/randomize_test.go @@ -26,7 +26,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/contracts" - "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -42,7 +41,7 @@ var ( ) func TestRandomize(t *testing.T) { - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}}, 10000000, params.TestXDPoSMockChainConfig) transactOpts := bind.NewKeyedTransactor(key) transactOpts.GasLimit = 1000000 @@ -72,7 +71,7 @@ func TestRandomize(t *testing.T) { } func TestSendTxRandomizeSecretAndOpening(t *testing.T) { - genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} + genesis := types.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} // TODO(daniel): replace NewSimulatedBackend with NewXDCSimulatedBackend backend := backends.NewSimulatedBackend(genesis, 42000000) backend.Commit() diff --git a/contracts/tests/Inherited_test.go b/contracts/tests/Inherited_test.go index da9178ad1b..2a0c128487 100644 --- a/contracts/tests/Inherited_test.go +++ b/contracts/tests/Inherited_test.go @@ -9,7 +9,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" @@ -28,7 +28,7 @@ func TestPriceFeed(t *testing.T) { common.TIPXDCXCancellationFee = big.NewInt(0) // init genesis contractBackend := backends.NewXDCSimulatedBackend( - core.GenesisAlloc{ + types.GenesisAlloc{ mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, }, 42000000, diff --git a/contracts/trc21issuer/trc21issuer_test.go b/contracts/trc21issuer/trc21issuer_test.go index 04d98f41fb..19e3dde595 100644 --- a/contracts/trc21issuer/trc21issuer_test.go +++ b/contracts/trc21issuer/trc21issuer_test.go @@ -8,7 +8,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" ) @@ -32,7 +32,7 @@ var ( func TestFeeTxWithTRC21Token(t *testing.T) { // init genesis contractBackend := backends.NewXDCSimulatedBackend( - core.GenesisAlloc{ + types.GenesisAlloc{ mainAddr: {Balance: big.NewInt(0).Mul(big.NewInt(10000000000000), big.NewInt(10000000000000))}, }, 42000000, diff --git a/contracts/utils_test.go b/contracts/utils_test.go index 0f706c6032..c30409ceb8 100644 --- a/contracts/utils_test.go +++ b/contracts/utils_test.go @@ -29,7 +29,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner" - "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -47,7 +46,7 @@ var ( ) func getCommonBackend() *backends.SimulatedBackend { - genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} + genesis := types.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} backend := backends.NewXDCSimulatedBackend(genesis, 10000000, params.TestXDPoSMockChainConfig) backend.Commit() diff --git a/contracts/validator/validator_test.go b/contracts/validator/validator_test.go index 090d261770..00ed583650 100644 --- a/contracts/validator/validator_test.go +++ b/contracts/validator/validator_test.go @@ -31,7 +31,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" contractValidator "github.com/XinFinOrg/XDPoSChain/contracts/validator/contract" - "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -54,7 +53,7 @@ var ( ) func TestValidator(t *testing.T) { - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) + contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig) transactOpts := bind.NewKeyedTransactor(key) validatorCap := new(big.Int) @@ -90,7 +89,7 @@ func TestValidator(t *testing.T) { } func TestRewardBalance(t *testing.T) { - contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{ + contractBackend := backends.NewXDCSimulatedBackend(types.GenesisAlloc{ acc1Addr: {Balance: new(big.Int).SetUint64(10000000)}, acc2Addr: {Balance: new(big.Int).SetUint64(10000000)}, acc4Addr: {Balance: new(big.Int).SetUint64(10000000)}, @@ -274,7 +273,7 @@ func TestStatedbUtils(t *testing.T) { validatorCap.SetString("50000000000000000000000", 10) voteAmount := new(big.Int) voteAmount.SetString("25000000000000000000000", 10) - genesisAlloc := core.GenesisAlloc{ + genesisAlloc := types.GenesisAlloc{ addr: {Balance: big.NewInt(1000000000)}, acc1Addr: {Balance: validatorCap}, acc2Addr: {Balance: validatorCap}, @@ -310,7 +309,7 @@ func TestStatedbUtils(t *testing.T) { return true } contractBackend.ForEachStorageAt(ctx, validatorAddress, nil, f) - genesisAlloc[common.MasternodeVotingSMCBinary] = core.GenesisAccount{ + genesisAlloc[common.MasternodeVotingSMCBinary] = types.Account{ Balance: validatorCap, Code: code, Storage: storage, diff --git a/core/bench_test.go b/core/bench_test.go index 7da8d8249d..fdef0fe89b 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -22,11 +22,10 @@ import ( "os" "testing" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" @@ -164,7 +163,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // generator function. gspec := Genesis{ Config: params.TestChainConfig, - Alloc: GenesisAlloc{benchRootAddr: {Balance: benchRootFunds}}, + Alloc: types.GenesisAlloc{benchRootAddr: {Balance: benchRootFunds}}, } genesis := gspec.MustCommit(db) chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, b.N, gen) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 849daac1b8..fcb30eb577 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -557,7 +557,7 @@ func TestFastVsFullChains(t *testing.T) { funds = big.NewInt(1000000000000000) gspec = &Genesis{ Config: params.TestChainConfig, - Alloc: GenesisAlloc{address: {Balance: funds}}, + Alloc: types.GenesisAlloc{address: {Balance: funds}}, BaseFee: big.NewInt(params.InitialBaseFee), } genesis = gspec.MustCommit(gendb) @@ -646,7 +646,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { funds = big.NewInt(1000000000000000) gspec = &Genesis{ Config: params.TestChainConfig, - Alloc: GenesisAlloc{address: {Balance: funds}}, + Alloc: types.GenesisAlloc{address: {Balance: funds}}, BaseFee: big.NewInt(params.InitialBaseFee), } genesis = gspec.MustCommit(gendb) @@ -733,7 +733,7 @@ func TestChainTxReorgs(t *testing.T) { gspec = &Genesis{ Config: params.TestChainConfig, GasLimit: 3141592, - Alloc: GenesisAlloc{ + Alloc: types.GenesisAlloc{ addr1: {Balance: big.NewInt(1000000000000000)}, addr2: {Balance: big.NewInt(1000000000000000)}, addr3: {Balance: big.NewInt(1000000000000000)}, @@ -844,7 +844,7 @@ func TestLogReorgs(t *testing.T) { db = rawdb.NewMemoryDatabase() // this code generates a log code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") - gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} + gspec = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} genesis = gspec.MustCommit(db) signer = types.LatestSigner(gspec.Config) ) @@ -1023,7 +1023,7 @@ func TestEIP155Transition(t *testing.T) { deleteAddr = common.Address{1} gspec = &Genesis{ Config: ¶ms.ChainConfig{ChainId: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, - Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, + Alloc: types.GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, } genesis = gspec.MustCommit(db) ) @@ -1131,7 +1131,7 @@ func TestEIP161AccountRemoval(t *testing.T) { EIP155Block: new(big.Int), EIP158Block: big.NewInt(2), }, - Alloc: GenesisAlloc{address: {Balance: funds}}, + Alloc: types.GenesisAlloc{address: {Balance: funds}}, } genesis = gspec.MustCommit(db) ) @@ -1452,7 +1452,7 @@ func TestEIP2718Transition(t *testing.T) { IstanbulBlock: big.NewInt(0), Eip1559Block: big.NewInt(0), }, - Alloc: GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, // The address 0xAAAA sloads 0x00 and 0x01 aa: { @@ -1553,7 +1553,7 @@ func TestTransientStorageReset(t *testing.T) { }...) gspec := &Genesis{ Config: params.TestChainConfig, - Alloc: GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -1624,7 +1624,7 @@ func TestEIP3651(t *testing.T) { funds = big.NewInt(8000000000000000) gspec = &Genesis{ Config: params.TestChainConfig, - Alloc: GenesisAlloc{ + Alloc: types.GenesisAlloc{ addr1: {Balance: funds}, addr2: {Balance: funds}, // The address 0xAAAA sloads 0x00 and 0x01 diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 1dbcaf9fb0..d24cd2ec9e 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -41,7 +41,7 @@ func ExampleGenerateChain() { // Ensure that key1 has some funds in the genesis block. gspec := &Genesis{ Config: ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}, - Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, + Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, } genesis := gspec.MustCommit(db) diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 27dcb1f7cc..181f6740d7 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -10,6 +10,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/params" ) @@ -26,7 +27,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` Mixhash common.Hash `json:"mixHash"` Coinbase common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` Number math.HexOrDecimal64 `json:"number"` GasUsed math.HexOrDecimal64 `json:"gasUsed"` ParentHash common.Hash `json:"parentHash"` @@ -42,7 +43,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.Mixhash = g.Mixhash enc.Coinbase = g.Coinbase if g.Alloc != nil { - enc.Alloc = make(map[common.UnprefixedAddress]GenesisAccount, len(g.Alloc)) + enc.Alloc = make(map[common.UnprefixedAddress]types.Account, len(g.Alloc)) for k, v := range g.Alloc { enc.Alloc[common.UnprefixedAddress(k)] = v } @@ -65,7 +66,7 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` Mixhash *common.Hash `json:"mixHash"` Coinbase *common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` Number *math.HexOrDecimal64 `json:"number"` GasUsed *math.HexOrDecimal64 `json:"gasUsed"` ParentHash *common.Hash `json:"parentHash"` @@ -104,7 +105,7 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.Alloc == nil { return errors.New("missing required field 'alloc' for Genesis") } - g.Alloc = make(GenesisAlloc, len(dec.Alloc)) + g.Alloc = make(types.GenesisAlloc, len(dec.Alloc)) for k, v := range dec.Alloc { g.Alloc[common.Address(k)] = v } diff --git a/core/genesis.go b/core/genesis.go index ef8541970a..370f81ea28 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -17,22 +17,19 @@ package core import ( - "bytes" - "encoding/hex" "encoding/json" "errors" "fmt" "math/big" "strings" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/crypto" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/common/math" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/params" @@ -40,10 +37,15 @@ import ( ) //go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go -//go:generate go run github.com/fjl/gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go var errGenesisNoConfig = errors.New("genesis has no chain configuration") +// Deprecated: use types.GenesisAccount instead. +type GenesisAccount = types.Account + +// Deprecated: use types.GenesisAlloc instead. +type GenesisAlloc = types.GenesisAlloc + // Genesis specifies the header fields, state of a genesis block. It also defines hard // fork switch-over blocks through the chain configuration. type Genesis struct { @@ -55,7 +57,7 @@ type Genesis struct { Difficulty *big.Int `json:"difficulty" gencodec:"required"` Mixhash common.Hash `json:"mixHash"` Coinbase common.Address `json:"coinbase"` - Alloc GenesisAlloc `json:"alloc" gencodec:"required"` + Alloc types.GenesisAlloc `json:"alloc" gencodec:"required"` // These fields are used for consensus tests. Please don't use them // in actual genesis blocks. @@ -65,30 +67,6 @@ type Genesis struct { BaseFee *big.Int `json:"baseFeePerGas"` } -// GenesisAlloc specifies the initial state that is part of the genesis block. -type GenesisAlloc map[common.Address]GenesisAccount - -func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { - m := make(map[common.UnprefixedAddress]GenesisAccount) - if err := json.Unmarshal(data, &m); err != nil { - return err - } - *ga = make(GenesisAlloc) - for addr, a := range m { - (*ga)[common.Address(addr)] = a - } - return nil -} - -// GenesisAccount is an account in the state of the genesis block. -type GenesisAccount struct { - Code []byte `json:"code,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - Balance *big.Int `json:"balance" gencodec:"required"` - Nonce uint64 `json:"nonce,omitempty"` - PrivateKey []byte `json:"secretKey,omitempty"` // for tests -} - // field type overrides for gencodec type genesisSpecMarshaling struct { Nonce math.HexOrDecimal64 @@ -99,36 +77,7 @@ type genesisSpecMarshaling struct { Number math.HexOrDecimal64 Difficulty *math.HexOrDecimal256 BaseFee *math.HexOrDecimal256 - Alloc map[common.UnprefixedAddress]GenesisAccount -} - -type genesisAccountMarshaling struct { - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes -} - -// storageJSON represents a 256 bit byte array, but allows less than 256 bits when -// unmarshaling from hex. -type storageJSON common.Hash - -func (h *storageJSON) UnmarshalText(text []byte) error { - text = bytes.TrimPrefix(text, []byte("0x")) - if len(text) > 64 { - return fmt.Errorf("too many hex characters in storage key/value %q", text) - } - offset := len(h) - len(text)/2 // pad on the left - if _, err := hex.Decode(h[offset:], text); err != nil { - fmt.Println(err) - return fmt.Errorf("invalid hex storage key/value %q", text) - } - return nil -} - -func (h storageJSON) MarshalText() ([]byte, error) { - return hexutil.Bytes(h[:]).MarshalText() + Alloc map[common.UnprefixedAddress]types.Account } // GenesisMismatchError is raised when trying to overwrite an existing @@ -312,7 +261,7 @@ func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { g := Genesis{ - Alloc: GenesisAlloc{addr: {Balance: balance}}, + Alloc: types.GenesisAlloc{addr: {Balance: balance}}, BaseFee: big.NewInt(params.InitialBaseFee), } return g.MustCommit(db) @@ -373,7 +322,7 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { GasLimit: 6283185, BaseFee: big.NewInt(params.InitialBaseFee), Difficulty: big.NewInt(1), - Alloc: map[common.Address]GenesisAccount{ + Alloc: map[common.Address]types.Account{ common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD @@ -387,20 +336,20 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { } } -func decodePrealloc(data string) GenesisAlloc { +func decodePrealloc(data string) types.GenesisAlloc { var p []struct{ Addr, Balance *big.Int } if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { panic(err) } - ga := make(GenesisAlloc, len(p)) + ga := make(types.GenesisAlloc, len(p)) for _, account := range p { - ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} + ga[common.BigToAddress(account.Addr)] = types.Account{Balance: account.Balance} } return ga } -func DecodeAllocJson(s string) GenesisAlloc { - alloc := GenesisAlloc{} +func DecodeAllocJson(s string) types.GenesisAlloc { + alloc := types.GenesisAlloc{} json.Unmarshal([]byte(s), &alloc) return alloc } diff --git a/core/genesis_test.go b/core/genesis_test.go index a05d924865..2de9c4ca36 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -21,11 +21,11 @@ import ( "reflect" "testing" + "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core/rawdb" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" - - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/params" "github.com/davecgh/go-spew/spew" @@ -47,7 +47,7 @@ func TestSetupGenesis(t *testing.T) { customghash = common.HexToHash("0xfc8a143549950b0d3e3e7b70b0067b152e6b903ab5438f1ea87f0448ec93da48") customg = Genesis{ Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, - Alloc: GenesisAlloc{ + Alloc: types.GenesisAlloc{ {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, }, } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 39d6ce194f..71462096e0 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -79,8 +79,8 @@ func TestStateProcessorErrors(t *testing.T) { db = rawdb.NewMemoryDatabase() gspec = &Genesis{ Config: config, - Alloc: GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{ + Alloc: types.GenesisAlloc{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(1000000000000000000), // 1 ether Nonce: 0, }, @@ -213,8 +213,8 @@ func TestStateProcessorErrors(t *testing.T) { PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), }, - Alloc: GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): GenesisAccount{ + Alloc: types.GenesisAlloc{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(1000000000000000000), // 1 ether Nonce: 0, }, diff --git a/core/types/account.go b/core/types/account.go new file mode 100644 index 0000000000..3e15010aaf --- /dev/null +++ b/core/types/account.go @@ -0,0 +1,88 @@ +// Copyright 2024 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 . + +package types + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/common/hexutil" + "github.com/XinFinOrg/XDPoSChain/common/math" +) + +//go:generate go run github.com/fjl/gencodec -type Account -field-override accountMarshaling -out gen_account.go + +// Account represents an Ethereum account and its attached data. +// This type is used to specify accounts in the genesis block state, and +// is also useful for JSON encoding/decoding of accounts. +type Account struct { + Code []byte `json:"code,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *big.Int `json:"balance" gencodec:"required"` + Nonce uint64 `json:"nonce,omitempty"` + + // used in tests + PrivateKey []byte `json:"secretKey,omitempty"` +} + +type accountMarshaling struct { + Code hexutil.Bytes + Balance *math.HexOrDecimal256 + Nonce math.HexOrDecimal64 + Storage map[storageJSON]storageJSON + PrivateKey hexutil.Bytes +} + +// storageJSON represents a 256 bit byte array, but allows less than 256 bits when +// unmarshaling from hex. +type storageJSON common.Hash + +func (h *storageJSON) UnmarshalText(text []byte) error { + text = bytes.TrimPrefix(text, []byte("0x")) + if len(text) > 64 { + return fmt.Errorf("too many hex characters in storage key/value %q", text) + } + offset := len(h) - len(text)/2 // pad on the left + if _, err := hex.Decode(h[offset:], text); err != nil { + fmt.Println(err) + return fmt.Errorf("invalid hex storage key/value %q", text) + } + return nil +} + +func (h storageJSON) MarshalText() ([]byte, error) { + return hexutil.Bytes(h[:]).MarshalText() +} + +// GenesisAlloc specifies the initial state that is part of the genesis block. +type GenesisAlloc map[common.Address]Account + +func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { + m := make(map[common.UnprefixedAddress]Account) + if err := json.Unmarshal(data, &m); err != nil { + return err + } + *ga = make(GenesisAlloc) + for addr, a := range m { + (*ga)[common.Address(addr)] = a + } + return nil +} diff --git a/core/gen_genesis_account.go b/core/types/gen_account.go similarity index 61% rename from core/gen_genesis_account.go rename to core/types/gen_account.go index dd0a6f6719..0fd48d2eb9 100644 --- a/core/gen_genesis_account.go +++ b/core/types/gen_account.go @@ -1,6 +1,6 @@ // Code generated by github.com/fjl/gencodec. DO NOT EDIT. -package core +package types import ( "encoding/json" @@ -12,62 +12,62 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/math" ) -var _ = (*genesisAccountMarshaling)(nil) +var _ = (*accountMarshaling)(nil) // MarshalJSON marshals as JSON. -func (g GenesisAccount) MarshalJSON() ([]byte, error) { - type GenesisAccount struct { +func (a Account) MarshalJSON() ([]byte, error) { + type Account struct { Code hexutil.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` } - var enc GenesisAccount - enc.Code = g.Code - if g.Storage != nil { - enc.Storage = make(map[storageJSON]storageJSON, len(g.Storage)) - for k, v := range g.Storage { + var enc Account + enc.Code = a.Code + if a.Storage != nil { + enc.Storage = make(map[storageJSON]storageJSON, len(a.Storage)) + for k, v := range a.Storage { enc.Storage[storageJSON(k)] = storageJSON(v) } } - enc.Balance = (*math.HexOrDecimal256)(g.Balance) - enc.Nonce = math.HexOrDecimal64(g.Nonce) - enc.PrivateKey = g.PrivateKey + enc.Balance = (*math.HexOrDecimal256)(a.Balance) + enc.Nonce = math.HexOrDecimal64(a.Nonce) + enc.PrivateKey = a.PrivateKey return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. -func (g *GenesisAccount) UnmarshalJSON(input []byte) error { - type GenesisAccount struct { +func (a *Account) UnmarshalJSON(input []byte) error { + type Account struct { Code *hexutil.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` } - var dec GenesisAccount + var dec Account if err := json.Unmarshal(input, &dec); err != nil { return err } if dec.Code != nil { - g.Code = *dec.Code + a.Code = *dec.Code } if dec.Storage != nil { - g.Storage = make(map[common.Hash]common.Hash, len(dec.Storage)) + a.Storage = make(map[common.Hash]common.Hash, len(dec.Storage)) for k, v := range dec.Storage { - g.Storage[common.Hash(k)] = common.Hash(v) + a.Storage[common.Hash(k)] = common.Hash(v) } } if dec.Balance == nil { - return errors.New("missing required field 'balance' for GenesisAccount") + return errors.New("missing required field 'balance' for Account") } - g.Balance = (*big.Int)(dec.Balance) + a.Balance = (*big.Int)(dec.Balance) if dec.Nonce != nil { - g.Nonce = uint64(*dec.Nonce) + a.Nonce = uint64(*dec.Nonce) } if dec.PrivateKey != nil { - g.PrivateKey = *dec.PrivateKey + a.PrivateKey = *dec.PrivateKey } return nil } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index a775c62201..5a2204e32b 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -676,7 +676,7 @@ func TestLightFilterLogs(t *testing.T) { key, _ = crypto.GenerateKey() addr = crypto.PubkeyToAddress(key.PublicKey) genesis = &core.Genesis{Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ addr: {Balance: big.NewInt(params.Ether)}, }, } diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index abaca11901..e6ac77a076 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -116,7 +116,7 @@ func newTestBackend(t *testing.T, eip1559Block *big.Int, pending bool) *testBack addr = crypto.PubkeyToAddress(key.PublicKey) gspec = &core.Genesis{ Config: &config, - Alloc: core.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, + Alloc: types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, } signer = types.LatestSigner(gspec.Config) ) diff --git a/eth/helper_test.go b/eth/helper_test.go index 0b793d09bc..c883e6f624 100644 --- a/eth/helper_test.go +++ b/eth/helper_test.go @@ -58,7 +58,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func db = rawdb.NewMemoryDatabase() gspec = &core.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, + Alloc: types.GenesisAlloc{testBank: {Balance: big.NewInt(1000000)}}, } genesis = gspec.MustCommit(db) blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}) diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 53d3b9dcaf..2c0b1b6570 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -136,12 +136,12 @@ func TestZeroValueToNotExitCall(t *testing.T) { byte(vm.DUP1), byte(vm.PUSH1), 0xff, byte(vm.GAS), // value=0,address=0xff, gas=GAS byte(vm.CALL), } - var alloc = core.GenesisAlloc{ - to: core.GenesisAccount{ + var alloc = types.GenesisAlloc{ + to: types.Account{ Nonce: 1, Code: code, }, - origin: core.GenesisAccount{ + origin: types.Account{ Nonce: 0, Balance: big.NewInt(500000000000000), }, @@ -215,16 +215,16 @@ func TestPrestateTracerCreate2(t *testing.T) { Difficulty: big.NewInt(0x30000), GasLimit: uint64(6000000), } - alloc := core.GenesisAlloc{} + alloc := types.GenesisAlloc{} // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns // the address - alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{ + alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.Account{ Nonce: 1, Code: hexutil.MustDecode("0x63deadbeef60005263cafebabe6004601c6000F560005260206000F3"), Balance: big.NewInt(1), } - alloc[origin] = core.GenesisAccount{ + alloc[origin] = types.Account{ Nonce: 1, Code: []byte{}, Balance: big.NewInt(500000000000000), @@ -309,7 +309,7 @@ func BenchmarkTransactionTrace(b *testing.B) { GasLimit: gas, // BaseFee: big.NewInt(8), } - alloc := core.GenesisAlloc{} + alloc := types.GenesisAlloc{} // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns // the address loop := []byte{ @@ -317,12 +317,12 @@ func BenchmarkTransactionTrace(b *testing.B) { byte(vm.PUSH1), 0, // jumpdestination byte(vm.JUMP), } - alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{ + alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.Account{ Nonce: 1, Code: loop, Balance: big.NewInt(1), } - alloc[from] = core.GenesisAccount{ + alloc[from] = types.Account{ Nonce: 1, Code: []byte{}, Balance: big.NewInt(500000000000000), diff --git a/les/helper_test.go b/les/helper_test.go index 19e054626a..2093a6fb17 100644 --- a/les/helper_test.go +++ b/les/helper_test.go @@ -142,7 +142,7 @@ func newTestProtocolManager(lightSync bool, blocks int, generator func(int, *cor engine = ethash.NewFaker() gspec = core.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, } genesis = gspec.MustCommit(db) chain BlockChain diff --git a/light/odr_test.go b/light/odr_test.go index 29ffe84fbf..e561f62ab4 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -258,7 +258,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) { sdb = rawdb.NewMemoryDatabase() ldb = rawdb.NewMemoryDatabase() gspec = core.Genesis{ - Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, BaseFee: big.NewInt(params.InitialBaseFee), } genesis = gspec.MustCommit(sdb) diff --git a/light/trie_test.go b/light/trie_test.go index 1dda0cc73e..bf4853e536 100644 --- a/light/trie_test.go +++ b/light/trie_test.go @@ -28,6 +28,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/trie" @@ -39,7 +40,7 @@ func TestNodeIterator(t *testing.T) { fulldb = rawdb.NewMemoryDatabase() lightdb = rawdb.NewMemoryDatabase() gspec = core.Genesis{ - Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, BaseFee: big.NewInt(params.InitialBaseFee), } genesis = gspec.MustCommit(fulldb) diff --git a/light/txpool_test.go b/light/txpool_test.go index e52e8dff73..dc7ae41482 100644 --- a/light/txpool_test.go +++ b/light/txpool_test.go @@ -85,7 +85,7 @@ func TestTxPool(t *testing.T) { sdb = rawdb.NewMemoryDatabase() ldb = rawdb.NewMemoryDatabase() gspec = core.Genesis{ - Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, + Alloc: types.GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, BaseFee: big.NewInt(params.InitialBaseFee), } genesis = gspec.MustCommit(sdb) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 8a6cc1c412..505f86ccc4 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -50,8 +50,8 @@ func (t *BlockTest) UnmarshalJSON(in []byte) error { type btJSON struct { Blocks []btBlock `json:"blocks"` Genesis btHeader `json:"genesisBlockHeader"` - Pre core.GenesisAlloc `json:"pre"` - Post core.GenesisAlloc `json:"postState"` + Pre types.GenesisAlloc `json:"pre"` + Post types.GenesisAlloc `json:"postState"` BestBlock common.UnprefixedHash `json:"lastblockhash"` Network string `json:"network"` } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 45d4244d80..926ac0b1c9 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -57,7 +57,7 @@ func (t *StateTest) UnmarshalJSON(in []byte) error { type stJSON struct { Env stEnv `json:"env"` - Pre core.GenesisAlloc `json:"pre"` + Pre types.GenesisAlloc `json:"pre"` Tx stTransaction `json:"transaction"` Out hexutil.Bytes `json:"out"` Post map[string][]stPostState `json:"post"` @@ -185,7 +185,7 @@ func (t *StateTest) gasLimit(subtest StateSubtest) uint64 { return t.json.Tx.GasLimit[t.json.Post[subtest.Fork][subtest.Index].Indexes.Gas] } -func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB { +func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB { sdb := state.NewDatabase(db) statedb, _ := state.New(common.Hash{}, sdb) for addr, a := range accounts { diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index 8866168d52..e4a5b1ef8e 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/params" @@ -50,8 +51,8 @@ type vmJSON struct { Logs common.UnprefixedHash `json:"logs"` GasRemaining *math.HexOrDecimal64 `json:"gas"` Out hexutil.Bytes `json:"out"` - Pre core.GenesisAlloc `json:"pre"` - Post core.GenesisAlloc `json:"post"` + Pre types.GenesisAlloc `json:"pre"` + Post types.GenesisAlloc `json:"post"` PostStateRoot common.Hash `json:"postStateRoot"` } From 85059ed0d72f1b8ae704b376ec597b0988882672 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 255/280] accounts/abi: delete duplicate error check (#29136) --- accounts/abi/type.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 2dbd24c85a..500f670191 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -178,9 +178,6 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty return Type{}, errors.New("abi: purely anonymous or underscored field is not supported") } fieldName := ResolveNameConflict(name, func(s string) bool { return used[s] }) - if err != nil { - return Type{}, err - } used[fieldName] = true if !isValidFieldName(fieldName) { return Type{}, fmt.Errorf("field %d has invalid name", idx) From 13d39173b36593f3cc4432a283032708bf93ffc2 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 256/280] accounts/usbwallet: update hid library (#29176) --- accounts/usbwallet/hub.go | 8 ++++---- accounts/usbwallet/wallet.go | 6 +++--- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 66948a23d8..7b43215cf4 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -26,7 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/karalabe/usb" + "github.com/karalabe/hid" ) // LedgerScheme is the protocol scheme prefixing account and wallet URLs. @@ -109,7 +109,7 @@ func NewTrezorHubWithWebUSB() (*Hub, error) { // newHub creates a new hardware wallet manager for generic USB devices. func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) { - if !usb.Supported() { + if !hid.Supported() { return nil, errors.New("unsupported platform") } hub := &Hub{ @@ -155,7 +155,7 @@ func (hub *Hub) refreshWallets() { return } // Retrieve the current list of USB wallet devices - var devices []usb.DeviceInfo + var devices []hid.DeviceInfo if runtime.GOOS == "linux" { // hidapi on Linux opens the device during enumeration to retrieve some infos, @@ -170,7 +170,7 @@ func (hub *Hub) refreshWallets() { return } } - infos, err := usb.Enumerate(hub.vendorID, 0) + infos, err := hid.Enumerate(hub.vendorID, 0) if err != nil { failcount := hub.enumFails.Add(1) if runtime.GOOS == "linux" { diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index ca296f4cb6..7ce681f10b 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -31,7 +31,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/karalabe/usb" + "github.com/karalabe/hid" ) // Maximum time between wallet health checks to detect USB unplugs. @@ -79,8 +79,8 @@ type wallet struct { driver driver // Hardware implementation of the low level device operations url *accounts.URL // Textual URL uniquely identifying this wallet - info usb.DeviceInfo // Known USB device infos about the wallet - device usb.Device // USB device advertising itself as a hardware wallet + info hid.DeviceInfo // Known USB device infos about the wallet + device hid.Device // USB device advertising itself as a hardware wallet accounts []accounts.Account // List of derive accounts pinned on the hardware wallet paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations diff --git a/go.mod b/go.mod index b84e0ed811..d95af86f6a 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/google/uuid v1.6.0 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c - github.com/karalabe/usb v0.0.2 + github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 github.com/kevinburke/go-bindata v3.23.0+incompatible github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-isatty v0.0.17 diff --git a/go.sum b/go.sum index 16558b1e15..1693b7fa7e 100644 --- a/go.sum +++ b/go.sum @@ -113,10 +113,10 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kevinburke/go-bindata v3.23.0+incompatible h1:rqNOXZlqrYhMVVAsQx8wuc+LaA73YcfbQ407wAykyS8= github.com/kevinburke/go-bindata v3.23.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= From 888963c6ff15e6ed535884a943a8274cfd134d72 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 257/280] accounts: remove deprecated function NewPlaintextKeyStore (#29171) --- accounts/keystore/account_cache_test.go | 2 +- accounts/keystore/keystore.go | 9 ------- accounts/keystore/keystore_test.go | 35 +++++++++++-------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 4d68d48320..9e5cc38fbd 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -86,7 +86,7 @@ func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { func TestWatchNewFile(t *testing.T) { t.Parallel() - dir, ks := tmpKeyStore(t, false) + dir, ks := tmpKeyStore(t) // Ensure the watcher is started before adding any files. ks.Accounts() diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 42dc45a656..60e7f3cdf8 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -87,15 +87,6 @@ func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { return ks } -// NewPlaintextKeyStore creates a keystore for the given directory. -// Deprecated: Use NewKeyStore. -func NewPlaintextKeyStore(keydir string) *KeyStore { - keydir, _ = filepath.Abs(keydir) - ks := &KeyStore{storage: &keyStorePlain{keydir}} - ks.init(keydir) - return ks -} - func (ks *KeyStore) init(keydir string) { // Lock the mutex since the account cache might call back with events ks.mu.Lock() diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index 0762a95582..8905714521 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -37,7 +37,7 @@ var testSigData = make([]byte, 32) func TestKeyStore(t *testing.T) { t.Parallel() - dir, ks := tmpKeyStore(t, true) + dir, ks := tmpKeyStore(t) a, err := ks.NewAccount("foo") if err != nil { @@ -72,7 +72,7 @@ func TestKeyStore(t *testing.T) { func TestSign(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "" // not used but required by API a1, err := ks.NewAccount(pass) @@ -89,7 +89,7 @@ func TestSign(t *testing.T) { func TestSignWithPassphrase(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "passwd" acc, err := ks.NewAccount(pass) @@ -117,7 +117,7 @@ func TestSignWithPassphrase(t *testing.T) { func TestTimedUnlock(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) pass := "foo" a1, err := ks.NewAccount(pass) @@ -152,7 +152,7 @@ func TestTimedUnlock(t *testing.T) { func TestOverrideUnlock(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) pass := "foo" a1, err := ks.NewAccount(pass) @@ -193,7 +193,7 @@ func TestOverrideUnlock(t *testing.T) { // This test should fail under -race if signing races the expiration goroutine. func TestSignRace(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Create a test account. a1, err := ks.NewAccount("") @@ -238,7 +238,7 @@ func waitForKsUpdating(t *testing.T, ks *KeyStore, wantStatus bool, maxTime time func TestWalletNotifierLifecycle(t *testing.T) { t.Parallel() // Create a temporary keystore to test with - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Ensure that the notification updater is not running yet time.Sleep(250 * time.Millisecond) @@ -284,7 +284,7 @@ type walletEvent struct { // or deleted from the keystore. func TestWalletNotifications(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, false) + _, ks := tmpKeyStore(t) // Subscribe to the wallet feed and collect events. var ( @@ -346,7 +346,7 @@ func TestWalletNotifications(t *testing.T) { // TestImportECDSA tests the import functionality of a keystore. func TestImportECDSA(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) key, err := crypto.GenerateKey() if err != nil { t.Fatalf("failed to generate key: %v", key) @@ -365,7 +365,7 @@ func TestImportECDSA(t *testing.T) { // TestImportExport tests the import and export functionality of a keystore. func TestImportExport(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -374,8 +374,7 @@ func TestImportExport(t *testing.T) { if err != nil { t.Fatalf("failed to export account: %v", acc) } - dir2, ks2 := tmpKeyStore(t, true) - defer os.RemoveAll(dir2) + _, ks2 := tmpKeyStore(t) if _, err = ks2.Import(json, "old", "old"); err == nil { t.Errorf("importing with invalid password succeeded") } @@ -395,7 +394,7 @@ func TestImportExport(t *testing.T) { // This test should fail under -race if importing races. func TestImportRace(t *testing.T) { t.Parallel() - _, ks := tmpKeyStore(t, true) + _, ks := tmpKeyStore(t) acc, err := ks.NewAccount("old") if err != nil { t.Fatalf("failed to create account: %v", acc) @@ -404,7 +403,7 @@ func TestImportRace(t *testing.T) { if err != nil { t.Fatalf("failed to export account: %v", acc) } - _, ks2 := tmpKeyStore(t, true) + _, ks2 := tmpKeyStore(t) var atom atomic.Uint32 var wg sync.WaitGroup wg.Add(2) @@ -458,11 +457,7 @@ func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { } } -func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { +func tmpKeyStore(t *testing.T) (string, *KeyStore) { d := t.TempDir() - newKs := NewPlaintextKeyStore - if encrypted { - newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } - } - return d, newKs(d) + return d, NewKeyStore(d, veryLightScryptN, veryLightScryptP) } From a9ca99dc6a5fd8c9c30f354dec3c6c1b5c609714 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 258/280] accounts: remove redundant string conversion (#29184) --- accounts/accounts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/accounts.go b/accounts/accounts.go index 359c4f680e..8a66d93e58 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -208,7 +208,7 @@ func TextHash(data []byte) []byte { // // This gives context to the signed message and prevents signing of transactions. func TextAndHash(data []byte) ([]byte, string) { - msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data)) + msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) hasher := sha3.NewLegacyKeccak256() hasher.Write([]byte(msg)) return hasher.Sum(nil), msg From 2b60816af1490a4b58c7500841973295ef7d99d9 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 259/280] accounts/scwallet: remove references to deprecated elliptic package (#28946) --- accounts/scwallet/securechannel.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index 5bb9ce9d77..a1bb7ac3d0 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -20,7 +20,6 @@ import ( "bytes" "crypto/aes" "crypto/cipher" - "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/sha512" @@ -72,11 +71,11 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes if err != nil { return nil, fmt.Errorf("could not unmarshal public key from card: %v", err) } - secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) + secret, _ := crypto.S256().ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) return &SecureChannelSession{ card: card, secret: secret.Bytes(), - publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y), + publicKey: crypto.FromECDSAPub(&key.PublicKey), }, nil } From 30dc0f47c9886024113cf6d57d4113e78995a4ff Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 260/280] accounts/abi/bind: check invalid chainID first (#29275) --- accounts/abi/bind/auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 48f0601621..ba74ad11bf 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -141,10 +141,10 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou // NewKeyedTransactorWithChainID is a utility method to easily create a transaction signer // from a single private key. func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*TransactOpts, error) { - keyAddr := crypto.PubkeyToAddress(key.PublicKey) if chainID == nil { return nil, ErrNoChainID } + keyAddr := crypto.PubkeyToAddress(key.PublicKey) signer := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: keyAddr, From dfc0f112b8dcfdc88cf2310081888e447fc2dc3c Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:16 +0800 Subject: [PATCH 261/280] accounts/keystore: use min/max/clear from go1.21 (#29307) --- accounts/keystore/keystore.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 60e7f3cdf8..32580d01c1 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -511,7 +511,5 @@ func (ks *KeyStore) isUpdating() bool { // zeroKey zeroes a private key in memory. func zeroKey(k *ecdsa.PrivateKey) { b := k.D.Bits() - for i := range b { - b[i] = 0 - } + clear(b) } From 733a5fc193acf4185802e2dcd4244a75f8897f28 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 262/280] accounts: fix mismatched names in comments (#29348) --- accounts/abi/argument.go | 2 +- accounts/keystore/account_cache_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index fa5461895a..227a088b7d 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -127,7 +127,7 @@ func (arguments Arguments) Copy(v interface{}, values []interface{}) error { return arguments.copyAtomic(v, values[0]) } -// unpackAtomic unpacks ( hexdata -> go ) a single value +// copyAtomic copies ( hexdata -> go ) a single value func (arguments Arguments) copyAtomic(v interface{}, marshalledValues interface{}) error { dst := reflect.ValueOf(v).Elem() src := reflect.ValueOf(marshalledValues) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 9e5cc38fbd..2955156e96 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -51,7 +51,7 @@ var ( } ) -// waitWatcherStarts waits up to 1s for the keystore watcher to start. +// waitWatcherStart waits up to 1s for the keystore watcher to start. func waitWatcherStart(ks *KeyStore) bool { // On systems where file watch is not supported, just return "ok". if !ks.cache.watcher.enabled() { From 02a3aa13c1ed972f1bf5b7bdf4c8f2e195eb6671 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 263/280] accounts/abi: fix typos (#29542 #29600) --- accounts/abi/reflect.go | 4 ++-- accounts/abi/type_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 1863e5bb7d..729ca93c54 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -24,7 +24,7 @@ import ( "strings" ) -// ConvertType converts an interface of a runtime type into a interface of the +// ConvertType converts an interface of a runtime type into an interface of the // given type, e.g. turn this code: // // var fields []reflect.StructField @@ -33,7 +33,7 @@ import ( // Name: "X", // Type: reflect.TypeOf(new(big.Int)), // Tag: reflect.StructTag("json:\"" + "x" + "\""), -// } +// }) // // into: // diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index 2b43fd7f8b..188554a262 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -25,7 +25,7 @@ import ( "github.com/davecgh/go-spew/spew" ) -// typeWithoutStringer is a alias for the Type type which simply doesn't implement +// typeWithoutStringer is an alias for the Type type which simply doesn't implement // the stringer interface to allow printing type details in the tests below. type typeWithoutStringer Type From ef71887d7af119514c1d91f03b8391d47645d0ef Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 264/280] accounts, cmd/geth, core: close opened files (#29598) * fix: open file used up but not closed * feat: more same case * feat: accept conversation --- accounts/keystore/keystore.go | 7 +++---- accounts/scwallet/hub.go | 1 + core/mkalloc.go | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 32580d01c1..983793e0b7 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -323,11 +323,10 @@ func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error { // Lock removes the private key with the given address from memory. func (ks *KeyStore) Lock(addr common.Address) error { ks.mu.Lock() - if unl, found := ks.unlocked[addr]; found { - ks.mu.Unlock() + unl, found := ks.unlocked[addr] + ks.mu.Unlock() + if found { ks.expire(addr, unl, time.Duration(0)*time.Nanosecond) - } else { - ks.mu.Unlock() } return nil } diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index 50b5433765..410e8f0023 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -95,6 +95,7 @@ func (hub *Hub) readPairings() error { } return err } + defer pairingFile.Close() pairingData, err := io.ReadAll(pairingFile) if err != nil { diff --git a/core/mkalloc.go b/core/mkalloc.go index 6c8a5d0ee5..0eb2e86e2d 100644 --- a/core/mkalloc.go +++ b/core/mkalloc.go @@ -78,6 +78,7 @@ func main() { if err != nil { panic(err) } + defer file.Close() if err := json.NewDecoder(file).Decode(g); err != nil { panic(err) } From 643c715b43c42e199329867ab37ba86aa13531f0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 265/280] accounts: fix TestUpdateKeyfileContents (#29867) Create the directory before NewKeyStore. This ensures the watcher successfully starts on the first attempt, and waitWatcherStart functions as intended. --- accounts/keystore/account_cache_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 2955156e96..440329593a 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -326,6 +326,11 @@ func TestUpdatedKeyfileContents(t *testing.T) { // Create a temporary keystore to test with dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) + + // Create the directory + os.MkdirAll(dir, 0700) + defer os.RemoveAll(dir) + ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() @@ -335,9 +340,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { if !waitWatcherStart(ks) { t.Fatal("keystore watcher didn't start in time") } - // Create the directory and copy a key file into it. - os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) + // Copy a key file into it file := filepath.Join(dir, "aaa") // Place one of our testfiles in there From d2e00672c5b72c8242e3fd6f61b90ad906dda730 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 266/280] accounts: avoid duplicate regex compilation (#29943) * fix: Optimize regular initialization * modify var name * variable change to private types --- accounts/abi/type.go | 6 ++++-- accounts/scwallet/wallet.go | 12 ++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 500f670191..55b4735ef7 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -64,6 +64,9 @@ type Type struct { var ( // typeRegex parses the abi sub types typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?") + + // sliceSizeRegex grab the slice size + sliceSizeRegex = regexp.MustCompile("[0-9]+") ) // NewType creates a new reflection type of abi type given in t. @@ -91,8 +94,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty // grab the last cell and create a type from there sliced := t[i:] // grab the slice size with regexp - re := regexp.MustCompile("[0-9]+") - intz := re.FindAllString(sliced, -1) + intz := sliceSizeRegex.FindAllString(sliced, -1) if len(intz) == 0 { // is a slice diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index a919394c63..eaa1eb3a1d 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -73,6 +73,14 @@ var ( DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes()) ) +var ( + // PinRegexp is the regular expression used to validate PIN codes. + pinRegexp = regexp.MustCompile(`^[0-9]{6,}$`) + + // PukRegexp is the regular expression used to validate PUK codes. + pukRegexp = regexp.MustCompile(`^[0-9]{12,}$`) +) + // List of APDU command-related constants const ( claISO7816 = 0 @@ -380,7 +388,7 @@ func (w *Wallet) Open(passphrase string) error { case passphrase == "": return ErrPINUnblockNeeded case status.PinRetryCount > 0: - if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) { + if !pinRegexp.MatchString(passphrase) { w.log.Error("PIN needs to be at least 6 digits") return ErrPINNeeded } @@ -388,7 +396,7 @@ func (w *Wallet) Open(passphrase string) error { return err } default: - if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) { + if !pukRegexp.MatchString(passphrase) { w.log.Error("PUK needs to be at least 12 digits") return ErrPINUnblockNeeded } From 62895df6938beccf3963e41b781545ab764c6213 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 267/280] accounts/keystore: use t.TempDir in test (#30052) --- accounts/keystore/account_cache_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 440329593a..12dab2a53b 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -325,11 +325,7 @@ func TestUpdatedKeyfileContents(t *testing.T) { t.Parallel() // Create a temporary keystore to test with - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-updatedkeyfilecontents-test-%d-%d", os.Getpid(), rand.Int())) - - // Create the directory - os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) + dir := t.TempDir() ks := NewKeyStore(dir, LightScryptN, LightScryptP) From a0a1322d844a0c8a8a2b80fe75c611a5bb71ef72 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 268/280] accounts/usbwallet/trezor: upgrade to generate with protoc 27.1 (#30058) --- .../usbwallet/trezor/messages-common.pb.go | 1431 +++++---- .../usbwallet/trezor/messages-common.proto | 2 + .../usbwallet/trezor/messages-ethereum.pb.go | 1200 +++++--- .../usbwallet/trezor/messages-ethereum.proto | 2 + .../trezor/messages-management.pb.go | 2679 ++++++++++------- .../trezor/messages-management.proto | 2 + accounts/usbwallet/trezor/messages.pb.go | 1743 +++++++---- accounts/usbwallet/trezor/messages.proto | 3 + accounts/usbwallet/trezor/trezor.go | 2 +- 9 files changed, 4448 insertions(+), 2616 deletions(-) diff --git a/accounts/usbwallet/trezor/messages-common.pb.go b/accounts/usbwallet/trezor/messages-common.pb.go index 304bec0e36..3c62f40274 100644 --- a/accounts/usbwallet/trezor/messages-common.pb.go +++ b/accounts/usbwallet/trezor/messages-common.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.1 // source: messages-common.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type Failure_FailureType int32 @@ -39,37 +42,39 @@ const ( Failure_Failure_FirmwareError Failure_FailureType = 99 ) -var Failure_FailureType_name = map[int32]string{ - 1: "Failure_UnexpectedMessage", - 2: "Failure_ButtonExpected", - 3: "Failure_DataError", - 4: "Failure_ActionCancelled", - 5: "Failure_PinExpected", - 6: "Failure_PinCancelled", - 7: "Failure_PinInvalid", - 8: "Failure_InvalidSignature", - 9: "Failure_ProcessError", - 10: "Failure_NotEnoughFunds", - 11: "Failure_NotInitialized", - 12: "Failure_PinMismatch", - 99: "Failure_FirmwareError", -} - -var Failure_FailureType_value = map[string]int32{ - "Failure_UnexpectedMessage": 1, - "Failure_ButtonExpected": 2, - "Failure_DataError": 3, - "Failure_ActionCancelled": 4, - "Failure_PinExpected": 5, - "Failure_PinCancelled": 6, - "Failure_PinInvalid": 7, - "Failure_InvalidSignature": 8, - "Failure_ProcessError": 9, - "Failure_NotEnoughFunds": 10, - "Failure_NotInitialized": 11, - "Failure_PinMismatch": 12, - "Failure_FirmwareError": 99, -} +// Enum value maps for Failure_FailureType. +var ( + Failure_FailureType_name = map[int32]string{ + 1: "Failure_UnexpectedMessage", + 2: "Failure_ButtonExpected", + 3: "Failure_DataError", + 4: "Failure_ActionCancelled", + 5: "Failure_PinExpected", + 6: "Failure_PinCancelled", + 7: "Failure_PinInvalid", + 8: "Failure_InvalidSignature", + 9: "Failure_ProcessError", + 10: "Failure_NotEnoughFunds", + 11: "Failure_NotInitialized", + 12: "Failure_PinMismatch", + 99: "Failure_FirmwareError", + } + Failure_FailureType_value = map[string]int32{ + "Failure_UnexpectedMessage": 1, + "Failure_ButtonExpected": 2, + "Failure_DataError": 3, + "Failure_ActionCancelled": 4, + "Failure_PinExpected": 5, + "Failure_PinCancelled": 6, + "Failure_PinInvalid": 7, + "Failure_InvalidSignature": 8, + "Failure_ProcessError": 9, + "Failure_NotEnoughFunds": 10, + "Failure_NotInitialized": 11, + "Failure_PinMismatch": 12, + "Failure_FirmwareError": 99, + } +) func (x Failure_FailureType) Enum() *Failure_FailureType { p := new(Failure_FailureType) @@ -78,20 +83,34 @@ func (x Failure_FailureType) Enum() *Failure_FailureType { } func (x Failure_FailureType) String() string { - return proto.EnumName(Failure_FailureType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *Failure_FailureType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(Failure_FailureType_value, data, "Failure_FailureType") +func (Failure_FailureType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[0].Descriptor() +} + +func (Failure_FailureType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[0] +} + +func (x Failure_FailureType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Failure_FailureType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = Failure_FailureType(value) + *x = Failure_FailureType(num) return nil } +// Deprecated: Use Failure_FailureType.Descriptor instead. func (Failure_FailureType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{1, 0} + return file_messages_common_proto_rawDescGZIP(), []int{1, 0} } //* @@ -116,41 +135,43 @@ const ( ButtonRequest_ButtonRequest_UnknownDerivationPath ButtonRequest_ButtonRequestType = 15 ) -var ButtonRequest_ButtonRequestType_name = map[int32]string{ - 1: "ButtonRequest_Other", - 2: "ButtonRequest_FeeOverThreshold", - 3: "ButtonRequest_ConfirmOutput", - 4: "ButtonRequest_ResetDevice", - 5: "ButtonRequest_ConfirmWord", - 6: "ButtonRequest_WipeDevice", - 7: "ButtonRequest_ProtectCall", - 8: "ButtonRequest_SignTx", - 9: "ButtonRequest_FirmwareCheck", - 10: "ButtonRequest_Address", - 11: "ButtonRequest_PublicKey", - 12: "ButtonRequest_MnemonicWordCount", - 13: "ButtonRequest_MnemonicInput", - 14: "ButtonRequest_PassphraseType", - 15: "ButtonRequest_UnknownDerivationPath", -} - -var ButtonRequest_ButtonRequestType_value = map[string]int32{ - "ButtonRequest_Other": 1, - "ButtonRequest_FeeOverThreshold": 2, - "ButtonRequest_ConfirmOutput": 3, - "ButtonRequest_ResetDevice": 4, - "ButtonRequest_ConfirmWord": 5, - "ButtonRequest_WipeDevice": 6, - "ButtonRequest_ProtectCall": 7, - "ButtonRequest_SignTx": 8, - "ButtonRequest_FirmwareCheck": 9, - "ButtonRequest_Address": 10, - "ButtonRequest_PublicKey": 11, - "ButtonRequest_MnemonicWordCount": 12, - "ButtonRequest_MnemonicInput": 13, - "ButtonRequest_PassphraseType": 14, - "ButtonRequest_UnknownDerivationPath": 15, -} +// Enum value maps for ButtonRequest_ButtonRequestType. +var ( + ButtonRequest_ButtonRequestType_name = map[int32]string{ + 1: "ButtonRequest_Other", + 2: "ButtonRequest_FeeOverThreshold", + 3: "ButtonRequest_ConfirmOutput", + 4: "ButtonRequest_ResetDevice", + 5: "ButtonRequest_ConfirmWord", + 6: "ButtonRequest_WipeDevice", + 7: "ButtonRequest_ProtectCall", + 8: "ButtonRequest_SignTx", + 9: "ButtonRequest_FirmwareCheck", + 10: "ButtonRequest_Address", + 11: "ButtonRequest_PublicKey", + 12: "ButtonRequest_MnemonicWordCount", + 13: "ButtonRequest_MnemonicInput", + 14: "ButtonRequest_PassphraseType", + 15: "ButtonRequest_UnknownDerivationPath", + } + ButtonRequest_ButtonRequestType_value = map[string]int32{ + "ButtonRequest_Other": 1, + "ButtonRequest_FeeOverThreshold": 2, + "ButtonRequest_ConfirmOutput": 3, + "ButtonRequest_ResetDevice": 4, + "ButtonRequest_ConfirmWord": 5, + "ButtonRequest_WipeDevice": 6, + "ButtonRequest_ProtectCall": 7, + "ButtonRequest_SignTx": 8, + "ButtonRequest_FirmwareCheck": 9, + "ButtonRequest_Address": 10, + "ButtonRequest_PublicKey": 11, + "ButtonRequest_MnemonicWordCount": 12, + "ButtonRequest_MnemonicInput": 13, + "ButtonRequest_PassphraseType": 14, + "ButtonRequest_UnknownDerivationPath": 15, + } +) func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType { p := new(ButtonRequest_ButtonRequestType) @@ -159,20 +180,34 @@ func (x ButtonRequest_ButtonRequestType) Enum() *ButtonRequest_ButtonRequestType } func (x ButtonRequest_ButtonRequestType) String() string { - return proto.EnumName(ButtonRequest_ButtonRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ButtonRequest_ButtonRequestType_value, data, "ButtonRequest_ButtonRequestType") +func (ButtonRequest_ButtonRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[1].Descriptor() +} + +func (ButtonRequest_ButtonRequestType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[1] +} + +func (x ButtonRequest_ButtonRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ButtonRequest_ButtonRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = ButtonRequest_ButtonRequestType(value) + *x = ButtonRequest_ButtonRequestType(num) return nil } +// Deprecated: Use ButtonRequest_ButtonRequestType.Descriptor instead. func (ButtonRequest_ButtonRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{2, 0} + return file_messages_common_proto_rawDescGZIP(), []int{2, 0} } //* @@ -185,17 +220,19 @@ const ( PinMatrixRequest_PinMatrixRequestType_NewSecond PinMatrixRequest_PinMatrixRequestType = 3 ) -var PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ - 1: "PinMatrixRequestType_Current", - 2: "PinMatrixRequestType_NewFirst", - 3: "PinMatrixRequestType_NewSecond", -} - -var PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ - "PinMatrixRequestType_Current": 1, - "PinMatrixRequestType_NewFirst": 2, - "PinMatrixRequestType_NewSecond": 3, -} +// Enum value maps for PinMatrixRequest_PinMatrixRequestType. +var ( + PinMatrixRequest_PinMatrixRequestType_name = map[int32]string{ + 1: "PinMatrixRequestType_Current", + 2: "PinMatrixRequestType_NewFirst", + 3: "PinMatrixRequestType_NewSecond", + } + PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{ + "PinMatrixRequestType_Current": 1, + "PinMatrixRequestType_NewFirst": 2, + "PinMatrixRequestType_NewSecond": 3, + } +) func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatrixRequestType { p := new(PinMatrixRequest_PinMatrixRequestType) @@ -204,60 +241,82 @@ func (x PinMatrixRequest_PinMatrixRequestType) Enum() *PinMatrixRequest_PinMatri } func (x PinMatrixRequest_PinMatrixRequestType) String() string { - return proto.EnumName(PinMatrixRequest_PinMatrixRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(PinMatrixRequest_PinMatrixRequestType_value, data, "PinMatrixRequest_PinMatrixRequestType") +func (PinMatrixRequest_PinMatrixRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_common_proto_enumTypes[2].Descriptor() +} + +func (PinMatrixRequest_PinMatrixRequestType) Type() protoreflect.EnumType { + return &file_messages_common_proto_enumTypes[2] +} + +func (x PinMatrixRequest_PinMatrixRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PinMatrixRequest_PinMatrixRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = PinMatrixRequest_PinMatrixRequestType(value) + *x = PinMatrixRequest_PinMatrixRequestType(num) return nil } +// Deprecated: Use PinMatrixRequest_PinMatrixRequestType.Descriptor instead. func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{4, 0} + return file_messages_common_proto_rawDescGZIP(), []int{4, 0} } //* // Response: Success of the previous request // @end type Success struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` // human readable description of action or request-specific payload } -func (m *Success) Reset() { *m = Success{} } -func (m *Success) String() string { return proto.CompactTextString(m) } -func (*Success) ProtoMessage() {} +func (x *Success) Reset() { + *x = Success{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Success) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Success) ProtoMessage() {} + +func (x *Success) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Success.ProtoReflect.Descriptor instead. func (*Success) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{0} + return file_messages_common_proto_rawDescGZIP(), []int{0} } -func (m *Success) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Success.Unmarshal(m, b) -} -func (m *Success) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Success.Marshal(b, m, deterministic) -} -func (m *Success) XXX_Merge(src proto.Message) { - xxx_messageInfo_Success.Merge(m, src) -} -func (m *Success) XXX_Size() int { - return xxx_messageInfo_Success.Size(m) -} -func (m *Success) XXX_DiscardUnknown() { - xxx_messageInfo_Success.DiscardUnknown(m) -} - -var xxx_messageInfo_Success proto.InternalMessageInfo - -func (m *Success) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Success) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } @@ -266,48 +325,56 @@ func (m *Success) GetMessage() string { // Response: Failure of the previous request // @end type Failure struct { - Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` - Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` // computer-readable definition of the error state + Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` // human-readable message of the error state } -func (m *Failure) Reset() { *m = Failure{} } -func (m *Failure) String() string { return proto.CompactTextString(m) } -func (*Failure) ProtoMessage() {} +func (x *Failure) Reset() { + *x = Failure{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Failure) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Failure) ProtoMessage() {} + +func (x *Failure) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Failure.ProtoReflect.Descriptor instead. func (*Failure) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{1} + return file_messages_common_proto_rawDescGZIP(), []int{1} } -func (m *Failure) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Failure.Unmarshal(m, b) -} -func (m *Failure) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Failure.Marshal(b, m, deterministic) -} -func (m *Failure) XXX_Merge(src proto.Message) { - xxx_messageInfo_Failure.Merge(m, src) -} -func (m *Failure) XXX_Size() int { - return xxx_messageInfo_Failure.Size(m) -} -func (m *Failure) XXX_DiscardUnknown() { - xxx_messageInfo_Failure.DiscardUnknown(m) -} - -var xxx_messageInfo_Failure proto.InternalMessageInfo - -func (m *Failure) GetCode() Failure_FailureType { - if m != nil && m.Code != nil { - return *m.Code +func (x *Failure) GetCode() Failure_FailureType { + if x != nil && x.Code != nil { + return *x.Code } return Failure_Failure_UnexpectedMessage } -func (m *Failure) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Failure) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } @@ -317,48 +384,56 @@ func (m *Failure) GetMessage() string { // @auxstart // @next ButtonAck type ButtonRequest struct { - Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` - Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` + Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"` } -func (m *ButtonRequest) Reset() { *m = ButtonRequest{} } -func (m *ButtonRequest) String() string { return proto.CompactTextString(m) } -func (*ButtonRequest) ProtoMessage() {} +func (x *ButtonRequest) Reset() { + *x = ButtonRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ButtonRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ButtonRequest) ProtoMessage() {} + +func (x *ButtonRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ButtonRequest.ProtoReflect.Descriptor instead. func (*ButtonRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{2} + return file_messages_common_proto_rawDescGZIP(), []int{2} } -func (m *ButtonRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonRequest.Unmarshal(m, b) -} -func (m *ButtonRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonRequest.Marshal(b, m, deterministic) -} -func (m *ButtonRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonRequest.Merge(m, src) -} -func (m *ButtonRequest) XXX_Size() int { - return xxx_messageInfo_ButtonRequest.Size(m) -} -func (m *ButtonRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ButtonRequest proto.InternalMessageInfo - -func (m *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { - if m != nil && m.Code != nil { - return *m.Code +func (x *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType { + if x != nil && x.Code != nil { + return *x.Code } return ButtonRequest_ButtonRequest_Other } -func (m *ButtonRequest) GetData() string { - if m != nil && m.Data != nil { - return *m.Data +func (x *ButtonRequest) GetData() string { + if x != nil && x.Data != nil { + return *x.Data } return "" } @@ -367,75 +442,90 @@ func (m *ButtonRequest) GetData() string { // Request: Computer agrees to wait for HW button press // @auxend type ButtonAck struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *ButtonAck) Reset() { *m = ButtonAck{} } -func (m *ButtonAck) String() string { return proto.CompactTextString(m) } -func (*ButtonAck) ProtoMessage() {} +func (x *ButtonAck) Reset() { + *x = ButtonAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ButtonAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ButtonAck) ProtoMessage() {} + +func (x *ButtonAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ButtonAck.ProtoReflect.Descriptor instead. func (*ButtonAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{3} + return file_messages_common_proto_rawDescGZIP(), []int{3} } -func (m *ButtonAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ButtonAck.Unmarshal(m, b) -} -func (m *ButtonAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ButtonAck.Marshal(b, m, deterministic) -} -func (m *ButtonAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_ButtonAck.Merge(m, src) -} -func (m *ButtonAck) XXX_Size() int { - return xxx_messageInfo_ButtonAck.Size(m) -} -func (m *ButtonAck) XXX_DiscardUnknown() { - xxx_messageInfo_ButtonAck.DiscardUnknown(m) -} - -var xxx_messageInfo_ButtonAck proto.InternalMessageInfo - -//* +// * // Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme // @auxstart // @next PinMatrixAck type PinMatrixRequest struct { - Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"` } -func (m *PinMatrixRequest) Reset() { *m = PinMatrixRequest{} } -func (m *PinMatrixRequest) String() string { return proto.CompactTextString(m) } -func (*PinMatrixRequest) ProtoMessage() {} +func (x *PinMatrixRequest) Reset() { + *x = PinMatrixRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PinMatrixRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PinMatrixRequest) ProtoMessage() {} + +func (x *PinMatrixRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PinMatrixRequest.ProtoReflect.Descriptor instead. func (*PinMatrixRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{4} + return file_messages_common_proto_rawDescGZIP(), []int{4} } -func (m *PinMatrixRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixRequest.Unmarshal(m, b) -} -func (m *PinMatrixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixRequest.Marshal(b, m, deterministic) -} -func (m *PinMatrixRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixRequest.Merge(m, src) -} -func (m *PinMatrixRequest) XXX_Size() int { - return xxx_messageInfo_PinMatrixRequest.Size(m) -} -func (m *PinMatrixRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PinMatrixRequest proto.InternalMessageInfo - -func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { - if m != nil && m.Type != nil { - return *m.Type +func (x *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { + if x != nil && x.Type != nil { + return *x.Type } return PinMatrixRequest_PinMatrixRequestType_Current } @@ -444,40 +534,48 @@ func (m *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType { // Request: Computer responds with encoded PIN // @auxend type PinMatrixAck struct { - Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` // matrix encoded PIN entered by user } -func (m *PinMatrixAck) Reset() { *m = PinMatrixAck{} } -func (m *PinMatrixAck) String() string { return proto.CompactTextString(m) } -func (*PinMatrixAck) ProtoMessage() {} +func (x *PinMatrixAck) Reset() { + *x = PinMatrixAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PinMatrixAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PinMatrixAck) ProtoMessage() {} + +func (x *PinMatrixAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PinMatrixAck.ProtoReflect.Descriptor instead. func (*PinMatrixAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{5} + return file_messages_common_proto_rawDescGZIP(), []int{5} } -func (m *PinMatrixAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PinMatrixAck.Unmarshal(m, b) -} -func (m *PinMatrixAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PinMatrixAck.Marshal(b, m, deterministic) -} -func (m *PinMatrixAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PinMatrixAck.Merge(m, src) -} -func (m *PinMatrixAck) XXX_Size() int { - return xxx_messageInfo_PinMatrixAck.Size(m) -} -func (m *PinMatrixAck) XXX_DiscardUnknown() { - xxx_messageInfo_PinMatrixAck.DiscardUnknown(m) -} - -var xxx_messageInfo_PinMatrixAck proto.InternalMessageInfo - -func (m *PinMatrixAck) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin +func (x *PinMatrixAck) GetPin() string { + if x != nil && x.Pin != nil { + return *x.Pin } return "" } @@ -487,40 +585,48 @@ func (m *PinMatrixAck) GetPin() string { // @auxstart // @next PassphraseAck type PassphraseRequest struct { - OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` // passphrase is being entered on the device } -func (m *PassphraseRequest) Reset() { *m = PassphraseRequest{} } -func (m *PassphraseRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseRequest) ProtoMessage() {} +func (x *PassphraseRequest) Reset() { + *x = PassphraseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassphraseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassphraseRequest) ProtoMessage() {} + +func (x *PassphraseRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PassphraseRequest.ProtoReflect.Descriptor instead. func (*PassphraseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{6} + return file_messages_common_proto_rawDescGZIP(), []int{6} } -func (m *PassphraseRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseRequest.Unmarshal(m, b) -} -func (m *PassphraseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseRequest.Marshal(b, m, deterministic) -} -func (m *PassphraseRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseRequest.Merge(m, src) -} -func (m *PassphraseRequest) XXX_Size() int { - return xxx_messageInfo_PassphraseRequest.Size(m) -} -func (m *PassphraseRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseRequest proto.InternalMessageInfo - -func (m *PassphraseRequest) GetOnDevice() bool { - if m != nil && m.OnDevice != nil { - return *m.OnDevice +func (x *PassphraseRequest) GetOnDevice() bool { + if x != nil && x.OnDevice != nil { + return *x.OnDevice } return false } @@ -529,48 +635,56 @@ func (m *PassphraseRequest) GetOnDevice() bool { // Request: Send passphrase back // @next PassphraseStateRequest type PassphraseAck struct { - Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` - State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` + State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` // expected device state } -func (m *PassphraseAck) Reset() { *m = PassphraseAck{} } -func (m *PassphraseAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseAck) ProtoMessage() {} +func (x *PassphraseAck) Reset() { + *x = PassphraseAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassphraseAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassphraseAck) ProtoMessage() {} + +func (x *PassphraseAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PassphraseAck.ProtoReflect.Descriptor instead. func (*PassphraseAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{7} + return file_messages_common_proto_rawDescGZIP(), []int{7} } -func (m *PassphraseAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseAck.Unmarshal(m, b) -} -func (m *PassphraseAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseAck.Marshal(b, m, deterministic) -} -func (m *PassphraseAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseAck.Merge(m, src) -} -func (m *PassphraseAck) XXX_Size() int { - return xxx_messageInfo_PassphraseAck.Size(m) -} -func (m *PassphraseAck) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseAck.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseAck proto.InternalMessageInfo - -func (m *PassphraseAck) GetPassphrase() string { - if m != nil && m.Passphrase != nil { - return *m.Passphrase +func (x *PassphraseAck) GetPassphrase() string { + if x != nil && x.Passphrase != nil { + return *x.Passphrase } return "" } -func (m *PassphraseAck) GetState() []byte { - if m != nil { - return m.State +func (x *PassphraseAck) GetState() []byte { + if x != nil { + return x.State } return nil } @@ -579,40 +693,48 @@ func (m *PassphraseAck) GetState() []byte { // Response: Device awaits passphrase state // @next PassphraseStateAck type PassphraseStateRequest struct { - State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // actual device state } -func (m *PassphraseStateRequest) Reset() { *m = PassphraseStateRequest{} } -func (m *PassphraseStateRequest) String() string { return proto.CompactTextString(m) } -func (*PassphraseStateRequest) ProtoMessage() {} +func (x *PassphraseStateRequest) Reset() { + *x = PassphraseStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassphraseStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassphraseStateRequest) ProtoMessage() {} + +func (x *PassphraseStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PassphraseStateRequest.ProtoReflect.Descriptor instead. func (*PassphraseStateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{8} + return file_messages_common_proto_rawDescGZIP(), []int{8} } -func (m *PassphraseStateRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseStateRequest.Unmarshal(m, b) -} -func (m *PassphraseStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseStateRequest.Marshal(b, m, deterministic) -} -func (m *PassphraseStateRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseStateRequest.Merge(m, src) -} -func (m *PassphraseStateRequest) XXX_Size() int { - return xxx_messageInfo_PassphraseStateRequest.Size(m) -} -func (m *PassphraseStateRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseStateRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseStateRequest proto.InternalMessageInfo - -func (m *PassphraseStateRequest) GetState() []byte { - if m != nil { - return m.State +func (x *PassphraseStateRequest) GetState() []byte { + if x != nil { + return x.State } return nil } @@ -621,191 +743,456 @@ func (m *PassphraseStateRequest) GetState() []byte { // Request: Send passphrase state back // @auxend type PassphraseStateAck struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *PassphraseStateAck) Reset() { *m = PassphraseStateAck{} } -func (m *PassphraseStateAck) String() string { return proto.CompactTextString(m) } -func (*PassphraseStateAck) ProtoMessage() {} +func (x *PassphraseStateAck) Reset() { + *x = PassphraseStateAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassphraseStateAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassphraseStateAck) ProtoMessage() {} + +func (x *PassphraseStateAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PassphraseStateAck.ProtoReflect.Descriptor instead. func (*PassphraseStateAck) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{9} + return file_messages_common_proto_rawDescGZIP(), []int{9} } -func (m *PassphraseStateAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PassphraseStateAck.Unmarshal(m, b) -} -func (m *PassphraseStateAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PassphraseStateAck.Marshal(b, m, deterministic) -} -func (m *PassphraseStateAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_PassphraseStateAck.Merge(m, src) -} -func (m *PassphraseStateAck) XXX_Size() int { - return xxx_messageInfo_PassphraseStateAck.Size(m) -} -func (m *PassphraseStateAck) XXX_DiscardUnknown() { - xxx_messageInfo_PassphraseStateAck.DiscardUnknown(m) -} - -var xxx_messageInfo_PassphraseStateAck proto.InternalMessageInfo - -//* +// * // Structure representing BIP32 (hierarchical deterministic) node // Used for imports of private key into the device and exporting public key out of device // @embed type HDNodeType struct { - Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` - Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` - ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` - ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` - PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` - PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"` + Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"` + ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"` + ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"` + PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"` + PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"` } -func (m *HDNodeType) Reset() { *m = HDNodeType{} } -func (m *HDNodeType) String() string { return proto.CompactTextString(m) } -func (*HDNodeType) ProtoMessage() {} +func (x *HDNodeType) Reset() { + *x = HDNodeType{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_common_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HDNodeType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HDNodeType) ProtoMessage() {} + +func (x *HDNodeType) ProtoReflect() protoreflect.Message { + mi := &file_messages_common_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HDNodeType.ProtoReflect.Descriptor instead. func (*HDNodeType) Descriptor() ([]byte, []int) { - return fileDescriptor_aaf30d059fdbc38d, []int{10} + return file_messages_common_proto_rawDescGZIP(), []int{10} } -func (m *HDNodeType) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HDNodeType.Unmarshal(m, b) -} -func (m *HDNodeType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HDNodeType.Marshal(b, m, deterministic) -} -func (m *HDNodeType) XXX_Merge(src proto.Message) { - xxx_messageInfo_HDNodeType.Merge(m, src) -} -func (m *HDNodeType) XXX_Size() int { - return xxx_messageInfo_HDNodeType.Size(m) -} -func (m *HDNodeType) XXX_DiscardUnknown() { - xxx_messageInfo_HDNodeType.DiscardUnknown(m) -} - -var xxx_messageInfo_HDNodeType proto.InternalMessageInfo - -func (m *HDNodeType) GetDepth() uint32 { - if m != nil && m.Depth != nil { - return *m.Depth +func (x *HDNodeType) GetDepth() uint32 { + if x != nil && x.Depth != nil { + return *x.Depth } return 0 } -func (m *HDNodeType) GetFingerprint() uint32 { - if m != nil && m.Fingerprint != nil { - return *m.Fingerprint +func (x *HDNodeType) GetFingerprint() uint32 { + if x != nil && x.Fingerprint != nil { + return *x.Fingerprint } return 0 } -func (m *HDNodeType) GetChildNum() uint32 { - if m != nil && m.ChildNum != nil { - return *m.ChildNum +func (x *HDNodeType) GetChildNum() uint32 { + if x != nil && x.ChildNum != nil { + return *x.ChildNum } return 0 } -func (m *HDNodeType) GetChainCode() []byte { - if m != nil { - return m.ChainCode +func (x *HDNodeType) GetChainCode() []byte { + if x != nil { + return x.ChainCode } return nil } -func (m *HDNodeType) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey +func (x *HDNodeType) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey } return nil } -func (m *HDNodeType) GetPublicKey() []byte { - if m != nil { - return m.PublicKey +func (x *HDNodeType) GetPublicKey() []byte { + if x != nil { + return x.PublicKey } return nil } -func init() { - proto.RegisterEnum("hw.trezor.messages.common.Failure_FailureType", Failure_FailureType_name, Failure_FailureType_value) - proto.RegisterEnum("hw.trezor.messages.common.ButtonRequest_ButtonRequestType", ButtonRequest_ButtonRequestType_name, ButtonRequest_ButtonRequestType_value) - proto.RegisterEnum("hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType", PinMatrixRequest_PinMatrixRequestType_name, PinMatrixRequest_PinMatrixRequestType_value) - proto.RegisterType((*Success)(nil), "hw.trezor.messages.common.Success") - proto.RegisterType((*Failure)(nil), "hw.trezor.messages.common.Failure") - proto.RegisterType((*ButtonRequest)(nil), "hw.trezor.messages.common.ButtonRequest") - proto.RegisterType((*ButtonAck)(nil), "hw.trezor.messages.common.ButtonAck") - proto.RegisterType((*PinMatrixRequest)(nil), "hw.trezor.messages.common.PinMatrixRequest") - proto.RegisterType((*PinMatrixAck)(nil), "hw.trezor.messages.common.PinMatrixAck") - proto.RegisterType((*PassphraseRequest)(nil), "hw.trezor.messages.common.PassphraseRequest") - proto.RegisterType((*PassphraseAck)(nil), "hw.trezor.messages.common.PassphraseAck") - proto.RegisterType((*PassphraseStateRequest)(nil), "hw.trezor.messages.common.PassphraseStateRequest") - proto.RegisterType((*PassphraseStateAck)(nil), "hw.trezor.messages.common.PassphraseStateAck") - proto.RegisterType((*HDNodeType)(nil), "hw.trezor.messages.common.HDNodeType") +var File_messages_common_proto protoreflect.FileDescriptor + +var file_messages_common_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, + 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x22, 0x23, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xd5, 0x03, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2e, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0xeb, 0x02, 0x0a, 0x0b, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x55, 0x6e, 0x65, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, + 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x44, 0x61, 0x74, 0x61, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x10, 0x04, + 0x12, 0x17, 0x0a, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x45, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, + 0x64, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, + 0x69, 0x6e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e, + 0x6f, 0x74, 0x45, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x46, 0x75, 0x6e, 0x64, 0x73, 0x10, 0x0a, 0x12, + 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e, 0x6f, 0x74, 0x49, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x10, 0x0b, 0x12, 0x17, 0x0a, 0x13, 0x46, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x4d, 0x69, 0x73, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x10, 0x0c, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x63, 0x22, + 0xe6, 0x04, 0x0a, 0x0d, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x4e, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x3a, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf0, 0x03, 0x0a, 0x11, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4f, 0x74, 0x68, + 0x65, 0x72, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x46, 0x65, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x54, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x52, 0x65, 0x73, 0x65, 0x74, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x57, 0x6f, 0x72, 0x64, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x43, 0x61, + 0x6c, 0x6c, 0x10, 0x07, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x08, 0x12, 0x1f, + 0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x10, 0x09, 0x12, + 0x19, 0x0a, 0x15, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x0a, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, + 0x63, 0x57, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b, + 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e, + 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x10, 0x0d, 0x12, 0x20, 0x0a, + 0x1c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x0e, 0x12, + 0x27, 0x0a, 0x23, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x44, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x10, 0x0f, 0x22, 0x0b, 0x0a, 0x09, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x22, 0xe9, 0x01, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, + 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x7f, 0x0a, 0x14, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x69, 0x6e, 0x4d, + 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x69, + 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x46, 0x69, 0x72, 0x73, 0x74, 0x10, 0x02, 0x12, 0x22, 0x0a, + 0x1e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x10, + 0x03, 0x22, 0x20, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x41, 0x63, + 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03, + 0x70, 0x69, 0x6e, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6e, 0x5f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x6e, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x45, 0x0a, 0x0d, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x41, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73, + 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2e, 0x0a, 0x16, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x14, 0x0a, 0x12, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, + 0x63, 0x6b, 0x22, 0xc0, 0x01, 0x0a, 0x0a, 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0d, + 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x0b, 0x66, 0x69, + 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, 0x65, 0x7a, + 0x6f, 0x72, } -func init() { proto.RegisterFile("messages-common.proto", fileDescriptor_aaf30d059fdbc38d) } +var ( + file_messages_common_proto_rawDescOnce sync.Once + file_messages_common_proto_rawDescData = file_messages_common_proto_rawDesc +) -var fileDescriptor_aaf30d059fdbc38d = []byte{ - // 846 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xcd, 0x52, 0x23, 0x37, - 0x10, 0x2e, 0xff, 0x80, 0xed, 0xb6, 0xd9, 0x08, 0xc5, 0x80, 0x09, 0xb0, 0x38, 0xc3, 0x21, 0x5c, - 0xe2, 0x4a, 0xe5, 0x98, 0x53, 0x58, 0x83, 0x2b, 0xd4, 0x16, 0x86, 0x1a, 0xd8, 0xda, 0xa3, 0x4b, - 0xd1, 0xf4, 0x32, 0x2a, 0xcf, 0x48, 0x13, 0x8d, 0x06, 0xf0, 0x5e, 0xf2, 0x6a, 0x79, 0x89, 0xbc, - 0x42, 0xaa, 0x52, 0xb9, 0xe4, 0x11, 0xb6, 0x34, 0x3f, 0x78, 0xc6, 0x66, 0x39, 0xcd, 0xe8, 0xfb, - 0xbe, 0xee, 0x96, 0xba, 0x3f, 0x09, 0x76, 0x42, 0x8c, 0x63, 0x76, 0x8f, 0xf1, 0x8f, 0x5c, 0x85, - 0xa1, 0x92, 0xa3, 0x48, 0x2b, 0xa3, 0xe8, 0xbe, 0xff, 0x38, 0x32, 0x1a, 0x3f, 0x2b, 0x3d, 0x2a, - 0x04, 0xa3, 0x4c, 0xe0, 0x9c, 0x40, 0xeb, 0x36, 0xe1, 0x1c, 0xe3, 0x98, 0x0e, 0xa0, 0x95, 0xb3, - 0x83, 0xda, 0xb0, 0x76, 0xda, 0x71, 0x8b, 0xa5, 0xf3, 0x77, 0x03, 0x5a, 0x13, 0x26, 0x82, 0x44, - 0x23, 0x7d, 0x07, 0x4d, 0xae, 0xbc, 0x4c, 0xf2, 0xe6, 0xe7, 0xd1, 0xe8, 0xab, 0xa9, 0x47, 0x79, - 0x44, 0xf1, 0xbd, 0x5b, 0x44, 0xe8, 0xa6, 0xb1, 0xe5, 0x4a, 0xf5, 0x6a, 0xa5, 0xff, 0xea, 0xd0, - 0x2d, 0xe9, 0xe9, 0x11, 0xec, 0xe7, 0xcb, 0xd9, 0x07, 0x89, 0x4f, 0x11, 0x72, 0x83, 0xde, 0x55, - 0x26, 0x26, 0x35, 0xfa, 0x1d, 0xec, 0x16, 0xf4, 0xbb, 0xc4, 0x18, 0x25, 0x2f, 0x72, 0x09, 0xa9, - 0xd3, 0x1d, 0xd8, 0x2e, 0xb8, 0x73, 0x66, 0xd8, 0x85, 0xd6, 0x4a, 0x93, 0x06, 0x3d, 0x80, 0xbd, - 0x02, 0x3e, 0xe3, 0x46, 0x28, 0x39, 0x66, 0x92, 0x63, 0x10, 0xa0, 0x47, 0x9a, 0x74, 0x0f, 0xbe, - 0x2d, 0xc8, 0x1b, 0xb1, 0x4c, 0xb6, 0x41, 0x07, 0xd0, 0x2f, 0x11, 0xcb, 0x90, 0x4d, 0xba, 0x0b, - 0xb4, 0xc4, 0x5c, 0xca, 0x07, 0x16, 0x08, 0x8f, 0xb4, 0xe8, 0x21, 0x0c, 0x0a, 0x3c, 0x07, 0x6f, - 0xc5, 0xbd, 0x64, 0x26, 0xd1, 0x48, 0xda, 0x95, 0x7c, 0x5a, 0xd9, 0xf6, 0x67, 0xfb, 0xeb, 0x94, - 0x8f, 0x34, 0x55, 0xe6, 0x42, 0xaa, 0xe4, 0xde, 0x9f, 0x24, 0xd2, 0x8b, 0x09, 0xac, 0x70, 0x97, - 0x52, 0x18, 0xc1, 0x02, 0xf1, 0x19, 0x3d, 0xd2, 0x5d, 0xd9, 0xfa, 0x95, 0x88, 0x43, 0x66, 0xb8, - 0x4f, 0x7a, 0x74, 0x1f, 0x76, 0x0a, 0x62, 0x22, 0x74, 0xf8, 0xc8, 0x34, 0x66, 0xb5, 0xb8, 0xf3, - 0x4f, 0x13, 0xb6, 0xb2, 0xbe, 0xb9, 0xf8, 0x47, 0x82, 0xb1, 0xa1, 0xd3, 0xca, 0x74, 0x7f, 0x79, - 0x65, 0xba, 0x95, 0xb8, 0xea, 0xaa, 0x34, 0x69, 0x0a, 0x4d, 0x8f, 0x19, 0x96, 0x8f, 0x39, 0xfd, - 0x77, 0xfe, 0x6f, 0xc0, 0xf6, 0x9a, 0xde, 0xee, 0xbf, 0x02, 0xce, 0xae, 0x8d, 0x8f, 0x9a, 0xd4, - 0xa8, 0x03, 0x6f, 0xab, 0xc4, 0x04, 0xf1, 0xfa, 0x01, 0xf5, 0x9d, 0xaf, 0x31, 0xf6, 0x55, 0x60, - 0x67, 0x7d, 0x0c, 0x07, 0x55, 0xcd, 0x58, 0xc9, 0x4f, 0x42, 0x87, 0xd7, 0x89, 0x89, 0x12, 0x43, - 0x1a, 0xd6, 0x47, 0x55, 0x81, 0x8b, 0x31, 0x9a, 0x73, 0x7c, 0x10, 0x1c, 0x49, 0x73, 0x9d, 0xce, - 0xe3, 0x3f, 0x2a, 0x6d, 0xa7, 0x7f, 0x08, 0x83, 0x2a, 0xfd, 0x51, 0x44, 0x98, 0x07, 0x6f, 0xae, - 0x07, 0xdf, 0x68, 0x65, 0x90, 0x9b, 0x31, 0x0b, 0x02, 0xd2, 0xb2, 0xa3, 0xae, 0xd2, 0xd6, 0x07, - 0x77, 0x4f, 0xa4, 0xbd, 0xbe, 0xeb, 0x62, 0x3e, 0x63, 0x1f, 0xf9, 0x9c, 0x74, 0xec, 0xe8, 0xaa, - 0x82, 0x33, 0xcf, 0xd3, 0x18, 0x5b, 0x2b, 0x1c, 0xc0, 0xde, 0x4a, 0xd1, 0xe4, 0xf7, 0x40, 0xf0, - 0xf7, 0xb8, 0x20, 0x5d, 0x7a, 0x02, 0xc7, 0x55, 0xf2, 0x4a, 0x62, 0xa8, 0xa4, 0xe0, 0xf6, 0x3c, - 0x63, 0x95, 0x48, 0x43, 0x7a, 0xeb, 0xd5, 0x0b, 0xd1, 0xa5, 0xb4, 0x3d, 0xdb, 0xa2, 0x43, 0x38, - 0x5c, 0x29, 0xc1, 0xe2, 0x38, 0xf2, 0x35, 0x8b, 0xd3, 0xbb, 0x49, 0xde, 0xd0, 0x1f, 0xe0, 0xa4, - 0xaa, 0xf8, 0x20, 0xe7, 0x52, 0x3d, 0xca, 0x73, 0xd4, 0xe2, 0x81, 0xd9, 0xcb, 0x75, 0xc3, 0x8c, - 0x4f, 0xbe, 0x71, 0xba, 0xd0, 0xc9, 0x84, 0x67, 0x7c, 0xee, 0xfc, 0x5b, 0x03, 0x62, 0x2d, 0xca, - 0x8c, 0x16, 0x4f, 0x85, 0xf1, 0xee, 0xa0, 0x69, 0x16, 0x51, 0x61, 0xbc, 0x5f, 0x5f, 0x31, 0xde, - 0x6a, 0xe8, 0x1a, 0x90, 0xd9, 0xcf, 0x66, 0x73, 0xfe, 0x84, 0xfe, 0x4b, 0xac, 0x3d, 0xda, 0x4b, - 0xf8, 0x6c, 0x9c, 0x68, 0x8d, 0xd2, 0x90, 0x1a, 0xfd, 0x1e, 0x8e, 0x5e, 0x54, 0x4c, 0xf1, 0x71, - 0x22, 0x74, 0x6c, 0x48, 0xdd, 0x1a, 0xf3, 0x6b, 0x92, 0x5b, 0xe4, 0x4a, 0x7a, 0xa4, 0xe1, 0x0c, - 0xa1, 0xf7, 0xac, 0x39, 0xe3, 0x73, 0x4a, 0xa0, 0x11, 0x09, 0x39, 0xa8, 0x0d, 0xeb, 0xa7, 0x1d, - 0xd7, 0xfe, 0x3a, 0x3f, 0xc1, 0xf6, 0xb2, 0xaf, 0x45, 0x37, 0x0e, 0xa0, 0xa3, 0xe4, 0xcc, 0x4b, - 0x1d, 0x96, 0xb6, 0xa4, 0xed, 0xb6, 0x95, 0xcc, 0x1c, 0xe7, 0x5c, 0xc0, 0xd6, 0x32, 0xc2, 0x26, - 0x7d, 0x0b, 0x10, 0x3d, 0x03, 0xf9, 0xdb, 0x5d, 0x42, 0x68, 0x1f, 0x36, 0x62, 0xc3, 0x4c, 0xf6, - 0xd8, 0xf6, 0xdc, 0x6c, 0xe1, 0x8c, 0x60, 0x77, 0x99, 0xe6, 0xd6, 0x42, 0x45, 0xf5, 0x67, 0x7d, - 0xad, 0xac, 0xef, 0x03, 0x5d, 0xd1, 0xdb, 0x61, 0xfe, 0x55, 0x03, 0xf8, 0xed, 0x7c, 0xaa, 0xbc, - 0xec, 0xbd, 0xee, 0xc3, 0x86, 0x87, 0x91, 0xf1, 0xd3, 0x13, 0x6e, 0xb9, 0xd9, 0x82, 0x0e, 0xa1, - 0xfb, 0x49, 0xc8, 0x7b, 0xd4, 0x91, 0x16, 0xd2, 0x0c, 0xea, 0x29, 0x57, 0x86, 0xec, 0x81, 0xb9, - 0x2f, 0x02, 0x6f, 0x26, 0x93, 0x70, 0xd0, 0x48, 0xf9, 0x76, 0x0a, 0x4c, 0x93, 0x90, 0x1e, 0x01, - 0x70, 0x9f, 0x09, 0x39, 0x4b, 0x9f, 0xa6, 0xe6, 0xb0, 0x7e, 0xda, 0x73, 0x3b, 0x29, 0x32, 0xb6, - 0x6f, 0xcc, 0x31, 0x74, 0xa3, 0xd4, 0x6f, 0x38, 0x9b, 0xe3, 0x62, 0xb0, 0x91, 0x6e, 0x1a, 0x72, - 0xe8, 0x3d, 0x2e, 0x6c, 0x7c, 0x94, 0xde, 0x8e, 0x94, 0xdf, 0x4c, 0xf9, 0x4e, 0x54, 0xdc, 0x97, - 0x2f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x7d, 0x20, 0xa6, 0x35, 0x07, 0x00, 0x00, +func file_messages_common_proto_rawDescGZIP() []byte { + file_messages_common_proto_rawDescOnce.Do(func() { + file_messages_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_common_proto_rawDescData) + }) + return file_messages_common_proto_rawDescData +} + +var file_messages_common_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_messages_common_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_messages_common_proto_goTypes = []interface{}{ + (Failure_FailureType)(0), // 0: hw.trezor.messages.common.Failure.FailureType + (ButtonRequest_ButtonRequestType)(0), // 1: hw.trezor.messages.common.ButtonRequest.ButtonRequestType + (PinMatrixRequest_PinMatrixRequestType)(0), // 2: hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestType + (*Success)(nil), // 3: hw.trezor.messages.common.Success + (*Failure)(nil), // 4: hw.trezor.messages.common.Failure + (*ButtonRequest)(nil), // 5: hw.trezor.messages.common.ButtonRequest + (*ButtonAck)(nil), // 6: hw.trezor.messages.common.ButtonAck + (*PinMatrixRequest)(nil), // 7: hw.trezor.messages.common.PinMatrixRequest + (*PinMatrixAck)(nil), // 8: hw.trezor.messages.common.PinMatrixAck + (*PassphraseRequest)(nil), // 9: hw.trezor.messages.common.PassphraseRequest + (*PassphraseAck)(nil), // 10: hw.trezor.messages.common.PassphraseAck + (*PassphraseStateRequest)(nil), // 11: hw.trezor.messages.common.PassphraseStateRequest + (*PassphraseStateAck)(nil), // 12: hw.trezor.messages.common.PassphraseStateAck + (*HDNodeType)(nil), // 13: hw.trezor.messages.common.HDNodeType +} +var file_messages_common_proto_depIdxs = []int32{ + 0, // 0: hw.trezor.messages.common.Failure.code:type_name -> hw.trezor.messages.common.Failure.FailureType + 1, // 1: hw.trezor.messages.common.ButtonRequest.code:type_name -> hw.trezor.messages.common.ButtonRequest.ButtonRequestType + 2, // 2: hw.trezor.messages.common.PinMatrixRequest.type:type_name -> hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestType + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_messages_common_proto_init() } +func file_messages_common_proto_init() { + if File_messages_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_messages_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Success); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Failure); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PinMatrixRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PinMatrixAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassphraseRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassphraseAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassphraseStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassphraseStateAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_common_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HDNodeType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_common_proto_rawDesc, + NumEnums: 3, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_common_proto_goTypes, + DependencyIndexes: file_messages_common_proto_depIdxs, + EnumInfos: file_messages_common_proto_enumTypes, + MessageInfos: file_messages_common_proto_msgTypes, + }.Build() + File_messages_common_proto = out.File + file_messages_common_proto_rawDesc = nil + file_messages_common_proto_goTypes = nil + file_messages_common_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-common.proto b/accounts/usbwallet/trezor/messages-common.proto index 75a983b0a3..bb88c93be9 100644 --- a/accounts/usbwallet/trezor/messages-common.proto +++ b/accounts/usbwallet/trezor/messages-common.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.common; +option go_package = "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/trezor"; + /** * Response: Success of the previous request * @end diff --git a/accounts/usbwallet/trezor/messages-ethereum.pb.go b/accounts/usbwallet/trezor/messages-ethereum.pb.go index 5d664f5ba4..075b05bef0 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.pb.go +++ b/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.1 // source: messages-ethereum.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) //* // Request: Ask device for public key corresponding to address_n path @@ -27,48 +30,56 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // @next EthereumPublicKey // @next Failure type EthereumGetPublicKey struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` // optionally show on display before sending the result } -func (m *EthereumGetPublicKey) Reset() { *m = EthereumGetPublicKey{} } -func (m *EthereumGetPublicKey) String() string { return proto.CompactTextString(m) } -func (*EthereumGetPublicKey) ProtoMessage() {} +func (x *EthereumGetPublicKey) Reset() { + *x = EthereumGetPublicKey{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumGetPublicKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumGetPublicKey) ProtoMessage() {} + +func (x *EthereumGetPublicKey) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumGetPublicKey.ProtoReflect.Descriptor instead. func (*EthereumGetPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{0} + return file_messages_ethereum_proto_rawDescGZIP(), []int{0} } -func (m *EthereumGetPublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumGetPublicKey.Unmarshal(m, b) -} -func (m *EthereumGetPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumGetPublicKey.Marshal(b, m, deterministic) -} -func (m *EthereumGetPublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumGetPublicKey.Merge(m, src) -} -func (m *EthereumGetPublicKey) XXX_Size() int { - return xxx_messageInfo_EthereumGetPublicKey.Size(m) -} -func (m *EthereumGetPublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumGetPublicKey.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumGetPublicKey proto.InternalMessageInfo - -func (m *EthereumGetPublicKey) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumGetPublicKey) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumGetPublicKey) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay +func (x *EthereumGetPublicKey) GetShowDisplay() bool { + if x != nil && x.ShowDisplay != nil { + return *x.ShowDisplay } return false } @@ -77,48 +88,56 @@ func (m *EthereumGetPublicKey) GetShowDisplay() bool { // Response: Contains public key derived from device private seed // @end type EthereumPublicKey struct { - Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` - Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node *HDNodeType `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"` // BIP32 public node + Xpub *string `protobuf:"bytes,2,opt,name=xpub" json:"xpub,omitempty"` // serialized form of public node } -func (m *EthereumPublicKey) Reset() { *m = EthereumPublicKey{} } -func (m *EthereumPublicKey) String() string { return proto.CompactTextString(m) } -func (*EthereumPublicKey) ProtoMessage() {} +func (x *EthereumPublicKey) Reset() { + *x = EthereumPublicKey{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumPublicKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumPublicKey) ProtoMessage() {} + +func (x *EthereumPublicKey) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumPublicKey.ProtoReflect.Descriptor instead. func (*EthereumPublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{1} + return file_messages_ethereum_proto_rawDescGZIP(), []int{1} } -func (m *EthereumPublicKey) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumPublicKey.Unmarshal(m, b) -} -func (m *EthereumPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumPublicKey.Marshal(b, m, deterministic) -} -func (m *EthereumPublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumPublicKey.Merge(m, src) -} -func (m *EthereumPublicKey) XXX_Size() int { - return xxx_messageInfo_EthereumPublicKey.Size(m) -} -func (m *EthereumPublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumPublicKey.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumPublicKey proto.InternalMessageInfo - -func (m *EthereumPublicKey) GetNode() *HDNodeType { - if m != nil { - return m.Node +func (x *EthereumPublicKey) GetNode() *HDNodeType { + if x != nil { + return x.Node } return nil } -func (m *EthereumPublicKey) GetXpub() string { - if m != nil && m.Xpub != nil { - return *m.Xpub +func (x *EthereumPublicKey) GetXpub() string { + if x != nil && x.Xpub != nil { + return *x.Xpub } return "" } @@ -129,48 +148,56 @@ func (m *EthereumPublicKey) GetXpub() string { // @next EthereumAddress // @next Failure type EthereumGetAddress struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + ShowDisplay *bool `protobuf:"varint,2,opt,name=show_display,json=showDisplay" json:"show_display,omitempty"` // optionally show on display before sending the result } -func (m *EthereumGetAddress) Reset() { *m = EthereumGetAddress{} } -func (m *EthereumGetAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumGetAddress) ProtoMessage() {} +func (x *EthereumGetAddress) Reset() { + *x = EthereumGetAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumGetAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumGetAddress) ProtoMessage() {} + +func (x *EthereumGetAddress) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumGetAddress.ProtoReflect.Descriptor instead. func (*EthereumGetAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{2} + return file_messages_ethereum_proto_rawDescGZIP(), []int{2} } -func (m *EthereumGetAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumGetAddress.Unmarshal(m, b) -} -func (m *EthereumGetAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumGetAddress.Marshal(b, m, deterministic) -} -func (m *EthereumGetAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumGetAddress.Merge(m, src) -} -func (m *EthereumGetAddress) XXX_Size() int { - return xxx_messageInfo_EthereumGetAddress.Size(m) -} -func (m *EthereumGetAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumGetAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumGetAddress proto.InternalMessageInfo - -func (m *EthereumGetAddress) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumGetAddress) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumGetAddress) GetShowDisplay() bool { - if m != nil && m.ShowDisplay != nil { - return *m.ShowDisplay +func (x *EthereumGetAddress) GetShowDisplay() bool { + if x != nil && x.ShowDisplay != nil { + return *x.ShowDisplay } return false } @@ -179,48 +206,56 @@ func (m *EthereumGetAddress) GetShowDisplay() bool { // Response: Contains an Ethereum address derived from device private seed // @end type EthereumAddress struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // Ethereum address as 20 bytes (legacy firmwares) + AddressHex *string `protobuf:"bytes,2,opt,name=addressHex" json:"addressHex,omitempty"` // Ethereum address as hex string (newer firmwares) } -func (m *EthereumAddress) Reset() { *m = EthereumAddress{} } -func (m *EthereumAddress) String() string { return proto.CompactTextString(m) } -func (*EthereumAddress) ProtoMessage() {} +func (x *EthereumAddress) Reset() { + *x = EthereumAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumAddress) ProtoMessage() {} + +func (x *EthereumAddress) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumAddress.ProtoReflect.Descriptor instead. func (*EthereumAddress) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{3} + return file_messages_ethereum_proto_rawDescGZIP(), []int{3} } -func (m *EthereumAddress) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumAddress.Unmarshal(m, b) -} -func (m *EthereumAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumAddress.Marshal(b, m, deterministic) -} -func (m *EthereumAddress) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumAddress.Merge(m, src) -} -func (m *EthereumAddress) XXX_Size() int { - return xxx_messageInfo_EthereumAddress.Size(m) -} -func (m *EthereumAddress) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumAddress.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumAddress proto.InternalMessageInfo - -func (m *EthereumAddress) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumAddress) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumAddress) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumAddress) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } @@ -233,120 +268,128 @@ func (m *EthereumAddress) GetAddressHex() string { // @next EthereumTxRequest // @next Failure type EthereumSignTx struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` - GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` - GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` - ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` - ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` - Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` - DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` - DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` - TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + Nonce []byte `protobuf:"bytes,2,opt,name=nonce" json:"nonce,omitempty"` // <=256 bit unsigned big endian + GasPrice []byte `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice" json:"gas_price,omitempty"` // <=256 bit unsigned big endian (in wei) + GasLimit []byte `protobuf:"bytes,4,opt,name=gas_limit,json=gasLimit" json:"gas_limit,omitempty"` // <=256 bit unsigned big endian + ToBin []byte `protobuf:"bytes,5,opt,name=toBin" json:"toBin,omitempty"` // recipient address (20 bytes, legacy firmware) + ToHex *string `protobuf:"bytes,11,opt,name=toHex" json:"toHex,omitempty"` // recipient address (hex string, newer firmware) + Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"` // <=256 bit unsigned big endian (in wei) + DataInitialChunk []byte `protobuf:"bytes,7,opt,name=data_initial_chunk,json=dataInitialChunk" json:"data_initial_chunk,omitempty"` // The initial data chunk (<= 1024 bytes) + DataLength *uint32 `protobuf:"varint,8,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` // Length of transaction payload + ChainId *uint32 `protobuf:"varint,9,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` // Chain Id for EIP 155 + TxType *uint32 `protobuf:"varint,10,opt,name=tx_type,json=txType" json:"tx_type,omitempty"` // (only for Wanchain) } -func (m *EthereumSignTx) Reset() { *m = EthereumSignTx{} } -func (m *EthereumSignTx) String() string { return proto.CompactTextString(m) } -func (*EthereumSignTx) ProtoMessage() {} +func (x *EthereumSignTx) Reset() { + *x = EthereumSignTx{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumSignTx) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumSignTx) ProtoMessage() {} + +func (x *EthereumSignTx) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumSignTx.ProtoReflect.Descriptor instead. func (*EthereumSignTx) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{4} + return file_messages_ethereum_proto_rawDescGZIP(), []int{4} } -func (m *EthereumSignTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignTx.Unmarshal(m, b) -} -func (m *EthereumSignTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignTx.Marshal(b, m, deterministic) -} -func (m *EthereumSignTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignTx.Merge(m, src) -} -func (m *EthereumSignTx) XXX_Size() int { - return xxx_messageInfo_EthereumSignTx.Size(m) -} -func (m *EthereumSignTx) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignTx.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumSignTx proto.InternalMessageInfo - -func (m *EthereumSignTx) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumSignTx) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumSignTx) GetNonce() []byte { - if m != nil { - return m.Nonce +func (x *EthereumSignTx) GetNonce() []byte { + if x != nil { + return x.Nonce } return nil } -func (m *EthereumSignTx) GetGasPrice() []byte { - if m != nil { - return m.GasPrice +func (x *EthereumSignTx) GetGasPrice() []byte { + if x != nil { + return x.GasPrice } return nil } -func (m *EthereumSignTx) GetGasLimit() []byte { - if m != nil { - return m.GasLimit +func (x *EthereumSignTx) GetGasLimit() []byte { + if x != nil { + return x.GasLimit } return nil } -func (m *EthereumSignTx) GetToBin() []byte { - if m != nil { - return m.ToBin +func (x *EthereumSignTx) GetToBin() []byte { + if x != nil { + return x.ToBin } return nil } -func (m *EthereumSignTx) GetToHex() string { - if m != nil && m.ToHex != nil { - return *m.ToHex +func (x *EthereumSignTx) GetToHex() string { + if x != nil && x.ToHex != nil { + return *x.ToHex } return "" } -func (m *EthereumSignTx) GetValue() []byte { - if m != nil { - return m.Value +func (x *EthereumSignTx) GetValue() []byte { + if x != nil { + return x.Value } return nil } -func (m *EthereumSignTx) GetDataInitialChunk() []byte { - if m != nil { - return m.DataInitialChunk +func (x *EthereumSignTx) GetDataInitialChunk() []byte { + if x != nil { + return x.DataInitialChunk } return nil } -func (m *EthereumSignTx) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength +func (x *EthereumSignTx) GetDataLength() uint32 { + if x != nil && x.DataLength != nil { + return *x.DataLength } return 0 } -func (m *EthereumSignTx) GetChainId() uint32 { - if m != nil && m.ChainId != nil { - return *m.ChainId +func (x *EthereumSignTx) GetChainId() uint32 { + if x != nil && x.ChainId != nil { + return *x.ChainId } return 0 } -func (m *EthereumSignTx) GetTxType() uint32 { - if m != nil && m.TxType != nil { - return *m.TxType +func (x *EthereumSignTx) GetTxType() uint32 { + if x != nil && x.TxType != nil { + return *x.TxType } return 0 } @@ -358,64 +401,72 @@ func (m *EthereumSignTx) GetTxType() uint32 { // @end // @next EthereumTxAck type EthereumTxRequest struct { - DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` - SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` - SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` - SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DataLength *uint32 `protobuf:"varint,1,opt,name=data_length,json=dataLength" json:"data_length,omitempty"` // Number of bytes being requested (<= 1024) + SignatureV *uint32 `protobuf:"varint,2,opt,name=signature_v,json=signatureV" json:"signature_v,omitempty"` // Computed signature (recovery parameter, limited to 27 or 28) + SignatureR []byte `protobuf:"bytes,3,opt,name=signature_r,json=signatureR" json:"signature_r,omitempty"` // Computed signature R component (256 bit) + SignatureS []byte `protobuf:"bytes,4,opt,name=signature_s,json=signatureS" json:"signature_s,omitempty"` // Computed signature S component (256 bit) } -func (m *EthereumTxRequest) Reset() { *m = EthereumTxRequest{} } -func (m *EthereumTxRequest) String() string { return proto.CompactTextString(m) } -func (*EthereumTxRequest) ProtoMessage() {} +func (x *EthereumTxRequest) Reset() { + *x = EthereumTxRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumTxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumTxRequest) ProtoMessage() {} + +func (x *EthereumTxRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumTxRequest.ProtoReflect.Descriptor instead. func (*EthereumTxRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{5} + return file_messages_ethereum_proto_rawDescGZIP(), []int{5} } -func (m *EthereumTxRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxRequest.Unmarshal(m, b) -} -func (m *EthereumTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxRequest.Marshal(b, m, deterministic) -} -func (m *EthereumTxRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxRequest.Merge(m, src) -} -func (m *EthereumTxRequest) XXX_Size() int { - return xxx_messageInfo_EthereumTxRequest.Size(m) -} -func (m *EthereumTxRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumTxRequest proto.InternalMessageInfo - -func (m *EthereumTxRequest) GetDataLength() uint32 { - if m != nil && m.DataLength != nil { - return *m.DataLength +func (x *EthereumTxRequest) GetDataLength() uint32 { + if x != nil && x.DataLength != nil { + return *x.DataLength } return 0 } -func (m *EthereumTxRequest) GetSignatureV() uint32 { - if m != nil && m.SignatureV != nil { - return *m.SignatureV +func (x *EthereumTxRequest) GetSignatureV() uint32 { + if x != nil && x.SignatureV != nil { + return *x.SignatureV } return 0 } -func (m *EthereumTxRequest) GetSignatureR() []byte { - if m != nil { - return m.SignatureR +func (x *EthereumTxRequest) GetSignatureR() []byte { + if x != nil { + return x.SignatureR } return nil } -func (m *EthereumTxRequest) GetSignatureS() []byte { - if m != nil { - return m.SignatureS +func (x *EthereumTxRequest) GetSignatureS() []byte { + if x != nil { + return x.SignatureS } return nil } @@ -424,40 +475,48 @@ func (m *EthereumTxRequest) GetSignatureS() []byte { // Request: Transaction payload data. // @next EthereumTxRequest type EthereumTxAck struct { - DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DataChunk []byte `protobuf:"bytes,1,opt,name=data_chunk,json=dataChunk" json:"data_chunk,omitempty"` // Bytes from transaction payload (<= 1024 bytes) } -func (m *EthereumTxAck) Reset() { *m = EthereumTxAck{} } -func (m *EthereumTxAck) String() string { return proto.CompactTextString(m) } -func (*EthereumTxAck) ProtoMessage() {} +func (x *EthereumTxAck) Reset() { + *x = EthereumTxAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumTxAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumTxAck) ProtoMessage() {} + +func (x *EthereumTxAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumTxAck.ProtoReflect.Descriptor instead. func (*EthereumTxAck) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{6} + return file_messages_ethereum_proto_rawDescGZIP(), []int{6} } -func (m *EthereumTxAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumTxAck.Unmarshal(m, b) -} -func (m *EthereumTxAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumTxAck.Marshal(b, m, deterministic) -} -func (m *EthereumTxAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumTxAck.Merge(m, src) -} -func (m *EthereumTxAck) XXX_Size() int { - return xxx_messageInfo_EthereumTxAck.Size(m) -} -func (m *EthereumTxAck) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumTxAck.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumTxAck proto.InternalMessageInfo - -func (m *EthereumTxAck) GetDataChunk() []byte { - if m != nil { - return m.DataChunk +func (x *EthereumTxAck) GetDataChunk() []byte { + if x != nil { + return x.DataChunk } return nil } @@ -468,48 +527,56 @@ func (m *EthereumTxAck) GetDataChunk() []byte { // @next EthereumMessageSignature // @next Failure type EthereumSignMessage struct { - AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node + Message []byte `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` // message to be signed } -func (m *EthereumSignMessage) Reset() { *m = EthereumSignMessage{} } -func (m *EthereumSignMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumSignMessage) ProtoMessage() {} +func (x *EthereumSignMessage) Reset() { + *x = EthereumSignMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumSignMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumSignMessage) ProtoMessage() {} + +func (x *EthereumSignMessage) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumSignMessage.ProtoReflect.Descriptor instead. func (*EthereumSignMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{7} + return file_messages_ethereum_proto_rawDescGZIP(), []int{7} } -func (m *EthereumSignMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumSignMessage.Unmarshal(m, b) -} -func (m *EthereumSignMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumSignMessage.Marshal(b, m, deterministic) -} -func (m *EthereumSignMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumSignMessage.Merge(m, src) -} -func (m *EthereumSignMessage) XXX_Size() int { - return xxx_messageInfo_EthereumSignMessage.Size(m) -} -func (m *EthereumSignMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumSignMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumSignMessage proto.InternalMessageInfo - -func (m *EthereumSignMessage) GetAddressN() []uint32 { - if m != nil { - return m.AddressN +func (x *EthereumSignMessage) GetAddressN() []uint32 { + if x != nil { + return x.AddressN } return nil } -func (m *EthereumSignMessage) GetMessage() []byte { - if m != nil { - return m.Message +func (x *EthereumSignMessage) GetMessage() []byte { + if x != nil { + return x.Message } return nil } @@ -518,56 +585,64 @@ func (m *EthereumSignMessage) GetMessage() []byte { // Response: Signed message // @end type EthereumMessageSignature struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // address used to sign the message (20 bytes, legacy firmware) + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` // signature of the message + AddressHex *string `protobuf:"bytes,3,opt,name=addressHex" json:"addressHex,omitempty"` // address used to sign the message (hex string, newer firmware) } -func (m *EthereumMessageSignature) Reset() { *m = EthereumMessageSignature{} } -func (m *EthereumMessageSignature) String() string { return proto.CompactTextString(m) } -func (*EthereumMessageSignature) ProtoMessage() {} +func (x *EthereumMessageSignature) Reset() { + *x = EthereumMessageSignature{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumMessageSignature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumMessageSignature) ProtoMessage() {} + +func (x *EthereumMessageSignature) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumMessageSignature.ProtoReflect.Descriptor instead. func (*EthereumMessageSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{8} + return file_messages_ethereum_proto_rawDescGZIP(), []int{8} } -func (m *EthereumMessageSignature) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumMessageSignature.Unmarshal(m, b) -} -func (m *EthereumMessageSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumMessageSignature.Marshal(b, m, deterministic) -} -func (m *EthereumMessageSignature) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumMessageSignature.Merge(m, src) -} -func (m *EthereumMessageSignature) XXX_Size() int { - return xxx_messageInfo_EthereumMessageSignature.Size(m) -} -func (m *EthereumMessageSignature) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumMessageSignature.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumMessageSignature proto.InternalMessageInfo - -func (m *EthereumMessageSignature) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumMessageSignature) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumMessageSignature) GetSignature() []byte { - if m != nil { - return m.Signature +func (x *EthereumMessageSignature) GetSignature() []byte { + if x != nil { + return x.Signature } return nil } -func (m *EthereumMessageSignature) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumMessageSignature) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } @@ -578,121 +653,350 @@ func (m *EthereumMessageSignature) GetAddressHex() string { // @next Success // @next Failure type EthereumVerifyMessage struct { - AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddressBin []byte `protobuf:"bytes,1,opt,name=addressBin" json:"addressBin,omitempty"` // address to verify (20 bytes, legacy firmware) + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` // signature to verify + Message []byte `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` // message to verify + AddressHex *string `protobuf:"bytes,4,opt,name=addressHex" json:"addressHex,omitempty"` // address to verify (hex string, newer firmware) } -func (m *EthereumVerifyMessage) Reset() { *m = EthereumVerifyMessage{} } -func (m *EthereumVerifyMessage) String() string { return proto.CompactTextString(m) } -func (*EthereumVerifyMessage) ProtoMessage() {} +func (x *EthereumVerifyMessage) Reset() { + *x = EthereumVerifyMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_ethereum_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EthereumVerifyMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EthereumVerifyMessage) ProtoMessage() {} + +func (x *EthereumVerifyMessage) ProtoReflect() protoreflect.Message { + mi := &file_messages_ethereum_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EthereumVerifyMessage.ProtoReflect.Descriptor instead. func (*EthereumVerifyMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_cb33f46ba915f15c, []int{9} + return file_messages_ethereum_proto_rawDescGZIP(), []int{9} } -func (m *EthereumVerifyMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EthereumVerifyMessage.Unmarshal(m, b) -} -func (m *EthereumVerifyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EthereumVerifyMessage.Marshal(b, m, deterministic) -} -func (m *EthereumVerifyMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_EthereumVerifyMessage.Merge(m, src) -} -func (m *EthereumVerifyMessage) XXX_Size() int { - return xxx_messageInfo_EthereumVerifyMessage.Size(m) -} -func (m *EthereumVerifyMessage) XXX_DiscardUnknown() { - xxx_messageInfo_EthereumVerifyMessage.DiscardUnknown(m) -} - -var xxx_messageInfo_EthereumVerifyMessage proto.InternalMessageInfo - -func (m *EthereumVerifyMessage) GetAddressBin() []byte { - if m != nil { - return m.AddressBin +func (x *EthereumVerifyMessage) GetAddressBin() []byte { + if x != nil { + return x.AddressBin } return nil } -func (m *EthereumVerifyMessage) GetSignature() []byte { - if m != nil { - return m.Signature +func (x *EthereumVerifyMessage) GetSignature() []byte { + if x != nil { + return x.Signature } return nil } -func (m *EthereumVerifyMessage) GetMessage() []byte { - if m != nil { - return m.Message +func (x *EthereumVerifyMessage) GetMessage() []byte { + if x != nil { + return x.Message } return nil } -func (m *EthereumVerifyMessage) GetAddressHex() string { - if m != nil && m.AddressHex != nil { - return *m.AddressHex +func (x *EthereumVerifyMessage) GetAddressHex() string { + if x != nil && x.AddressHex != nil { + return *x.AddressHex } return "" } -func init() { - proto.RegisterType((*EthereumGetPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumGetPublicKey") - proto.RegisterType((*EthereumPublicKey)(nil), "hw.trezor.messages.ethereum.EthereumPublicKey") - proto.RegisterType((*EthereumGetAddress)(nil), "hw.trezor.messages.ethereum.EthereumGetAddress") - proto.RegisterType((*EthereumAddress)(nil), "hw.trezor.messages.ethereum.EthereumAddress") - proto.RegisterType((*EthereumSignTx)(nil), "hw.trezor.messages.ethereum.EthereumSignTx") - proto.RegisterType((*EthereumTxRequest)(nil), "hw.trezor.messages.ethereum.EthereumTxRequest") - proto.RegisterType((*EthereumTxAck)(nil), "hw.trezor.messages.ethereum.EthereumTxAck") - proto.RegisterType((*EthereumSignMessage)(nil), "hw.trezor.messages.ethereum.EthereumSignMessage") - proto.RegisterType((*EthereumMessageSignature)(nil), "hw.trezor.messages.ethereum.EthereumMessageSignature") - proto.RegisterType((*EthereumVerifyMessage)(nil), "hw.trezor.messages.ethereum.EthereumVerifyMessage") +var File_messages_ethereum_proto protoreflect.FileDescriptor + +var file_messages_ethereum_proto_rawDesc = []byte{ + 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x1a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, + 0x14, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x77, 0x44, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, 0x62, 0x0a, 0x11, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, + 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x70, 0x75, 0x62, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x78, 0x70, 0x75, 0x62, 0x22, 0x54, 0x0a, 0x12, 0x45, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x4e, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x73, 0x68, 0x6f, 0x77, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, + 0x51, 0x0a, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, + 0x69, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, + 0x65, 0x78, 0x22, 0xc2, 0x02, 0x0a, 0x0e, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, + 0x69, 0x67, 0x6e, 0x54, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, + 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x42, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x42, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x48, 0x65, + 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x48, 0x65, 0x78, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x10, 0x64, 0x61, 0x74, 0x61, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x75, + 0x6e, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x17, + 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x74, 0x78, 0x54, 0x79, 0x70, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x11, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x12, + 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, + 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x22, 0x2e, 0x0a, 0x0d, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x43, 0x68, 0x75, 0x6e, + 0x6b, 0x22, 0x4c, 0x0a, 0x13, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, 0x69, 0x67, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x5f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x08, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x78, 0x0a, 0x18, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x22, 0x8f, 0x01, 0x0a, 0x15, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x69, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x42, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x65, 0x78, 0x42, 0x77, 0x0a, 0x23, 0x63, + 0x6f, 0x6d, 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, + 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x42, 0x15, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, + 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, } -func init() { proto.RegisterFile("messages-ethereum.proto", fileDescriptor_cb33f46ba915f15c) } +var ( + file_messages_ethereum_proto_rawDescOnce sync.Once + file_messages_ethereum_proto_rawDescData = file_messages_ethereum_proto_rawDesc +) -var fileDescriptor_cb33f46ba915f15c = []byte{ - // 593 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, - 0x10, 0x95, 0x9b, 0xb4, 0x49, 0x26, 0x0d, 0x1f, 0xa6, 0x55, 0x17, 0x0a, 0x34, 0x18, 0x21, 0xe5, - 0x00, 0x3e, 0x70, 0x43, 0xe2, 0xd2, 0x52, 0x44, 0x2b, 0x4a, 0x55, 0xdc, 0xa8, 0x57, 0x6b, 0x63, - 0x6f, 0xe3, 0x55, 0x9d, 0xdd, 0xe0, 0x5d, 0xb7, 0x0e, 0x7f, 0x82, 0x23, 0xff, 0x87, 0x5f, 0x86, - 0xf6, 0x2b, 0x71, 0x52, 0x54, 0x0e, 0xbd, 0x65, 0xde, 0xbc, 0x7d, 0xf3, 0x66, 0xf4, 0x62, 0xd8, - 0x99, 0x10, 0x21, 0xf0, 0x98, 0x88, 0x77, 0x44, 0x66, 0xa4, 0x20, 0xe5, 0x24, 0x9c, 0x16, 0x5c, - 0x72, 0x7f, 0x37, 0xbb, 0x09, 0x65, 0x41, 0x7e, 0xf2, 0x22, 0x74, 0x94, 0xd0, 0x51, 0x9e, 0x6d, - 0xcf, 0x5f, 0x25, 0x7c, 0x32, 0xe1, 0xcc, 0xbc, 0x09, 0x2e, 0x60, 0xeb, 0xb3, 0xa5, 0x7c, 0x21, - 0xf2, 0xac, 0x1c, 0xe5, 0x34, 0xf9, 0x4a, 0x66, 0xfe, 0x2e, 0x74, 0x70, 0x9a, 0x16, 0x44, 0x88, - 0x98, 0x21, 0xaf, 0xdf, 0x18, 0xf4, 0xa2, 0xb6, 0x05, 0x4e, 0xfd, 0x57, 0xb0, 0x29, 0x32, 0x7e, - 0x13, 0xa7, 0x54, 0x4c, 0x73, 0x3c, 0x43, 0x6b, 0x7d, 0x6f, 0xd0, 0x8e, 0xba, 0x0a, 0x3b, 0x34, - 0x50, 0x30, 0x82, 0xc7, 0x4e, 0x77, 0x21, 0xfa, 0x01, 0x9a, 0x8c, 0xa7, 0x04, 0x79, 0x7d, 0x6f, - 0xd0, 0x7d, 0xff, 0x26, 0xfc, 0x87, 0x5f, 0x6b, 0xee, 0xe8, 0xf0, 0x94, 0xa7, 0x64, 0x38, 0x9b, - 0x92, 0x48, 0x3f, 0xf1, 0x7d, 0x68, 0x56, 0xd3, 0x72, 0xa4, 0x47, 0x75, 0x22, 0xfd, 0x3b, 0x18, - 0x82, 0x5f, 0xf3, 0xbe, 0x6f, 0xdc, 0xdd, 0xdb, 0xf9, 0x77, 0x78, 0xe8, 0x54, 0x9d, 0xe4, 0x4b, - 0x00, 0xab, 0x70, 0x40, 0x99, 0x76, 0xbf, 0x19, 0xd5, 0x90, 0x5a, 0xff, 0x88, 0x54, 0xd6, 0x62, - 0x0d, 0x09, 0xfe, 0xac, 0xc1, 0x03, 0xa7, 0x79, 0x4e, 0xc7, 0x6c, 0x58, 0xdd, 0xed, 0x72, 0x0b, - 0xd6, 0x19, 0x67, 0x09, 0xd1, 0x52, 0x9b, 0x91, 0x29, 0xd4, 0x93, 0x31, 0x16, 0xf1, 0xb4, 0xa0, - 0x09, 0x41, 0x0d, 0xdd, 0x69, 0x8f, 0xb1, 0x38, 0x53, 0xb5, 0x6b, 0xe6, 0x74, 0x42, 0x25, 0x6a, - 0xce, 0x9b, 0x27, 0xaa, 0x56, 0x7a, 0x92, 0x2b, 0xeb, 0xeb, 0x46, 0x4f, 0x17, 0x06, 0x55, 0x86, - 0xbb, 0xda, 0xb0, 0x29, 0x14, 0x7a, 0x8d, 0xf3, 0x92, 0xa0, 0x0d, 0xc3, 0xd5, 0x85, 0xff, 0x16, - 0xfc, 0x14, 0x4b, 0x1c, 0x53, 0x46, 0x25, 0xc5, 0x79, 0x9c, 0x64, 0x25, 0xbb, 0x42, 0x2d, 0x4d, - 0x79, 0xa4, 0x3a, 0xc7, 0xa6, 0xf1, 0x49, 0xe1, 0xfe, 0x1e, 0x74, 0x35, 0x3b, 0x27, 0x6c, 0x2c, - 0x33, 0xd4, 0xee, 0x7b, 0x83, 0x5e, 0x04, 0x0a, 0x3a, 0xd1, 0x88, 0xff, 0x14, 0xda, 0x49, 0x86, - 0x29, 0x8b, 0x69, 0x8a, 0x3a, 0xba, 0xdb, 0xd2, 0xf5, 0x71, 0xea, 0xef, 0x40, 0x4b, 0x56, 0xb1, - 0x9c, 0x4d, 0x09, 0x02, 0xdd, 0xd9, 0x90, 0x95, 0xca, 0x41, 0xf0, 0xdb, 0x5b, 0x44, 0x6a, 0x58, - 0x45, 0xe4, 0x47, 0x49, 0x84, 0x5c, 0x1d, 0xe5, 0xdd, 0x1a, 0xb5, 0x07, 0x5d, 0x41, 0xc7, 0x0c, - 0xcb, 0xb2, 0x20, 0xf1, 0xb5, 0xbe, 0x68, 0x2f, 0x82, 0x39, 0x74, 0xb1, 0x4c, 0x28, 0xec, 0x61, - 0x17, 0x84, 0x68, 0x99, 0x20, 0xec, 0x71, 0x17, 0x84, 0xf3, 0x20, 0x84, 0xde, 0xc2, 0xd8, 0x7e, - 0x72, 0xe5, 0xbf, 0x00, 0xed, 0xc0, 0x5e, 0xc9, 0xe4, 0xa5, 0xa3, 0x10, 0x7d, 0x9e, 0xe0, 0x04, - 0x9e, 0xd4, 0xd3, 0xf0, 0xcd, 0x64, 0xff, 0xee, 0x48, 0x20, 0x68, 0xd9, 0xff, 0x88, 0x0d, 0x85, - 0x2b, 0x83, 0x0a, 0x90, 0x53, 0xb3, 0x4a, 0xe7, 0xce, 0xda, 0x7f, 0x83, 0xfb, 0x1c, 0x3a, 0xf3, - 0x3d, 0xac, 0xee, 0x02, 0x58, 0x89, 0x75, 0xe3, 0x56, 0xac, 0x7f, 0x79, 0xb0, 0xed, 0x46, 0x5f, - 0x90, 0x82, 0x5e, 0xce, 0xdc, 0x2a, 0xf7, 0x9b, 0x5b, 0xdb, 0xb5, 0xb1, 0xb4, 0xeb, 0x8a, 0xa3, - 0xe6, 0xaa, 0xa3, 0x83, 0x8f, 0xf0, 0x3a, 0xe1, 0x93, 0x50, 0x60, 0xc9, 0x45, 0x46, 0x73, 0x3c, - 0x12, 0xee, 0x03, 0x93, 0xd3, 0x91, 0xf9, 0xe2, 0x8d, 0xca, 0xcb, 0x83, 0xed, 0xa1, 0x06, 0xad, - 0x5b, 0xb7, 0xc2, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xce, 0x81, 0xc8, 0x59, 0x05, 0x00, - 0x00, +func file_messages_ethereum_proto_rawDescGZIP() []byte { + file_messages_ethereum_proto_rawDescOnce.Do(func() { + file_messages_ethereum_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_ethereum_proto_rawDescData) + }) + return file_messages_ethereum_proto_rawDescData +} + +var file_messages_ethereum_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_messages_ethereum_proto_goTypes = []interface{}{ + (*EthereumGetPublicKey)(nil), // 0: hw.trezor.messages.ethereum.EthereumGetPublicKey + (*EthereumPublicKey)(nil), // 1: hw.trezor.messages.ethereum.EthereumPublicKey + (*EthereumGetAddress)(nil), // 2: hw.trezor.messages.ethereum.EthereumGetAddress + (*EthereumAddress)(nil), // 3: hw.trezor.messages.ethereum.EthereumAddress + (*EthereumSignTx)(nil), // 4: hw.trezor.messages.ethereum.EthereumSignTx + (*EthereumTxRequest)(nil), // 5: hw.trezor.messages.ethereum.EthereumTxRequest + (*EthereumTxAck)(nil), // 6: hw.trezor.messages.ethereum.EthereumTxAck + (*EthereumSignMessage)(nil), // 7: hw.trezor.messages.ethereum.EthereumSignMessage + (*EthereumMessageSignature)(nil), // 8: hw.trezor.messages.ethereum.EthereumMessageSignature + (*EthereumVerifyMessage)(nil), // 9: hw.trezor.messages.ethereum.EthereumVerifyMessage + (*HDNodeType)(nil), // 10: hw.trezor.messages.common.HDNodeType +} +var file_messages_ethereum_proto_depIdxs = []int32{ + 10, // 0: hw.trezor.messages.ethereum.EthereumPublicKey.node:type_name -> hw.trezor.messages.common.HDNodeType + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_messages_ethereum_proto_init() } +func file_messages_ethereum_proto_init() { + if File_messages_ethereum_proto != nil { + return + } + file_messages_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_messages_ethereum_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumGetPublicKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumPublicKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumGetAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumSignTx); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumTxRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumTxAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumSignMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumMessageSignature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_ethereum_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EthereumVerifyMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_ethereum_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_ethereum_proto_goTypes, + DependencyIndexes: file_messages_ethereum_proto_depIdxs, + MessageInfos: file_messages_ethereum_proto_msgTypes, + }.Build() + File_messages_ethereum_proto = out.File + file_messages_ethereum_proto_rawDesc = nil + file_messages_ethereum_proto_goTypes = nil + file_messages_ethereum_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-ethereum.proto b/accounts/usbwallet/trezor/messages-ethereum.proto index 096bed2e4a..a53902a3ec 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.proto +++ b/accounts/usbwallet/trezor/messages-ethereum.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.ethereum; +option go_package = "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageEthereum"; diff --git a/accounts/usbwallet/trezor/messages-management.pb.go b/accounts/usbwallet/trezor/messages-management.pb.go index f5c872f1fb..b27fe67519 100644 --- a/accounts/usbwallet/trezor/messages-management.pb.go +++ b/accounts/usbwallet/trezor/messages-management.pb.go @@ -1,25 +1,28 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages-management.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.1 // source: messages-management.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) //* // Structure representing passphrase source @@ -31,17 +34,19 @@ const ( ApplySettings_HOST ApplySettings_PassphraseSourceType = 2 ) -var ApplySettings_PassphraseSourceType_name = map[int32]string{ - 0: "ASK", - 1: "DEVICE", - 2: "HOST", -} - -var ApplySettings_PassphraseSourceType_value = map[string]int32{ - "ASK": 0, - "DEVICE": 1, - "HOST": 2, -} +// Enum value maps for ApplySettings_PassphraseSourceType. +var ( + ApplySettings_PassphraseSourceType_name = map[int32]string{ + 0: "ASK", + 1: "DEVICE", + 2: "HOST", + } + ApplySettings_PassphraseSourceType_value = map[string]int32{ + "ASK": 0, + "DEVICE": 1, + "HOST": 2, + } +) func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSourceType { p := new(ApplySettings_PassphraseSourceType) @@ -50,20 +55,34 @@ func (x ApplySettings_PassphraseSourceType) Enum() *ApplySettings_PassphraseSour } func (x ApplySettings_PassphraseSourceType) String() string { - return proto.EnumName(ApplySettings_PassphraseSourceType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(ApplySettings_PassphraseSourceType_value, data, "ApplySettings_PassphraseSourceType") +func (ApplySettings_PassphraseSourceType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[0].Descriptor() +} + +func (ApplySettings_PassphraseSourceType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[0] +} + +func (x ApplySettings_PassphraseSourceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ApplySettings_PassphraseSourceType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = ApplySettings_PassphraseSourceType(value) + *x = ApplySettings_PassphraseSourceType(num) return nil } +// Deprecated: Use ApplySettings_PassphraseSourceType.Descriptor instead. func (ApplySettings_PassphraseSourceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{4, 0} + return file_messages_management_proto_rawDescGZIP(), []int{4, 0} } //* @@ -77,19 +96,21 @@ type RecoveryDevice_RecoveryDeviceType int32 const ( // use powers of two when extending this field - RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 - RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 + RecoveryDevice_RecoveryDeviceType_ScrambledWords RecoveryDevice_RecoveryDeviceType = 0 // words in scrambled order + RecoveryDevice_RecoveryDeviceType_Matrix RecoveryDevice_RecoveryDeviceType = 1 // matrix recovery type ) -var RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ - 0: "RecoveryDeviceType_ScrambledWords", - 1: "RecoveryDeviceType_Matrix", -} - -var RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ - "RecoveryDeviceType_ScrambledWords": 0, - "RecoveryDeviceType_Matrix": 1, -} +// Enum value maps for RecoveryDevice_RecoveryDeviceType. +var ( + RecoveryDevice_RecoveryDeviceType_name = map[int32]string{ + 0: "RecoveryDeviceType_ScrambledWords", + 1: "RecoveryDeviceType_Matrix", + } + RecoveryDevice_RecoveryDeviceType_value = map[string]int32{ + "RecoveryDeviceType_ScrambledWords": 0, + "RecoveryDeviceType_Matrix": 1, + } +) func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDeviceType { p := new(RecoveryDevice_RecoveryDeviceType) @@ -98,20 +119,34 @@ func (x RecoveryDevice_RecoveryDeviceType) Enum() *RecoveryDevice_RecoveryDevice } func (x RecoveryDevice_RecoveryDeviceType) String() string { - return proto.EnumName(RecoveryDevice_RecoveryDeviceType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(RecoveryDevice_RecoveryDeviceType_value, data, "RecoveryDevice_RecoveryDeviceType") +func (RecoveryDevice_RecoveryDeviceType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[1].Descriptor() +} + +func (RecoveryDevice_RecoveryDeviceType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[1] +} + +func (x RecoveryDevice_RecoveryDeviceType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *RecoveryDevice_RecoveryDeviceType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = RecoveryDevice_RecoveryDeviceType(value) + *x = RecoveryDevice_RecoveryDeviceType(num) return nil } +// Deprecated: Use RecoveryDevice_RecoveryDeviceType.Descriptor instead. func (RecoveryDevice_RecoveryDeviceType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{17, 0} + return file_messages_management_proto_rawDescGZIP(), []int{17, 0} } //* @@ -124,17 +159,19 @@ const ( WordRequest_WordRequestType_Matrix6 WordRequest_WordRequestType = 2 ) -var WordRequest_WordRequestType_name = map[int32]string{ - 0: "WordRequestType_Plain", - 1: "WordRequestType_Matrix9", - 2: "WordRequestType_Matrix6", -} - -var WordRequest_WordRequestType_value = map[string]int32{ - "WordRequestType_Plain": 0, - "WordRequestType_Matrix9": 1, - "WordRequestType_Matrix6": 2, -} +// Enum value maps for WordRequest_WordRequestType. +var ( + WordRequest_WordRequestType_name = map[int32]string{ + 0: "WordRequestType_Plain", + 1: "WordRequestType_Matrix9", + 2: "WordRequestType_Matrix6", + } + WordRequest_WordRequestType_value = map[string]int32{ + "WordRequestType_Plain": 0, + "WordRequestType_Matrix9": 1, + "WordRequestType_Matrix6": 2, + } +) func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { p := new(WordRequest_WordRequestType) @@ -143,20 +180,34 @@ func (x WordRequest_WordRequestType) Enum() *WordRequest_WordRequestType { } func (x WordRequest_WordRequestType) String() string { - return proto.EnumName(WordRequest_WordRequestType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *WordRequest_WordRequestType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(WordRequest_WordRequestType_value, data, "WordRequest_WordRequestType") +func (WordRequest_WordRequestType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_management_proto_enumTypes[2].Descriptor() +} + +func (WordRequest_WordRequestType) Type() protoreflect.EnumType { + return &file_messages_management_proto_enumTypes[2] +} + +func (x WordRequest_WordRequestType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WordRequest_WordRequestType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = WordRequest_WordRequestType(value) + *x = WordRequest_WordRequestType(num) return nil } +// Deprecated: Use WordRequest_WordRequestType.Descriptor instead. func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{18, 0} + return file_messages_management_proto_rawDescGZIP(), []int{18, 0} } //* @@ -164,48 +215,56 @@ func (WordRequest_WordRequestType) EnumDescriptor() ([]byte, []int) { // @start // @next Features type Initialize struct { - State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` - SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // assumed device state, clear session if set and different + SkipPassphrase *bool `protobuf:"varint,2,opt,name=skip_passphrase,json=skipPassphrase" json:"skip_passphrase,omitempty"` // this session should always assume empty passphrase } -func (m *Initialize) Reset() { *m = Initialize{} } -func (m *Initialize) String() string { return proto.CompactTextString(m) } -func (*Initialize) ProtoMessage() {} +func (x *Initialize) Reset() { + *x = Initialize{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Initialize) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Initialize) ProtoMessage() {} + +func (x *Initialize) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Initialize.ProtoReflect.Descriptor instead. func (*Initialize) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{0} + return file_messages_management_proto_rawDescGZIP(), []int{0} } -func (m *Initialize) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Initialize.Unmarshal(m, b) -} -func (m *Initialize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Initialize.Marshal(b, m, deterministic) -} -func (m *Initialize) XXX_Merge(src proto.Message) { - xxx_messageInfo_Initialize.Merge(m, src) -} -func (m *Initialize) XXX_Size() int { - return xxx_messageInfo_Initialize.Size(m) -} -func (m *Initialize) XXX_DiscardUnknown() { - xxx_messageInfo_Initialize.DiscardUnknown(m) -} - -var xxx_messageInfo_Initialize proto.InternalMessageInfo - -func (m *Initialize) GetState() []byte { - if m != nil { - return m.State +func (x *Initialize) GetState() []byte { + if x != nil { + return x.State } return nil } -func (m *Initialize) GetSkipPassphrase() bool { - if m != nil && m.SkipPassphrase != nil { - return *m.SkipPassphrase +func (x *Initialize) GetSkipPassphrase() bool { + if x != nil && x.SkipPassphrase != nil { + return *x.SkipPassphrase } return false } @@ -215,282 +274,297 @@ func (m *Initialize) GetSkipPassphrase() bool { // @start // @next Features type GetFeatures struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *GetFeatures) Reset() { *m = GetFeatures{} } -func (m *GetFeatures) String() string { return proto.CompactTextString(m) } -func (*GetFeatures) ProtoMessage() {} +func (x *GetFeatures) Reset() { + *x = GetFeatures{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetFeatures) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetFeatures) ProtoMessage() {} + +func (x *GetFeatures) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetFeatures.ProtoReflect.Descriptor instead. func (*GetFeatures) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{1} + return file_messages_management_proto_rawDescGZIP(), []int{1} } -func (m *GetFeatures) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetFeatures.Unmarshal(m, b) -} -func (m *GetFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetFeatures.Marshal(b, m, deterministic) -} -func (m *GetFeatures) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetFeatures.Merge(m, src) -} -func (m *GetFeatures) XXX_Size() int { - return xxx_messageInfo_GetFeatures.Size(m) -} -func (m *GetFeatures) XXX_DiscardUnknown() { - xxx_messageInfo_GetFeatures.DiscardUnknown(m) -} - -var xxx_messageInfo_GetFeatures proto.InternalMessageInfo - -//* +// * // Response: Reports various information about the device // @end type Features struct { - Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` - MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` - MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` - PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` - BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` - DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` - PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` - Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` - Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` - BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` - Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` - PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` - PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` - FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` - NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` - Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` - Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` - FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` - FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` - FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` - FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` - FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` - UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` - NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vendor *string `protobuf:"bytes,1,opt,name=vendor" json:"vendor,omitempty"` // name of the manufacturer, e.g. "trezor.io" + MajorVersion *uint32 `protobuf:"varint,2,opt,name=major_version,json=majorVersion" json:"major_version,omitempty"` // major version of the firmware/bootloader, e.g. 1 + MinorVersion *uint32 `protobuf:"varint,3,opt,name=minor_version,json=minorVersion" json:"minor_version,omitempty"` // minor version of the firmware/bootloader, e.g. 0 + PatchVersion *uint32 `protobuf:"varint,4,opt,name=patch_version,json=patchVersion" json:"patch_version,omitempty"` // patch version of the firmware/bootloader, e.g. 0 + BootloaderMode *bool `protobuf:"varint,5,opt,name=bootloader_mode,json=bootloaderMode" json:"bootloader_mode,omitempty"` // is device in bootloader mode? + DeviceId *string `protobuf:"bytes,6,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` // device's unique identifier + PinProtection *bool `protobuf:"varint,7,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // is device protected by PIN? + PassphraseProtection *bool `protobuf:"varint,8,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // is node/mnemonic encrypted using passphrase? + Language *string `protobuf:"bytes,9,opt,name=language" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,10,opt,name=label" json:"label,omitempty"` // device description label + Initialized *bool `protobuf:"varint,12,opt,name=initialized" json:"initialized,omitempty"` // does device contain seed? + Revision []byte `protobuf:"bytes,13,opt,name=revision" json:"revision,omitempty"` // SCM revision of firmware + BootloaderHash []byte `protobuf:"bytes,14,opt,name=bootloader_hash,json=bootloaderHash" json:"bootloader_hash,omitempty"` // hash of the bootloader + Imported *bool `protobuf:"varint,15,opt,name=imported" json:"imported,omitempty"` // was storage imported from an external source? + PinCached *bool `protobuf:"varint,16,opt,name=pin_cached,json=pinCached" json:"pin_cached,omitempty"` // is PIN already cached in session? + PassphraseCached *bool `protobuf:"varint,17,opt,name=passphrase_cached,json=passphraseCached" json:"passphrase_cached,omitempty"` // is passphrase already cached in session? + FirmwarePresent *bool `protobuf:"varint,18,opt,name=firmware_present,json=firmwarePresent" json:"firmware_present,omitempty"` // is valid firmware loaded? + NeedsBackup *bool `protobuf:"varint,19,opt,name=needs_backup,json=needsBackup" json:"needs_backup,omitempty"` // does storage need backup? (equals to Storage.needs_backup) + Flags *uint32 `protobuf:"varint,20,opt,name=flags" json:"flags,omitempty"` // device flags (equals to Storage.flags) + Model *string `protobuf:"bytes,21,opt,name=model" json:"model,omitempty"` // device hardware model + FwMajor *uint32 `protobuf:"varint,22,opt,name=fw_major,json=fwMajor" json:"fw_major,omitempty"` // reported firmware version if in bootloader mode + FwMinor *uint32 `protobuf:"varint,23,opt,name=fw_minor,json=fwMinor" json:"fw_minor,omitempty"` // reported firmware version if in bootloader mode + FwPatch *uint32 `protobuf:"varint,24,opt,name=fw_patch,json=fwPatch" json:"fw_patch,omitempty"` // reported firmware version if in bootloader mode + FwVendor *string `protobuf:"bytes,25,opt,name=fw_vendor,json=fwVendor" json:"fw_vendor,omitempty"` // reported firmware vendor if in bootloader mode + FwVendorKeys []byte `protobuf:"bytes,26,opt,name=fw_vendor_keys,json=fwVendorKeys" json:"fw_vendor_keys,omitempty"` // reported firmware vendor keys (their hash) + UnfinishedBackup *bool `protobuf:"varint,27,opt,name=unfinished_backup,json=unfinishedBackup" json:"unfinished_backup,omitempty"` // report unfinished backup (equals to Storage.unfinished_backup) + NoBackup *bool `protobuf:"varint,28,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` // report no backup (equals to Storage.no_backup) } -func (m *Features) Reset() { *m = Features{} } -func (m *Features) String() string { return proto.CompactTextString(m) } -func (*Features) ProtoMessage() {} +func (x *Features) Reset() { + *x = Features{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Features) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Features) ProtoMessage() {} + +func (x *Features) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Features.ProtoReflect.Descriptor instead. func (*Features) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{2} + return file_messages_management_proto_rawDescGZIP(), []int{2} } -func (m *Features) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Features.Unmarshal(m, b) -} -func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Features.Marshal(b, m, deterministic) -} -func (m *Features) XXX_Merge(src proto.Message) { - xxx_messageInfo_Features.Merge(m, src) -} -func (m *Features) XXX_Size() int { - return xxx_messageInfo_Features.Size(m) -} -func (m *Features) XXX_DiscardUnknown() { - xxx_messageInfo_Features.DiscardUnknown(m) -} - -var xxx_messageInfo_Features proto.InternalMessageInfo - -func (m *Features) GetVendor() string { - if m != nil && m.Vendor != nil { - return *m.Vendor +func (x *Features) GetVendor() string { + if x != nil && x.Vendor != nil { + return *x.Vendor } return "" } -func (m *Features) GetMajorVersion() uint32 { - if m != nil && m.MajorVersion != nil { - return *m.MajorVersion +func (x *Features) GetMajorVersion() uint32 { + if x != nil && x.MajorVersion != nil { + return *x.MajorVersion } return 0 } -func (m *Features) GetMinorVersion() uint32 { - if m != nil && m.MinorVersion != nil { - return *m.MinorVersion +func (x *Features) GetMinorVersion() uint32 { + if x != nil && x.MinorVersion != nil { + return *x.MinorVersion } return 0 } -func (m *Features) GetPatchVersion() uint32 { - if m != nil && m.PatchVersion != nil { - return *m.PatchVersion +func (x *Features) GetPatchVersion() uint32 { + if x != nil && x.PatchVersion != nil { + return *x.PatchVersion } return 0 } -func (m *Features) GetBootloaderMode() bool { - if m != nil && m.BootloaderMode != nil { - return *m.BootloaderMode +func (x *Features) GetBootloaderMode() bool { + if x != nil && x.BootloaderMode != nil { + return *x.BootloaderMode } return false } -func (m *Features) GetDeviceId() string { - if m != nil && m.DeviceId != nil { - return *m.DeviceId +func (x *Features) GetDeviceId() string { + if x != nil && x.DeviceId != nil { + return *x.DeviceId } return "" } -func (m *Features) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *Features) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *Features) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *Features) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *Features) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *Features) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return "" } -func (m *Features) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *Features) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *Features) GetInitialized() bool { - if m != nil && m.Initialized != nil { - return *m.Initialized +func (x *Features) GetInitialized() bool { + if x != nil && x.Initialized != nil { + return *x.Initialized } return false } -func (m *Features) GetRevision() []byte { - if m != nil { - return m.Revision +func (x *Features) GetRevision() []byte { + if x != nil { + return x.Revision } return nil } -func (m *Features) GetBootloaderHash() []byte { - if m != nil { - return m.BootloaderHash +func (x *Features) GetBootloaderHash() []byte { + if x != nil { + return x.BootloaderHash } return nil } -func (m *Features) GetImported() bool { - if m != nil && m.Imported != nil { - return *m.Imported +func (x *Features) GetImported() bool { + if x != nil && x.Imported != nil { + return *x.Imported } return false } -func (m *Features) GetPinCached() bool { - if m != nil && m.PinCached != nil { - return *m.PinCached +func (x *Features) GetPinCached() bool { + if x != nil && x.PinCached != nil { + return *x.PinCached } return false } -func (m *Features) GetPassphraseCached() bool { - if m != nil && m.PassphraseCached != nil { - return *m.PassphraseCached +func (x *Features) GetPassphraseCached() bool { + if x != nil && x.PassphraseCached != nil { + return *x.PassphraseCached } return false } -func (m *Features) GetFirmwarePresent() bool { - if m != nil && m.FirmwarePresent != nil { - return *m.FirmwarePresent +func (x *Features) GetFirmwarePresent() bool { + if x != nil && x.FirmwarePresent != nil { + return *x.FirmwarePresent } return false } -func (m *Features) GetNeedsBackup() bool { - if m != nil && m.NeedsBackup != nil { - return *m.NeedsBackup +func (x *Features) GetNeedsBackup() bool { + if x != nil && x.NeedsBackup != nil { + return *x.NeedsBackup } return false } -func (m *Features) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags +func (x *Features) GetFlags() uint32 { + if x != nil && x.Flags != nil { + return *x.Flags } return 0 } -func (m *Features) GetModel() string { - if m != nil && m.Model != nil { - return *m.Model +func (x *Features) GetModel() string { + if x != nil && x.Model != nil { + return *x.Model } return "" } -func (m *Features) GetFwMajor() uint32 { - if m != nil && m.FwMajor != nil { - return *m.FwMajor +func (x *Features) GetFwMajor() uint32 { + if x != nil && x.FwMajor != nil { + return *x.FwMajor } return 0 } -func (m *Features) GetFwMinor() uint32 { - if m != nil && m.FwMinor != nil { - return *m.FwMinor +func (x *Features) GetFwMinor() uint32 { + if x != nil && x.FwMinor != nil { + return *x.FwMinor } return 0 } -func (m *Features) GetFwPatch() uint32 { - if m != nil && m.FwPatch != nil { - return *m.FwPatch +func (x *Features) GetFwPatch() uint32 { + if x != nil && x.FwPatch != nil { + return *x.FwPatch } return 0 } -func (m *Features) GetFwVendor() string { - if m != nil && m.FwVendor != nil { - return *m.FwVendor +func (x *Features) GetFwVendor() string { + if x != nil && x.FwVendor != nil { + return *x.FwVendor } return "" } -func (m *Features) GetFwVendorKeys() []byte { - if m != nil { - return m.FwVendorKeys +func (x *Features) GetFwVendorKeys() []byte { + if x != nil { + return x.FwVendorKeys } return nil } -func (m *Features) GetUnfinishedBackup() bool { - if m != nil && m.UnfinishedBackup != nil { - return *m.UnfinishedBackup +func (x *Features) GetUnfinishedBackup() bool { + if x != nil && x.UnfinishedBackup != nil { + return *x.UnfinishedBackup } return false } -func (m *Features) GetNoBackup() bool { - if m != nil && m.NoBackup != nil { - return *m.NoBackup +func (x *Features) GetNoBackup() bool { + if x != nil && x.NoBackup != nil { + return *x.NoBackup } return false } @@ -500,124 +574,139 @@ func (m *Features) GetNoBackup() bool { // @start // @next Success type ClearSession struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *ClearSession) Reset() { *m = ClearSession{} } -func (m *ClearSession) String() string { return proto.CompactTextString(m) } -func (*ClearSession) ProtoMessage() {} +func (x *ClearSession) Reset() { + *x = ClearSession{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClearSession) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClearSession) ProtoMessage() {} + +func (x *ClearSession) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClearSession.ProtoReflect.Descriptor instead. func (*ClearSession) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{3} + return file_messages_management_proto_rawDescGZIP(), []int{3} } -func (m *ClearSession) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ClearSession.Unmarshal(m, b) -} -func (m *ClearSession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ClearSession.Marshal(b, m, deterministic) -} -func (m *ClearSession) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClearSession.Merge(m, src) -} -func (m *ClearSession) XXX_Size() int { - return xxx_messageInfo_ClearSession.Size(m) -} -func (m *ClearSession) XXX_DiscardUnknown() { - xxx_messageInfo_ClearSession.DiscardUnknown(m) -} - -var xxx_messageInfo_ClearSession proto.InternalMessageInfo - -//* +// * // Request: change language and/or label of the device // @start // @next Success // @next Failure type ApplySettings struct { - Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` - Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` - UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` - Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` - PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` - AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` - DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Language *string `protobuf:"bytes,1,opt,name=language" json:"language,omitempty"` + Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` + UsePassphrase *bool `protobuf:"varint,3,opt,name=use_passphrase,json=usePassphrase" json:"use_passphrase,omitempty"` + Homescreen []byte `protobuf:"bytes,4,opt,name=homescreen" json:"homescreen,omitempty"` + PassphraseSource *ApplySettings_PassphraseSourceType `protobuf:"varint,5,opt,name=passphrase_source,json=passphraseSource,enum=hw.trezor.messages.management.ApplySettings_PassphraseSourceType" json:"passphrase_source,omitempty"` + AutoLockDelayMs *uint32 `protobuf:"varint,6,opt,name=auto_lock_delay_ms,json=autoLockDelayMs" json:"auto_lock_delay_ms,omitempty"` + DisplayRotation *uint32 `protobuf:"varint,7,opt,name=display_rotation,json=displayRotation" json:"display_rotation,omitempty"` // in degrees from North } -func (m *ApplySettings) Reset() { *m = ApplySettings{} } -func (m *ApplySettings) String() string { return proto.CompactTextString(m) } -func (*ApplySettings) ProtoMessage() {} +func (x *ApplySettings) Reset() { + *x = ApplySettings{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplySettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplySettings) ProtoMessage() {} + +func (x *ApplySettings) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplySettings.ProtoReflect.Descriptor instead. func (*ApplySettings) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{4} + return file_messages_management_proto_rawDescGZIP(), []int{4} } -func (m *ApplySettings) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplySettings.Unmarshal(m, b) -} -func (m *ApplySettings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplySettings.Marshal(b, m, deterministic) -} -func (m *ApplySettings) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplySettings.Merge(m, src) -} -func (m *ApplySettings) XXX_Size() int { - return xxx_messageInfo_ApplySettings.Size(m) -} -func (m *ApplySettings) XXX_DiscardUnknown() { - xxx_messageInfo_ApplySettings.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplySettings proto.InternalMessageInfo - -func (m *ApplySettings) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *ApplySettings) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return "" } -func (m *ApplySettings) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *ApplySettings) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *ApplySettings) GetUsePassphrase() bool { - if m != nil && m.UsePassphrase != nil { - return *m.UsePassphrase +func (x *ApplySettings) GetUsePassphrase() bool { + if x != nil && x.UsePassphrase != nil { + return *x.UsePassphrase } return false } -func (m *ApplySettings) GetHomescreen() []byte { - if m != nil { - return m.Homescreen +func (x *ApplySettings) GetHomescreen() []byte { + if x != nil { + return x.Homescreen } return nil } -func (m *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { - if m != nil && m.PassphraseSource != nil { - return *m.PassphraseSource +func (x *ApplySettings) GetPassphraseSource() ApplySettings_PassphraseSourceType { + if x != nil && x.PassphraseSource != nil { + return *x.PassphraseSource } return ApplySettings_ASK } -func (m *ApplySettings) GetAutoLockDelayMs() uint32 { - if m != nil && m.AutoLockDelayMs != nil { - return *m.AutoLockDelayMs +func (x *ApplySettings) GetAutoLockDelayMs() uint32 { + if x != nil && x.AutoLockDelayMs != nil { + return *x.AutoLockDelayMs } return 0 } -func (m *ApplySettings) GetDisplayRotation() uint32 { - if m != nil && m.DisplayRotation != nil { - return *m.DisplayRotation +func (x *ApplySettings) GetDisplayRotation() uint32 { + if x != nil && x.DisplayRotation != nil { + return *x.DisplayRotation } return 0 } @@ -628,40 +717,48 @@ func (m *ApplySettings) GetDisplayRotation() uint32 { // @next Success // @next Failure type ApplyFlags struct { - Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Flags *uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` // bitmask, can only set bits, not unset } -func (m *ApplyFlags) Reset() { *m = ApplyFlags{} } -func (m *ApplyFlags) String() string { return proto.CompactTextString(m) } -func (*ApplyFlags) ProtoMessage() {} +func (x *ApplyFlags) Reset() { + *x = ApplyFlags{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyFlags) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyFlags) ProtoMessage() {} + +func (x *ApplyFlags) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyFlags.ProtoReflect.Descriptor instead. func (*ApplyFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{5} + return file_messages_management_proto_rawDescGZIP(), []int{5} } -func (m *ApplyFlags) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplyFlags.Unmarshal(m, b) -} -func (m *ApplyFlags) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplyFlags.Marshal(b, m, deterministic) -} -func (m *ApplyFlags) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplyFlags.Merge(m, src) -} -func (m *ApplyFlags) XXX_Size() int { - return xxx_messageInfo_ApplyFlags.Size(m) -} -func (m *ApplyFlags) XXX_DiscardUnknown() { - xxx_messageInfo_ApplyFlags.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplyFlags proto.InternalMessageInfo - -func (m *ApplyFlags) GetFlags() uint32 { - if m != nil && m.Flags != nil { - return *m.Flags +func (x *ApplyFlags) GetFlags() uint32 { + if x != nil && x.Flags != nil { + return *x.Flags } return 0 } @@ -672,40 +769,48 @@ func (m *ApplyFlags) GetFlags() uint32 { // @next Success // @next Failure type ChangePin struct { - Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Remove *bool `protobuf:"varint,1,opt,name=remove" json:"remove,omitempty"` // is PIN removal requested? } -func (m *ChangePin) Reset() { *m = ChangePin{} } -func (m *ChangePin) String() string { return proto.CompactTextString(m) } -func (*ChangePin) ProtoMessage() {} +func (x *ChangePin) Reset() { + *x = ChangePin{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChangePin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChangePin) ProtoMessage() {} + +func (x *ChangePin) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChangePin.ProtoReflect.Descriptor instead. func (*ChangePin) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{6} + return file_messages_management_proto_rawDescGZIP(), []int{6} } -func (m *ChangePin) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ChangePin.Unmarshal(m, b) -} -func (m *ChangePin) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ChangePin.Marshal(b, m, deterministic) -} -func (m *ChangePin) XXX_Merge(src proto.Message) { - xxx_messageInfo_ChangePin.Merge(m, src) -} -func (m *ChangePin) XXX_Size() int { - return xxx_messageInfo_ChangePin.Size(m) -} -func (m *ChangePin) XXX_DiscardUnknown() { - xxx_messageInfo_ChangePin.DiscardUnknown(m) -} - -var xxx_messageInfo_ChangePin proto.InternalMessageInfo - -func (m *ChangePin) GetRemove() bool { - if m != nil && m.Remove != nil { - return *m.Remove +func (x *ChangePin) GetRemove() bool { + if x != nil && x.Remove != nil { + return *x.Remove } return false } @@ -715,64 +820,72 @@ func (m *ChangePin) GetRemove() bool { // @start // @next Success type Ping struct { - Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` - ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` // message to send back in Success message + ButtonProtection *bool `protobuf:"varint,2,opt,name=button_protection,json=buttonProtection" json:"button_protection,omitempty"` // ask for button press + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // ask for PIN if set in device + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // ask for passphrase if set in device } -func (m *Ping) Reset() { *m = Ping{} } -func (m *Ping) String() string { return proto.CompactTextString(m) } -func (*Ping) ProtoMessage() {} +func (x *Ping) Reset() { + *x = Ping{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Ping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Ping) ProtoMessage() {} + +func (x *Ping) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Ping.ProtoReflect.Descriptor instead. func (*Ping) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{7} + return file_messages_management_proto_rawDescGZIP(), []int{7} } -func (m *Ping) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Ping.Unmarshal(m, b) -} -func (m *Ping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Ping.Marshal(b, m, deterministic) -} -func (m *Ping) XXX_Merge(src proto.Message) { - xxx_messageInfo_Ping.Merge(m, src) -} -func (m *Ping) XXX_Size() int { - return xxx_messageInfo_Ping.Size(m) -} -func (m *Ping) XXX_DiscardUnknown() { - xxx_messageInfo_Ping.DiscardUnknown(m) -} - -var xxx_messageInfo_Ping proto.InternalMessageInfo - -func (m *Ping) GetMessage() string { - if m != nil && m.Message != nil { - return *m.Message +func (x *Ping) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message } return "" } -func (m *Ping) GetButtonProtection() bool { - if m != nil && m.ButtonProtection != nil { - return *m.ButtonProtection +func (x *Ping) GetButtonProtection() bool { + if x != nil && x.ButtonProtection != nil { + return *x.ButtonProtection } return false } -func (m *Ping) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *Ping) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *Ping) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *Ping) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } @@ -782,76 +895,91 @@ func (m *Ping) GetPassphraseProtection() bool { // @start // @next Failure type Cancel struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *Cancel) Reset() { *m = Cancel{} } -func (m *Cancel) String() string { return proto.CompactTextString(m) } -func (*Cancel) ProtoMessage() {} +func (x *Cancel) Reset() { + *x = Cancel{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Cancel) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Cancel) ProtoMessage() {} + +func (x *Cancel) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Cancel.ProtoReflect.Descriptor instead. func (*Cancel) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{8} + return file_messages_management_proto_rawDescGZIP(), []int{8} } -func (m *Cancel) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Cancel.Unmarshal(m, b) -} -func (m *Cancel) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Cancel.Marshal(b, m, deterministic) -} -func (m *Cancel) XXX_Merge(src proto.Message) { - xxx_messageInfo_Cancel.Merge(m, src) -} -func (m *Cancel) XXX_Size() int { - return xxx_messageInfo_Cancel.Size(m) -} -func (m *Cancel) XXX_DiscardUnknown() { - xxx_messageInfo_Cancel.DiscardUnknown(m) -} - -var xxx_messageInfo_Cancel proto.InternalMessageInfo - -//* +// * // Request: Request a sample of random data generated by hardware RNG. May be used for testing. // @start // @next Entropy // @next Failure type GetEntropy struct { - Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Size *uint32 `protobuf:"varint,1,req,name=size" json:"size,omitempty"` // size of requested entropy } -func (m *GetEntropy) Reset() { *m = GetEntropy{} } -func (m *GetEntropy) String() string { return proto.CompactTextString(m) } -func (*GetEntropy) ProtoMessage() {} +func (x *GetEntropy) Reset() { + *x = GetEntropy{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEntropy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEntropy) ProtoMessage() {} + +func (x *GetEntropy) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEntropy.ProtoReflect.Descriptor instead. func (*GetEntropy) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{9} + return file_messages_management_proto_rawDescGZIP(), []int{9} } -func (m *GetEntropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetEntropy.Unmarshal(m, b) -} -func (m *GetEntropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetEntropy.Marshal(b, m, deterministic) -} -func (m *GetEntropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetEntropy.Merge(m, src) -} -func (m *GetEntropy) XXX_Size() int { - return xxx_messageInfo_GetEntropy.Size(m) -} -func (m *GetEntropy) XXX_DiscardUnknown() { - xxx_messageInfo_GetEntropy.DiscardUnknown(m) -} - -var xxx_messageInfo_GetEntropy proto.InternalMessageInfo - -func (m *GetEntropy) GetSize() uint32 { - if m != nil && m.Size != nil { - return *m.Size +func (x *GetEntropy) GetSize() uint32 { + if x != nil && x.Size != nil { + return *x.Size } return 0 } @@ -860,40 +988,48 @@ func (m *GetEntropy) GetSize() uint32 { // Response: Reply with random data generated by internal RNG // @end type Entropy struct { - Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entropy []byte `protobuf:"bytes,1,req,name=entropy" json:"entropy,omitempty"` // chunk of random generated bytes } -func (m *Entropy) Reset() { *m = Entropy{} } -func (m *Entropy) String() string { return proto.CompactTextString(m) } -func (*Entropy) ProtoMessage() {} +func (x *Entropy) Reset() { + *x = Entropy{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Entropy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Entropy) ProtoMessage() {} + +func (x *Entropy) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Entropy.ProtoReflect.Descriptor instead. func (*Entropy) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{10} + return file_messages_management_proto_rawDescGZIP(), []int{10} } -func (m *Entropy) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Entropy.Unmarshal(m, b) -} -func (m *Entropy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Entropy.Marshal(b, m, deterministic) -} -func (m *Entropy) XXX_Merge(src proto.Message) { - xxx_messageInfo_Entropy.Merge(m, src) -} -func (m *Entropy) XXX_Size() int { - return xxx_messageInfo_Entropy.Size(m) -} -func (m *Entropy) XXX_DiscardUnknown() { - xxx_messageInfo_Entropy.DiscardUnknown(m) -} - -var xxx_messageInfo_Entropy proto.InternalMessageInfo - -func (m *Entropy) GetEntropy() []byte { - if m != nil { - return m.Entropy +func (x *Entropy) GetEntropy() []byte { + if x != nil { + return x.Entropy } return nil } @@ -904,134 +1040,152 @@ func (m *Entropy) GetEntropy() []byte { // @next Success // @next Failure type WipeDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *WipeDevice) Reset() { *m = WipeDevice{} } -func (m *WipeDevice) String() string { return proto.CompactTextString(m) } -func (*WipeDevice) ProtoMessage() {} +func (x *WipeDevice) Reset() { + *x = WipeDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WipeDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WipeDevice) ProtoMessage() {} + +func (x *WipeDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WipeDevice.ProtoReflect.Descriptor instead. func (*WipeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{11} + return file_messages_management_proto_rawDescGZIP(), []int{11} } -func (m *WipeDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WipeDevice.Unmarshal(m, b) -} -func (m *WipeDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WipeDevice.Marshal(b, m, deterministic) -} -func (m *WipeDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_WipeDevice.Merge(m, src) -} -func (m *WipeDevice) XXX_Size() int { - return xxx_messageInfo_WipeDevice.Size(m) -} -func (m *WipeDevice) XXX_DiscardUnknown() { - xxx_messageInfo_WipeDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_WipeDevice proto.InternalMessageInfo - -//* +// * // Request: Load seed and related internal settings from the computer // @start // @next Success // @next Failure type LoadDevice struct { - Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` - Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` - Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` - PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` - U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Mnemonic *string `protobuf:"bytes,1,opt,name=mnemonic" json:"mnemonic,omitempty"` // seed encoded as BIP-39 mnemonic (12, 18 or 24 words) + Node *HDNodeType `protobuf:"bytes,2,opt,name=node" json:"node,omitempty"` // BIP-32 node + Pin *string `protobuf:"bytes,3,opt,name=pin" json:"pin,omitempty"` // set PIN protection + PassphraseProtection *bool `protobuf:"varint,4,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` // device label + SkipChecksum *bool `protobuf:"varint,7,opt,name=skip_checksum,json=skipChecksum" json:"skip_checksum,omitempty"` // do not test mnemonic for valid BIP-39 checksum + U2FCounter *uint32 `protobuf:"varint,8,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter } -func (m *LoadDevice) Reset() { *m = LoadDevice{} } -func (m *LoadDevice) String() string { return proto.CompactTextString(m) } -func (*LoadDevice) ProtoMessage() {} +// Default values for LoadDevice fields. +const ( + Default_LoadDevice_Language = string("english") +) + +func (x *LoadDevice) Reset() { + *x = LoadDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LoadDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoadDevice) ProtoMessage() {} + +func (x *LoadDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoadDevice.ProtoReflect.Descriptor instead. func (*LoadDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{12} + return file_messages_management_proto_rawDescGZIP(), []int{12} } -func (m *LoadDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_LoadDevice.Unmarshal(m, b) -} -func (m *LoadDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_LoadDevice.Marshal(b, m, deterministic) -} -func (m *LoadDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_LoadDevice.Merge(m, src) -} -func (m *LoadDevice) XXX_Size() int { - return xxx_messageInfo_LoadDevice.Size(m) -} -func (m *LoadDevice) XXX_DiscardUnknown() { - xxx_messageInfo_LoadDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_LoadDevice proto.InternalMessageInfo - -const Default_LoadDevice_Language string = "english" - -func (m *LoadDevice) GetMnemonic() string { - if m != nil && m.Mnemonic != nil { - return *m.Mnemonic +func (x *LoadDevice) GetMnemonic() string { + if x != nil && x.Mnemonic != nil { + return *x.Mnemonic } return "" } -func (m *LoadDevice) GetNode() *HDNodeType { - if m != nil { - return m.Node +func (x *LoadDevice) GetNode() *HDNodeType { + if x != nil { + return x.Node } return nil } -func (m *LoadDevice) GetPin() string { - if m != nil && m.Pin != nil { - return *m.Pin +func (x *LoadDevice) GetPin() string { + if x != nil && x.Pin != nil { + return *x.Pin } return "" } -func (m *LoadDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *LoadDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *LoadDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *LoadDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_LoadDevice_Language } -func (m *LoadDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *LoadDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *LoadDevice) GetSkipChecksum() bool { - if m != nil && m.SkipChecksum != nil { - return *m.SkipChecksum +func (x *LoadDevice) GetSkipChecksum() bool { + if x != nil && x.SkipChecksum != nil { + return *x.SkipChecksum } return false } -func (m *LoadDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *LoadDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } @@ -1042,107 +1196,118 @@ func (m *LoadDevice) GetU2FCounter() uint32 { // @next EntropyRequest // @next Failure type ResetDevice struct { - DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` - Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` - PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` - U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` - NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayRandom *bool `protobuf:"varint,1,opt,name=display_random,json=displayRandom" json:"display_random,omitempty"` // display entropy generated by the device before asking for additional entropy + Strength *uint32 `protobuf:"varint,2,opt,name=strength,def=256" json:"strength,omitempty"` // strength of seed in bits + PassphraseProtection *bool `protobuf:"varint,3,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + PinProtection *bool `protobuf:"varint,4,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // enable PIN protection + Language *string `protobuf:"bytes,5,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,6,opt,name=label" json:"label,omitempty"` // device label + U2FCounter *uint32 `protobuf:"varint,7,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter + SkipBackup *bool `protobuf:"varint,8,opt,name=skip_backup,json=skipBackup" json:"skip_backup,omitempty"` // postpone seed backup to BackupDevice workflow + NoBackup *bool `protobuf:"varint,9,opt,name=no_backup,json=noBackup" json:"no_backup,omitempty"` // indicate that no backup is going to be made } -func (m *ResetDevice) Reset() { *m = ResetDevice{} } -func (m *ResetDevice) String() string { return proto.CompactTextString(m) } -func (*ResetDevice) ProtoMessage() {} +// Default values for ResetDevice fields. +const ( + Default_ResetDevice_Strength = uint32(256) + Default_ResetDevice_Language = string("english") +) + +func (x *ResetDevice) Reset() { + *x = ResetDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResetDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResetDevice) ProtoMessage() {} + +func (x *ResetDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResetDevice.ProtoReflect.Descriptor instead. func (*ResetDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{13} + return file_messages_management_proto_rawDescGZIP(), []int{13} } -func (m *ResetDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ResetDevice.Unmarshal(m, b) -} -func (m *ResetDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ResetDevice.Marshal(b, m, deterministic) -} -func (m *ResetDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_ResetDevice.Merge(m, src) -} -func (m *ResetDevice) XXX_Size() int { - return xxx_messageInfo_ResetDevice.Size(m) -} -func (m *ResetDevice) XXX_DiscardUnknown() { - xxx_messageInfo_ResetDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_ResetDevice proto.InternalMessageInfo - -const Default_ResetDevice_Strength uint32 = 256 -const Default_ResetDevice_Language string = "english" - -func (m *ResetDevice) GetDisplayRandom() bool { - if m != nil && m.DisplayRandom != nil { - return *m.DisplayRandom +func (x *ResetDevice) GetDisplayRandom() bool { + if x != nil && x.DisplayRandom != nil { + return *x.DisplayRandom } return false } -func (m *ResetDevice) GetStrength() uint32 { - if m != nil && m.Strength != nil { - return *m.Strength +func (x *ResetDevice) GetStrength() uint32 { + if x != nil && x.Strength != nil { + return *x.Strength } return Default_ResetDevice_Strength } -func (m *ResetDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *ResetDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *ResetDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *ResetDevice) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *ResetDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *ResetDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_ResetDevice_Language } -func (m *ResetDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *ResetDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *ResetDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *ResetDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func (m *ResetDevice) GetSkipBackup() bool { - if m != nil && m.SkipBackup != nil { - return *m.SkipBackup +func (x *ResetDevice) GetSkipBackup() bool { + if x != nil && x.SkipBackup != nil { + return *x.SkipBackup } return false } -func (m *ResetDevice) GetNoBackup() bool { - if m != nil && m.NoBackup != nil { - return *m.NoBackup +func (x *ResetDevice) GetNoBackup() bool { + if x != nil && x.NoBackup != nil { + return *x.NoBackup } return false } @@ -1152,108 +1317,130 @@ func (m *ResetDevice) GetNoBackup() bool { // @start // @next Success type BackupDevice struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *BackupDevice) Reset() { *m = BackupDevice{} } -func (m *BackupDevice) String() string { return proto.CompactTextString(m) } -func (*BackupDevice) ProtoMessage() {} +func (x *BackupDevice) Reset() { + *x = BackupDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BackupDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackupDevice) ProtoMessage() {} + +func (x *BackupDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackupDevice.ProtoReflect.Descriptor instead. func (*BackupDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{14} + return file_messages_management_proto_rawDescGZIP(), []int{14} } -func (m *BackupDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BackupDevice.Unmarshal(m, b) -} -func (m *BackupDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BackupDevice.Marshal(b, m, deterministic) -} -func (m *BackupDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_BackupDevice.Merge(m, src) -} -func (m *BackupDevice) XXX_Size() int { - return xxx_messageInfo_BackupDevice.Size(m) -} -func (m *BackupDevice) XXX_DiscardUnknown() { - xxx_messageInfo_BackupDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_BackupDevice proto.InternalMessageInfo - -//* +// * // Response: Ask for additional entropy from host computer // @next EntropyAck type EntropyRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields } -func (m *EntropyRequest) Reset() { *m = EntropyRequest{} } -func (m *EntropyRequest) String() string { return proto.CompactTextString(m) } -func (*EntropyRequest) ProtoMessage() {} +func (x *EntropyRequest) Reset() { + *x = EntropyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EntropyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntropyRequest) ProtoMessage() {} + +func (x *EntropyRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntropyRequest.ProtoReflect.Descriptor instead. func (*EntropyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{15} + return file_messages_management_proto_rawDescGZIP(), []int{15} } -func (m *EntropyRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyRequest.Unmarshal(m, b) -} -func (m *EntropyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyRequest.Marshal(b, m, deterministic) -} -func (m *EntropyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyRequest.Merge(m, src) -} -func (m *EntropyRequest) XXX_Size() int { - return xxx_messageInfo_EntropyRequest.Size(m) -} -func (m *EntropyRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_EntropyRequest proto.InternalMessageInfo - -//* +// * // Request: Provide additional entropy for seed generation function // @next Success type EntropyAck struct { - Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entropy []byte `protobuf:"bytes,1,opt,name=entropy" json:"entropy,omitempty"` // 256 bits (32 bytes) of random data } -func (m *EntropyAck) Reset() { *m = EntropyAck{} } -func (m *EntropyAck) String() string { return proto.CompactTextString(m) } -func (*EntropyAck) ProtoMessage() {} +func (x *EntropyAck) Reset() { + *x = EntropyAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EntropyAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EntropyAck) ProtoMessage() {} + +func (x *EntropyAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EntropyAck.ProtoReflect.Descriptor instead. func (*EntropyAck) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{16} + return file_messages_management_proto_rawDescGZIP(), []int{16} } -func (m *EntropyAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EntropyAck.Unmarshal(m, b) -} -func (m *EntropyAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EntropyAck.Marshal(b, m, deterministic) -} -func (m *EntropyAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_EntropyAck.Merge(m, src) -} -func (m *EntropyAck) XXX_Size() int { - return xxx_messageInfo_EntropyAck.Size(m) -} -func (m *EntropyAck) XXX_DiscardUnknown() { - xxx_messageInfo_EntropyAck.DiscardUnknown(m) -} - -var xxx_messageInfo_EntropyAck proto.InternalMessageInfo - -func (m *EntropyAck) GetEntropy() []byte { - if m != nil { - return m.Entropy +func (x *EntropyAck) GetEntropy() []byte { + if x != nil { + return x.Entropy } return nil } @@ -1264,107 +1451,118 @@ func (m *EntropyAck) GetEntropy() []byte { // @start // @next WordRequest type RecoveryDevice struct { - WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` - PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` - PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` - Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` - Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` - EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WordCount *uint32 `protobuf:"varint,1,opt,name=word_count,json=wordCount" json:"word_count,omitempty"` // number of words in BIP-39 mnemonic + PassphraseProtection *bool `protobuf:"varint,2,opt,name=passphrase_protection,json=passphraseProtection" json:"passphrase_protection,omitempty"` // enable master node encryption using passphrase + PinProtection *bool `protobuf:"varint,3,opt,name=pin_protection,json=pinProtection" json:"pin_protection,omitempty"` // enable PIN protection + Language *string `protobuf:"bytes,4,opt,name=language,def=english" json:"language,omitempty"` // device language + Label *string `protobuf:"bytes,5,opt,name=label" json:"label,omitempty"` // device label + EnforceWordlist *bool `protobuf:"varint,6,opt,name=enforce_wordlist,json=enforceWordlist" json:"enforce_wordlist,omitempty"` // enforce BIP-39 wordlist during the process // 7 reserved for unused recovery method - Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` - U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Type *RecoveryDevice_RecoveryDeviceType `protobuf:"varint,8,opt,name=type,enum=hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType" json:"type,omitempty"` // supported recovery type + U2FCounter *uint32 `protobuf:"varint,9,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // U2F counter + DryRun *bool `protobuf:"varint,10,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"` // perform dry-run recovery workflow (for safe mnemonic validation) } -func (m *RecoveryDevice) Reset() { *m = RecoveryDevice{} } -func (m *RecoveryDevice) String() string { return proto.CompactTextString(m) } -func (*RecoveryDevice) ProtoMessage() {} +// Default values for RecoveryDevice fields. +const ( + Default_RecoveryDevice_Language = string("english") +) + +func (x *RecoveryDevice) Reset() { + *x = RecoveryDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RecoveryDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RecoveryDevice) ProtoMessage() {} + +func (x *RecoveryDevice) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RecoveryDevice.ProtoReflect.Descriptor instead. func (*RecoveryDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{17} + return file_messages_management_proto_rawDescGZIP(), []int{17} } -func (m *RecoveryDevice) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RecoveryDevice.Unmarshal(m, b) -} -func (m *RecoveryDevice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RecoveryDevice.Marshal(b, m, deterministic) -} -func (m *RecoveryDevice) XXX_Merge(src proto.Message) { - xxx_messageInfo_RecoveryDevice.Merge(m, src) -} -func (m *RecoveryDevice) XXX_Size() int { - return xxx_messageInfo_RecoveryDevice.Size(m) -} -func (m *RecoveryDevice) XXX_DiscardUnknown() { - xxx_messageInfo_RecoveryDevice.DiscardUnknown(m) -} - -var xxx_messageInfo_RecoveryDevice proto.InternalMessageInfo - -const Default_RecoveryDevice_Language string = "english" - -func (m *RecoveryDevice) GetWordCount() uint32 { - if m != nil && m.WordCount != nil { - return *m.WordCount +func (x *RecoveryDevice) GetWordCount() uint32 { + if x != nil && x.WordCount != nil { + return *x.WordCount } return 0 } -func (m *RecoveryDevice) GetPassphraseProtection() bool { - if m != nil && m.PassphraseProtection != nil { - return *m.PassphraseProtection +func (x *RecoveryDevice) GetPassphraseProtection() bool { + if x != nil && x.PassphraseProtection != nil { + return *x.PassphraseProtection } return false } -func (m *RecoveryDevice) GetPinProtection() bool { - if m != nil && m.PinProtection != nil { - return *m.PinProtection +func (x *RecoveryDevice) GetPinProtection() bool { + if x != nil && x.PinProtection != nil { + return *x.PinProtection } return false } -func (m *RecoveryDevice) GetLanguage() string { - if m != nil && m.Language != nil { - return *m.Language +func (x *RecoveryDevice) GetLanguage() string { + if x != nil && x.Language != nil { + return *x.Language } return Default_RecoveryDevice_Language } -func (m *RecoveryDevice) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label +func (x *RecoveryDevice) GetLabel() string { + if x != nil && x.Label != nil { + return *x.Label } return "" } -func (m *RecoveryDevice) GetEnforceWordlist() bool { - if m != nil && m.EnforceWordlist != nil { - return *m.EnforceWordlist +func (x *RecoveryDevice) GetEnforceWordlist() bool { + if x != nil && x.EnforceWordlist != nil { + return *x.EnforceWordlist } return false } -func (m *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { - if m != nil && m.Type != nil { - return *m.Type +func (x *RecoveryDevice) GetType() RecoveryDevice_RecoveryDeviceType { + if x != nil && x.Type != nil { + return *x.Type } return RecoveryDevice_RecoveryDeviceType_ScrambledWords } -func (m *RecoveryDevice) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *RecoveryDevice) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func (m *RecoveryDevice) GetDryRun() bool { - if m != nil && m.DryRun != nil { - return *m.DryRun +func (x *RecoveryDevice) GetDryRun() bool { + if x != nil && x.DryRun != nil { + return *x.DryRun } return false } @@ -1374,40 +1572,48 @@ func (m *RecoveryDevice) GetDryRun() bool { // Its position is shown only on device's internal display. // @next WordAck type WordRequest struct { - Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type *WordRequest_WordRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.management.WordRequest_WordRequestType" json:"type,omitempty"` } -func (m *WordRequest) Reset() { *m = WordRequest{} } -func (m *WordRequest) String() string { return proto.CompactTextString(m) } -func (*WordRequest) ProtoMessage() {} +func (x *WordRequest) Reset() { + *x = WordRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WordRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WordRequest) ProtoMessage() {} + +func (x *WordRequest) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WordRequest.ProtoReflect.Descriptor instead. func (*WordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{18} + return file_messages_management_proto_rawDescGZIP(), []int{18} } -func (m *WordRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordRequest.Unmarshal(m, b) -} -func (m *WordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordRequest.Marshal(b, m, deterministic) -} -func (m *WordRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordRequest.Merge(m, src) -} -func (m *WordRequest) XXX_Size() int { - return xxx_messageInfo_WordRequest.Size(m) -} -func (m *WordRequest) XXX_DiscardUnknown() { - xxx_messageInfo_WordRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_WordRequest proto.InternalMessageInfo - -func (m *WordRequest) GetType() WordRequest_WordRequestType { - if m != nil && m.Type != nil { - return *m.Type +func (x *WordRequest) GetType() WordRequest_WordRequestType { + if x != nil && x.Type != nil { + return *x.Type } return WordRequest_WordRequestType_Plain } @@ -1418,40 +1624,48 @@ func (m *WordRequest) GetType() WordRequest_WordRequestType { // @next Success // @next Failure type WordAck struct { - Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Word *string `protobuf:"bytes,1,req,name=word" json:"word,omitempty"` // one word of mnemonic on asked position } -func (m *WordAck) Reset() { *m = WordAck{} } -func (m *WordAck) String() string { return proto.CompactTextString(m) } -func (*WordAck) ProtoMessage() {} +func (x *WordAck) Reset() { + *x = WordAck{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WordAck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WordAck) ProtoMessage() {} + +func (x *WordAck) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WordAck.ProtoReflect.Descriptor instead. func (*WordAck) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{19} + return file_messages_management_proto_rawDescGZIP(), []int{19} } -func (m *WordAck) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_WordAck.Unmarshal(m, b) -} -func (m *WordAck) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_WordAck.Marshal(b, m, deterministic) -} -func (m *WordAck) XXX_Merge(src proto.Message) { - xxx_messageInfo_WordAck.Merge(m, src) -} -func (m *WordAck) XXX_Size() int { - return xxx_messageInfo_WordAck.Size(m) -} -func (m *WordAck) XXX_DiscardUnknown() { - xxx_messageInfo_WordAck.DiscardUnknown(m) -} - -var xxx_messageInfo_WordAck proto.InternalMessageInfo - -func (m *WordAck) GetWord() string { - if m != nil && m.Word != nil { - return *m.Word +func (x *WordAck) GetWord() string { + if x != nil && x.Word != nil { + return *x.Word } return "" } @@ -1461,161 +1675,602 @@ func (m *WordAck) GetWord() string { // @start // @next Success type SetU2FCounter struct { - U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + U2FCounter *uint32 `protobuf:"varint,1,opt,name=u2f_counter,json=u2fCounter" json:"u2f_counter,omitempty"` // counter } -func (m *SetU2FCounter) Reset() { *m = SetU2FCounter{} } -func (m *SetU2FCounter) String() string { return proto.CompactTextString(m) } -func (*SetU2FCounter) ProtoMessage() {} +func (x *SetU2FCounter) Reset() { + *x = SetU2FCounter{} + if protoimpl.UnsafeEnabled { + mi := &file_messages_management_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetU2FCounter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetU2FCounter) ProtoMessage() {} + +func (x *SetU2FCounter) ProtoReflect() protoreflect.Message { + mi := &file_messages_management_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetU2FCounter.ProtoReflect.Descriptor instead. func (*SetU2FCounter) Descriptor() ([]byte, []int) { - return fileDescriptor_0c720c20d27aa029, []int{20} + return file_messages_management_proto_rawDescGZIP(), []int{20} } -func (m *SetU2FCounter) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SetU2FCounter.Unmarshal(m, b) -} -func (m *SetU2FCounter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SetU2FCounter.Marshal(b, m, deterministic) -} -func (m *SetU2FCounter) XXX_Merge(src proto.Message) { - xxx_messageInfo_SetU2FCounter.Merge(m, src) -} -func (m *SetU2FCounter) XXX_Size() int { - return xxx_messageInfo_SetU2FCounter.Size(m) -} -func (m *SetU2FCounter) XXX_DiscardUnknown() { - xxx_messageInfo_SetU2FCounter.DiscardUnknown(m) -} - -var xxx_messageInfo_SetU2FCounter proto.InternalMessageInfo - -func (m *SetU2FCounter) GetU2FCounter() uint32 { - if m != nil && m.U2FCounter != nil { - return *m.U2FCounter +func (x *SetU2FCounter) GetU2FCounter() uint32 { + if x != nil && x.U2FCounter != nil { + return *x.U2FCounter } return 0 } -func init() { - proto.RegisterEnum("hw.trezor.messages.management.ApplySettings_PassphraseSourceType", ApplySettings_PassphraseSourceType_name, ApplySettings_PassphraseSourceType_value) - proto.RegisterEnum("hw.trezor.messages.management.RecoveryDevice_RecoveryDeviceType", RecoveryDevice_RecoveryDeviceType_name, RecoveryDevice_RecoveryDeviceType_value) - proto.RegisterEnum("hw.trezor.messages.management.WordRequest_WordRequestType", WordRequest_WordRequestType_name, WordRequest_WordRequestType_value) - proto.RegisterType((*Initialize)(nil), "hw.trezor.messages.management.Initialize") - proto.RegisterType((*GetFeatures)(nil), "hw.trezor.messages.management.GetFeatures") - proto.RegisterType((*Features)(nil), "hw.trezor.messages.management.Features") - proto.RegisterType((*ClearSession)(nil), "hw.trezor.messages.management.ClearSession") - proto.RegisterType((*ApplySettings)(nil), "hw.trezor.messages.management.ApplySettings") - proto.RegisterType((*ApplyFlags)(nil), "hw.trezor.messages.management.ApplyFlags") - proto.RegisterType((*ChangePin)(nil), "hw.trezor.messages.management.ChangePin") - proto.RegisterType((*Ping)(nil), "hw.trezor.messages.management.Ping") - proto.RegisterType((*Cancel)(nil), "hw.trezor.messages.management.Cancel") - proto.RegisterType((*GetEntropy)(nil), "hw.trezor.messages.management.GetEntropy") - proto.RegisterType((*Entropy)(nil), "hw.trezor.messages.management.Entropy") - proto.RegisterType((*WipeDevice)(nil), "hw.trezor.messages.management.WipeDevice") - proto.RegisterType((*LoadDevice)(nil), "hw.trezor.messages.management.LoadDevice") - proto.RegisterType((*ResetDevice)(nil), "hw.trezor.messages.management.ResetDevice") - proto.RegisterType((*BackupDevice)(nil), "hw.trezor.messages.management.BackupDevice") - proto.RegisterType((*EntropyRequest)(nil), "hw.trezor.messages.management.EntropyRequest") - proto.RegisterType((*EntropyAck)(nil), "hw.trezor.messages.management.EntropyAck") - proto.RegisterType((*RecoveryDevice)(nil), "hw.trezor.messages.management.RecoveryDevice") - proto.RegisterType((*WordRequest)(nil), "hw.trezor.messages.management.WordRequest") - proto.RegisterType((*WordAck)(nil), "hw.trezor.messages.management.WordAck") - proto.RegisterType((*SetU2FCounter)(nil), "hw.trezor.messages.management.SetU2FCounter") +var File_messages_management_proto protoreflect.FileDescriptor + +var file_messages_management_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x77, 0x2e, + 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x15, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x4b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x61, + 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x73, 0x6b, 0x69, 0x70, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x22, 0x0d, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x8c, 0x07, + 0x0a, 0x08, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, + 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x6e, 0x64, + 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x6f, 0x72, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, + 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x62, 0x6f, 0x6f, 0x74, + 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, + 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, + 0x72, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x62, 0x6f, + 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x69, 0x6e, 0x5f, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x69, + 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, + 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x65, 0x65, 0x64, 0x73, 0x42, 0x61, 0x63, 0x6b, + 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x19, + 0x0a, 0x08, 0x66, 0x77, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x66, 0x77, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x77, 0x5f, + 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x77, 0x4d, + 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x77, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x18, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x66, 0x77, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, + 0x1b, 0x0a, 0x09, 0x66, 0x77, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x66, 0x77, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x12, 0x24, 0x0a, 0x0e, + 0x66, 0x77, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x1a, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x66, 0x77, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x4b, 0x65, + 0x79, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x75, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x75, + 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x1c, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x22, 0x0e, 0x0a, 0x0c, + 0x43, 0x6c, 0x65, 0x61, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x03, 0x0a, + 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, + 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x73, 0x65, 0x50, 0x61, 0x73, + 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x68, 0x6f, 0x6d, 0x65, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x68, 0x6f, 0x6d, + 0x65, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x12, 0x6e, 0x0a, 0x11, 0x70, 0x61, 0x73, 0x73, 0x70, + 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x2e, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x5f, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x6b, 0x44, 0x65, 0x6c, + 0x61, 0x79, 0x4d, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, + 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x35, 0x0a, 0x14, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x4b, 0x10, 0x00, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x56, 0x49, 0x43, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x48, 0x4f, 0x53, 0x54, 0x10, 0x02, 0x22, 0x22, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x46, + 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0x23, 0x0a, 0x09, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x50, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, + 0xa9, 0x01, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x11, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x08, 0x0a, 0x06, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x22, 0x20, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x23, 0x0a, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x01, 0x20, + 0x02, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x22, 0x0c, 0x0a, 0x0a, + 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0xab, 0x02, 0x0a, 0x0a, 0x4c, + 0x6f, 0x61, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x6e, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x6e, 0x65, + 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x12, 0x39, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, + 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x07, 0x65, 0x6e, 0x67, 0x6c, 0x69, + 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x73, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, 0x32, + 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x22, 0xcb, 0x02, 0x0a, 0x0b, 0x52, 0x65, 0x73, + 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0d, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, + 0x1f, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x3a, 0x03, 0x32, 0x35, 0x36, 0x52, 0x08, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x70, + 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x08, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x07, + 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, 0x32, + 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, + 0x6b, 0x69, 0x70, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, + 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, + 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x22, 0x0e, 0x0a, 0x0c, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x26, 0x0a, 0x0a, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x41, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x22, 0xdd, 0x03, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x15, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x14, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x69, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x70, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, + 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x3a, 0x07, 0x65, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x64, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0f, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x64, + 0x6c, 0x69, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, + 0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0a, 0x75, 0x32, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, + 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, + 0x79, 0x52, 0x75, 0x6e, 0x22, 0x5a, 0x0a, 0x12, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x63, 0x72, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x64, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x10, + 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x10, 0x01, + 0x22, 0xc5, 0x01, 0x0a, 0x0b, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x4e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3a, + 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x57, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x6f, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x66, 0x0a, 0x0f, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, 0x12, 0x1b, + 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x39, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x57, + 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, + 0x61, 0x74, 0x72, 0x69, 0x78, 0x36, 0x10, 0x02, 0x22, 0x1d, 0x0a, 0x07, 0x57, 0x6f, 0x72, 0x64, + 0x41, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, + 0x09, 0x52, 0x04, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x30, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x55, 0x32, + 0x46, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x32, 0x66, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x75, + 0x32, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x42, 0x79, 0x0a, 0x23, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, 0x72, 0x65, + 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x17, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, + 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, + 0x65, 0x7a, 0x6f, 0x72, } -func init() { proto.RegisterFile("messages-management.proto", fileDescriptor_0c720c20d27aa029) } +var ( + file_messages_management_proto_rawDescOnce sync.Once + file_messages_management_proto_rawDescData = file_messages_management_proto_rawDesc +) -var fileDescriptor_0c720c20d27aa029 = []byte{ - // 1393 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xdd, 0x6e, 0xdb, 0xc8, - 0x15, 0x8e, 0x7e, 0x62, 0x49, 0xc7, 0xfa, 0xcb, 0xd4, 0x8e, 0xe9, 0xb8, 0x6e, 0x1c, 0xba, 0x6e, - 0x12, 0x04, 0x15, 0x0a, 0x17, 0x09, 0x90, 0x5c, 0x14, 0x75, 0xec, 0xfc, 0x21, 0x71, 0x6a, 0xd0, - 0x6e, 0x02, 0xf4, 0x86, 0x18, 0x91, 0x47, 0xd2, 0xd4, 0xe4, 0x0c, 0xcb, 0x19, 0xda, 0x55, 0x5e, - 0x60, 0x6f, 0xf6, 0x45, 0x16, 0xfb, 0x1c, 0x7b, 0xb5, 0xcf, 0xb0, 0xef, 0xb2, 0x98, 0x19, 0x52, - 0xa2, 0x65, 0x3b, 0x46, 0x76, 0xef, 0xe6, 0x7c, 0xe7, 0xe3, 0x68, 0xce, 0x77, 0xbe, 0x39, 0x63, - 0xc3, 0x7a, 0x8c, 0x52, 0xd2, 0x31, 0xca, 0xbf, 0xc6, 0x94, 0xd3, 0x31, 0xc6, 0xc8, 0xd5, 0x20, - 0x49, 0x85, 0x12, 0x64, 0x73, 0x72, 0x3e, 0x50, 0x29, 0x7e, 0x11, 0xe9, 0xa0, 0x20, 0x0d, 0xe6, - 0xa4, 0x7b, 0xab, 0xb3, 0x2f, 0x03, 0x11, 0xc7, 0x82, 0xdb, 0xaf, 0xdc, 0xf7, 0x00, 0xef, 0x38, - 0x53, 0x8c, 0x46, 0xec, 0x0b, 0x92, 0x15, 0xb8, 0x2d, 0x15, 0x55, 0xe8, 0x54, 0xb6, 0x2a, 0x8f, - 0xda, 0x9e, 0x0d, 0xc8, 0x43, 0xe8, 0xc9, 0x53, 0x96, 0xf8, 0x09, 0x95, 0x32, 0x99, 0xa4, 0x54, - 0xa2, 0x53, 0xdd, 0xaa, 0x3c, 0x6a, 0x7a, 0x5d, 0x0d, 0x1f, 0xcd, 0x50, 0xb7, 0x03, 0xcb, 0x6f, - 0x50, 0xbd, 0x46, 0xaa, 0xb2, 0x14, 0xa5, 0xfb, 0x7d, 0x03, 0x9a, 0x45, 0x40, 0xee, 0xc2, 0xd2, - 0x19, 0xf2, 0x50, 0xa4, 0x66, 0xef, 0x96, 0x97, 0x47, 0x64, 0x1b, 0x3a, 0x31, 0xfd, 0xaf, 0x48, - 0xfd, 0x33, 0x4c, 0x25, 0x13, 0xdc, 0x6c, 0xdd, 0xf1, 0xda, 0x06, 0xfc, 0x64, 0x31, 0x43, 0x62, - 0xbc, 0x44, 0xaa, 0xe5, 0x24, 0x0d, 0x96, 0x48, 0x09, 0x55, 0xc1, 0x64, 0x46, 0xaa, 0x5b, 0x92, - 0x01, 0x0b, 0xd2, 0x43, 0xe8, 0x0d, 0x85, 0x50, 0x91, 0xa0, 0x21, 0xa6, 0x7e, 0x2c, 0x42, 0x74, - 0x6e, 0xdb, 0x5a, 0xe6, 0xf0, 0xa1, 0x08, 0x91, 0x6c, 0x40, 0x2b, 0xc4, 0x33, 0x16, 0xa0, 0xcf, - 0x42, 0x67, 0xc9, 0x1c, 0xb9, 0x69, 0x81, 0x77, 0x21, 0xd9, 0x81, 0x6e, 0xc2, 0xb8, 0xaf, 0x25, - 0xc4, 0x40, 0xe9, 0xdf, 0x6a, 0x98, 0x4d, 0x3a, 0x09, 0xe3, 0x47, 0x33, 0x90, 0xfc, 0x1d, 0x56, - 0xe7, 0x9a, 0x95, 0xd9, 0x4d, 0xc3, 0x5e, 0x99, 0x27, 0x4b, 0x1f, 0xdd, 0x83, 0x66, 0x44, 0xf9, - 0x38, 0xa3, 0x63, 0x74, 0x5a, 0xf6, 0x77, 0x8b, 0x58, 0xf7, 0x27, 0xa2, 0x43, 0x8c, 0x1c, 0x30, - 0x09, 0x1b, 0x90, 0x2d, 0x58, 0x66, 0xb3, 0x1e, 0x86, 0x4e, 0xdb, 0x6c, 0x5e, 0x86, 0xf4, 0x9e, - 0x29, 0x9e, 0x31, 0xa3, 0x4a, 0xc7, 0xb4, 0x76, 0x16, 0x2f, 0x28, 0x32, 0xa1, 0x72, 0xe2, 0x74, - 0x0d, 0xa5, 0xa4, 0xc8, 0x5b, 0x2a, 0x27, 0x7a, 0x13, 0x16, 0x27, 0x22, 0x55, 0x18, 0x3a, 0x3d, - 0xf3, 0x1b, 0xb3, 0x98, 0x6c, 0x02, 0x68, 0x41, 0x02, 0x1a, 0x4c, 0x30, 0x74, 0xfa, 0x26, 0xdb, - 0x4a, 0x18, 0xdf, 0x37, 0x00, 0x79, 0x02, 0x77, 0x4a, 0x42, 0xe4, 0xac, 0x3b, 0x86, 0xd5, 0x9f, - 0x27, 0x72, 0xf2, 0x63, 0xe8, 0x8f, 0x58, 0x1a, 0x9f, 0xd3, 0x54, 0x6b, 0x86, 0x12, 0xb9, 0x72, - 0x88, 0xe1, 0xf6, 0x0a, 0xfc, 0xc8, 0xc2, 0xe4, 0x01, 0xb4, 0x39, 0x62, 0x28, 0xfd, 0x21, 0x0d, - 0x4e, 0xb3, 0xc4, 0xf9, 0x83, 0x2d, 0xdd, 0x60, 0x2f, 0x0d, 0xa4, 0x25, 0x1b, 0x45, 0x74, 0x2c, - 0x9d, 0x15, 0xe3, 0x06, 0x1b, 0x68, 0x54, 0xf7, 0x3e, 0x72, 0x56, 0xad, 0x90, 0x26, 0x20, 0xeb, - 0xd0, 0x1c, 0x9d, 0xfb, 0xc6, 0x79, 0xce, 0x5d, 0x43, 0x6f, 0x8c, 0xce, 0x0f, 0x75, 0x58, 0xa4, - 0xb4, 0xdf, 0x9c, 0xb5, 0x59, 0x4a, 0x87, 0x79, 0xca, 0xb8, 0xcc, 0x71, 0x8a, 0xd4, 0x91, 0x0e, - 0xb5, 0x89, 0x46, 0xe7, 0x7e, 0xee, 0xfb, 0x75, 0xdb, 0xcc, 0xd1, 0xf9, 0x27, 0xeb, 0xfc, 0x3f, - 0x43, 0x77, 0x96, 0xf4, 0x4f, 0x71, 0x2a, 0x9d, 0x7b, 0x46, 0xf7, 0x76, 0xc1, 0x78, 0x8f, 0x53, - 0xa9, 0xa5, 0xcb, 0xf8, 0x88, 0x71, 0x26, 0x27, 0x18, 0x16, 0x75, 0x6e, 0x58, 0xe9, 0xe6, 0x89, - 0xbc, 0xd8, 0x0d, 0x68, 0x71, 0x51, 0x90, 0xfe, 0x68, 0x7b, 0xc4, 0x85, 0x4d, 0xba, 0x5d, 0x68, - 0xef, 0x47, 0x48, 0xd3, 0x63, 0x94, 0xba, 0xf1, 0xee, 0x77, 0x35, 0xe8, 0xec, 0x25, 0x49, 0x34, - 0x3d, 0x46, 0xa5, 0x18, 0x1f, 0xcb, 0x0b, 0xd6, 0xab, 0x5c, 0x67, 0xbd, 0x6a, 0xd9, 0x7a, 0x3b, - 0xd0, 0xcd, 0xb4, 0xb5, 0xe7, 0x93, 0xa1, 0x66, 0x2f, 0x42, 0x26, 0x71, 0x3e, 0x18, 0xc8, 0x9f, - 0x00, 0x26, 0x22, 0x46, 0x19, 0xa4, 0x88, 0xf6, 0x5e, 0xb6, 0xbd, 0x12, 0x42, 0xf8, 0x05, 0x7f, - 0x48, 0x91, 0xa5, 0x81, 0xbd, 0x97, 0xdd, 0xdd, 0xbd, 0xc1, 0x57, 0xe7, 0xda, 0xe0, 0x42, 0x05, - 0x83, 0xf9, 0x6f, 0x1e, 0x9b, 0x4d, 0x4e, 0xa6, 0x09, 0x96, 0x2d, 0x66, 0x51, 0xf2, 0x04, 0x08, - 0xcd, 0x94, 0xf0, 0x23, 0x11, 0x9c, 0xfa, 0x21, 0x46, 0x74, 0xea, 0xc7, 0xd2, 0xdc, 0xf2, 0x8e, - 0xd7, 0xd3, 0x99, 0x0f, 0x22, 0x38, 0x3d, 0xd0, 0xf8, 0xa1, 0xd4, 0x7e, 0x0c, 0x99, 0x4c, 0x34, - 0x29, 0x15, 0x8a, 0xce, 0xae, 0x7b, 0xc7, 0xeb, 0xe5, 0xb8, 0x97, 0xc3, 0xee, 0x53, 0x58, 0xb9, - 0xea, 0x04, 0xa4, 0x01, 0xb5, 0xbd, 0xe3, 0xf7, 0xfd, 0x5b, 0x04, 0x60, 0xe9, 0xe0, 0xd5, 0xa7, - 0x77, 0xfb, 0xaf, 0xfa, 0x15, 0xd2, 0x84, 0xfa, 0xdb, 0x7f, 0x1d, 0x9f, 0xf4, 0xab, 0xae, 0x0b, - 0x60, 0xca, 0x78, 0x5d, 0x78, 0xd3, 0x3a, 0xb6, 0x52, 0x72, 0xac, 0xbb, 0x0d, 0xad, 0xfd, 0x09, - 0xe5, 0x63, 0x3c, 0x62, 0x5c, 0x0f, 0xd3, 0x14, 0x63, 0x71, 0x66, 0xdb, 0xd4, 0xf4, 0xf2, 0xc8, - 0xfd, 0xa1, 0x02, 0xf5, 0x23, 0xc6, 0xc7, 0xc4, 0x81, 0x46, 0x2e, 0x56, 0xde, 0xc8, 0x22, 0xd4, - 0x7e, 0x1a, 0x66, 0x4a, 0x89, 0x0b, 0xd3, 0xcb, 0x8e, 0xf3, 0xbe, 0x4d, 0x94, 0x66, 0xd1, 0xe5, - 0x39, 0x57, 0xfb, 0xa6, 0x39, 0x57, 0xbf, 0x7e, 0xce, 0xb9, 0x4d, 0x58, 0xda, 0xa7, 0x3c, 0xc0, - 0xc8, 0xdd, 0x02, 0x78, 0x83, 0xea, 0x15, 0x57, 0xa9, 0x48, 0xa6, 0x84, 0x40, 0x5d, 0xb2, 0x2f, - 0xfa, 0xdc, 0xd5, 0x47, 0x1d, 0xcf, 0xac, 0xdd, 0x6d, 0x68, 0x14, 0x69, 0x07, 0x1a, 0x68, 0x97, - 0x86, 0xd1, 0xf6, 0x8a, 0xd0, 0x6d, 0x03, 0x7c, 0x66, 0x09, 0x1e, 0x98, 0x21, 0xed, 0xfe, 0x58, - 0x05, 0xf8, 0x20, 0x68, 0x68, 0x43, 0x6d, 0xed, 0x98, 0x63, 0x2c, 0x38, 0x0b, 0x0a, 0x6b, 0x17, - 0x31, 0x79, 0x0e, 0x75, 0xae, 0x1f, 0x02, 0xad, 0xc2, 0xf2, 0xee, 0xce, 0x55, 0x86, 0xcb, 0xdf, - 0xcc, 0xb7, 0x07, 0x1f, 0x45, 0x68, 0x4d, 0x65, 0x3e, 0x21, 0x7d, 0xa8, 0x25, 0xcc, 0xaa, 0xd2, - 0xf2, 0xf4, 0xf2, 0x37, 0x69, 0x41, 0xb6, 0x4b, 0x17, 0x4f, 0xdb, 0xbe, 0xf5, 0xa2, 0x81, 0x7c, - 0x1c, 0x31, 0x39, 0xb9, 0xea, 0x06, 0x2e, 0x95, 0x6f, 0xe0, 0x36, 0x74, 0xcc, 0xe3, 0x1c, 0x4c, - 0x30, 0x38, 0x95, 0x59, 0x9c, 0xbf, 0x44, 0x6d, 0x0d, 0xee, 0xe7, 0x18, 0xb9, 0x0f, 0xcb, 0xd9, - 0xee, 0xc8, 0x0f, 0x44, 0xc6, 0x15, 0xa6, 0xe6, 0xf9, 0xe9, 0x78, 0x90, 0xed, 0x8e, 0xf6, 0x2d, - 0xe2, 0xfe, 0x5c, 0x85, 0x65, 0x0f, 0x25, 0xaa, 0x5c, 0xae, 0x1d, 0xe8, 0xce, 0x3c, 0x4f, 0x79, - 0x28, 0xe2, 0xdc, 0x68, 0x9d, 0xc2, 0xf1, 0x06, 0x24, 0xf7, 0xa1, 0x29, 0x55, 0x8a, 0x7c, 0xac, - 0x26, 0xf6, 0xdd, 0x7e, 0x51, 0xdb, 0x7d, 0xfa, 0xcc, 0x9b, 0x81, 0xd7, 0xab, 0x51, 0xfb, 0x8a, - 0x1a, 0x97, 0x5d, 0x57, 0xbf, 0xca, 0x75, 0xbf, 0x43, 0xb4, 0x05, 0x3d, 0x1a, 0x8b, 0x7a, 0x68, - 0x82, 0x51, 0x35, 0x1f, 0xa5, 0xf6, 0xbd, 0x06, 0x0d, 0x5d, 0x35, 0x69, 0x5b, 0x97, 0x27, 0xad, - 0x5d, 0xe5, 0x5e, 0xec, 0x43, 0x37, 0xb7, 0xaf, 0x87, 0xff, 0xcb, 0x50, 0x2a, 0xf7, 0x2f, 0x00, - 0x39, 0xb2, 0x17, 0x9c, 0x5e, 0xf4, 0x74, 0xa5, 0xec, 0xe9, 0x5f, 0x6a, 0xd0, 0xf5, 0x30, 0x10, - 0x67, 0x98, 0x4e, 0xf3, 0xd6, 0x6c, 0x02, 0x9c, 0x8b, 0x34, 0xb4, 0x87, 0xcf, 0x67, 0x44, 0x4b, - 0x23, 0xe6, 0xec, 0xd7, 0x2b, 0x5e, 0xfd, 0x26, 0xc5, 0x6b, 0x37, 0x29, 0x5e, 0xbf, 0x51, 0xf1, - 0xdb, 0x65, 0xc5, 0x1f, 0x43, 0x1f, 0xf9, 0x48, 0xa4, 0x01, 0xfa, 0xfa, 0xac, 0x11, 0x93, 0xca, - 0xb4, 0xa4, 0xe9, 0xf5, 0x72, 0xfc, 0x73, 0x0e, 0x93, 0x13, 0xa8, 0xab, 0x69, 0x82, 0x46, 0xf4, - 0xee, 0xee, 0x3f, 0x6f, 0x98, 0xff, 0x17, 0xd5, 0x59, 0x08, 0xed, 0x4d, 0xd5, 0xbb, 0x2d, 0xb6, - 0xbc, 0x75, 0xa9, 0xe5, 0x6b, 0xd0, 0x08, 0xd3, 0xa9, 0x9f, 0x66, 0xdc, 0xfc, 0x75, 0xd5, 0xf4, - 0x96, 0xc2, 0x74, 0xea, 0x65, 0xdc, 0xfd, 0x0f, 0x90, 0xcb, 0xbb, 0x92, 0x1d, 0x78, 0x70, 0x19, - 0xf5, 0x8f, 0x83, 0x94, 0xc6, 0xc3, 0x08, 0x43, 0x5d, 0x8d, 0xec, 0xdf, 0x22, 0x9b, 0xb0, 0x7e, - 0x05, 0xed, 0x90, 0xaa, 0x94, 0xfd, 0xbf, 0x5f, 0x71, 0x7f, 0xaa, 0xc0, 0xb2, 0xa6, 0xe6, 0xbe, - 0x20, 0x1f, 0xf3, 0xda, 0x2b, 0xa6, 0xf6, 0x17, 0x37, 0xd4, 0x5e, 0xfa, 0xb2, 0xbc, 0x9e, 0x57, - 0xed, 0x8e, 0xa0, 0xb7, 0x90, 0x20, 0xeb, 0xb0, 0xba, 0x00, 0xf9, 0x47, 0x11, 0x65, 0xbc, 0x7f, - 0x8b, 0x6c, 0xc0, 0xda, 0x62, 0xca, 0x9e, 0xf4, 0x79, 0xbf, 0x72, 0x7d, 0xf2, 0x59, 0xbf, 0xea, - 0x6e, 0x42, 0x43, 0x27, 0xb5, 0x99, 0x09, 0xd4, 0x75, 0x87, 0xcd, 0x74, 0x6e, 0x79, 0x66, 0xed, - 0xfe, 0x0d, 0x3a, 0xc7, 0xa8, 0xfe, 0xbd, 0xfb, 0xba, 0x74, 0xbf, 0xca, 0xdd, 0xa8, 0x2c, 0x76, - 0xe3, 0xe5, 0x3f, 0x60, 0x3b, 0x10, 0xf1, 0x40, 0x52, 0x25, 0xe4, 0x84, 0x45, 0x74, 0x28, 0x0b, - 0x21, 0x22, 0x36, 0xb4, 0xff, 0xbb, 0x0c, 0xb3, 0xd1, 0xcb, 0xb5, 0x13, 0x03, 0x1e, 0x5a, 0x71, - 0x0e, 0x67, 0xd2, 0xfc, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x6e, 0xfc, 0x59, 0x29, 0x0d, 0x00, - 0x00, +func file_messages_management_proto_rawDescGZIP() []byte { + file_messages_management_proto_rawDescOnce.Do(func() { + file_messages_management_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_management_proto_rawDescData) + }) + return file_messages_management_proto_rawDescData +} + +var file_messages_management_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_messages_management_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_messages_management_proto_goTypes = []interface{}{ + (ApplySettings_PassphraseSourceType)(0), // 0: hw.trezor.messages.management.ApplySettings.PassphraseSourceType + (RecoveryDevice_RecoveryDeviceType)(0), // 1: hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceType + (WordRequest_WordRequestType)(0), // 2: hw.trezor.messages.management.WordRequest.WordRequestType + (*Initialize)(nil), // 3: hw.trezor.messages.management.Initialize + (*GetFeatures)(nil), // 4: hw.trezor.messages.management.GetFeatures + (*Features)(nil), // 5: hw.trezor.messages.management.Features + (*ClearSession)(nil), // 6: hw.trezor.messages.management.ClearSession + (*ApplySettings)(nil), // 7: hw.trezor.messages.management.ApplySettings + (*ApplyFlags)(nil), // 8: hw.trezor.messages.management.ApplyFlags + (*ChangePin)(nil), // 9: hw.trezor.messages.management.ChangePin + (*Ping)(nil), // 10: hw.trezor.messages.management.Ping + (*Cancel)(nil), // 11: hw.trezor.messages.management.Cancel + (*GetEntropy)(nil), // 12: hw.trezor.messages.management.GetEntropy + (*Entropy)(nil), // 13: hw.trezor.messages.management.Entropy + (*WipeDevice)(nil), // 14: hw.trezor.messages.management.WipeDevice + (*LoadDevice)(nil), // 15: hw.trezor.messages.management.LoadDevice + (*ResetDevice)(nil), // 16: hw.trezor.messages.management.ResetDevice + (*BackupDevice)(nil), // 17: hw.trezor.messages.management.BackupDevice + (*EntropyRequest)(nil), // 18: hw.trezor.messages.management.EntropyRequest + (*EntropyAck)(nil), // 19: hw.trezor.messages.management.EntropyAck + (*RecoveryDevice)(nil), // 20: hw.trezor.messages.management.RecoveryDevice + (*WordRequest)(nil), // 21: hw.trezor.messages.management.WordRequest + (*WordAck)(nil), // 22: hw.trezor.messages.management.WordAck + (*SetU2FCounter)(nil), // 23: hw.trezor.messages.management.SetU2FCounter + (*HDNodeType)(nil), // 24: hw.trezor.messages.common.HDNodeType +} +var file_messages_management_proto_depIdxs = []int32{ + 0, // 0: hw.trezor.messages.management.ApplySettings.passphrase_source:type_name -> hw.trezor.messages.management.ApplySettings.PassphraseSourceType + 24, // 1: hw.trezor.messages.management.LoadDevice.node:type_name -> hw.trezor.messages.common.HDNodeType + 1, // 2: hw.trezor.messages.management.RecoveryDevice.type:type_name -> hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceType + 2, // 3: hw.trezor.messages.management.WordRequest.type:type_name -> hw.trezor.messages.management.WordRequest.WordRequestType + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_messages_management_proto_init() } +func file_messages_management_proto_init() { + if File_messages_management_proto != nil { + return + } + file_messages_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_messages_management_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Initialize); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetFeatures); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Features); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClearSession); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplySettings); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyFlags); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChangePin); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Ping); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Cancel); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEntropy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Entropy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WipeDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LoadDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResetDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BackupDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EntropyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EntropyAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RecoveryDevice); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WordRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WordAck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messages_management_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetU2FCounter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_management_proto_rawDesc, + NumEnums: 3, + NumMessages: 21, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_messages_management_proto_goTypes, + DependencyIndexes: file_messages_management_proto_depIdxs, + EnumInfos: file_messages_management_proto_enumTypes, + MessageInfos: file_messages_management_proto_msgTypes, + }.Build() + File_messages_management_proto = out.File + file_messages_management_proto_rawDesc = nil + file_messages_management_proto_goTypes = nil + file_messages_management_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages-management.proto b/accounts/usbwallet/trezor/messages-management.proto index 0ab825a1bc..1eb34b5ea5 100644 --- a/accounts/usbwallet/trezor/messages-management.proto +++ b/accounts/usbwallet/trezor/messages-management.proto @@ -5,6 +5,8 @@ syntax = "proto2"; package hw.trezor.messages.management; +option go_package = "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessageManagement"; diff --git a/accounts/usbwallet/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go index 6278bd8ee0..5cc7b222cb 100644 --- a/accounts/usbwallet/trezor/messages.pb.go +++ b/accounts/usbwallet/trezor/messages.pb.go @@ -1,26 +1,29 @@ +// This file originates from the SatoshiLabs Trezor `common` repository at: +// https://github.com/trezor/trezor-common/blob/master/protob/messages.proto +// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9. + // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.1 // source: messages.proto package trezor import ( - fmt "fmt" - math "math" - - proto "github.com/golang/protobuf/proto" - descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) //* // Mapping between TREZOR wire identifier (uint) and a protobuf message @@ -241,397 +244,399 @@ const ( MessageType_MessageType_BinanceSignedTx MessageType = 709 ) -var MessageType_name = map[int32]string{ - 0: "MessageType_Initialize", - 1: "MessageType_Ping", - 2: "MessageType_Success", - 3: "MessageType_Failure", - 4: "MessageType_ChangePin", - 5: "MessageType_WipeDevice", - 9: "MessageType_GetEntropy", - 10: "MessageType_Entropy", - 13: "MessageType_LoadDevice", - 14: "MessageType_ResetDevice", - 17: "MessageType_Features", - 18: "MessageType_PinMatrixRequest", - 19: "MessageType_PinMatrixAck", - 20: "MessageType_Cancel", - 24: "MessageType_ClearSession", - 25: "MessageType_ApplySettings", - 26: "MessageType_ButtonRequest", - 27: "MessageType_ButtonAck", - 28: "MessageType_ApplyFlags", - 34: "MessageType_BackupDevice", - 35: "MessageType_EntropyRequest", - 36: "MessageType_EntropyAck", - 41: "MessageType_PassphraseRequest", - 42: "MessageType_PassphraseAck", - 77: "MessageType_PassphraseStateRequest", - 78: "MessageType_PassphraseStateAck", - 45: "MessageType_RecoveryDevice", - 46: "MessageType_WordRequest", - 47: "MessageType_WordAck", - 55: "MessageType_GetFeatures", - 63: "MessageType_SetU2FCounter", - 6: "MessageType_FirmwareErase", - 7: "MessageType_FirmwareUpload", - 8: "MessageType_FirmwareRequest", - 32: "MessageType_SelfTest", - 11: "MessageType_GetPublicKey", - 12: "MessageType_PublicKey", - 15: "MessageType_SignTx", - 21: "MessageType_TxRequest", - 22: "MessageType_TxAck", - 29: "MessageType_GetAddress", - 30: "MessageType_Address", - 38: "MessageType_SignMessage", - 39: "MessageType_VerifyMessage", - 40: "MessageType_MessageSignature", - 23: "MessageType_CipherKeyValue", - 48: "MessageType_CipheredKeyValue", - 53: "MessageType_SignIdentity", - 54: "MessageType_SignedIdentity", - 61: "MessageType_GetECDHSessionKey", - 62: "MessageType_ECDHSessionKey", - 71: "MessageType_CosiCommit", - 72: "MessageType_CosiCommitment", - 73: "MessageType_CosiSign", - 74: "MessageType_CosiSignature", - 100: "MessageType_DebugLinkDecision", - 101: "MessageType_DebugLinkGetState", - 102: "MessageType_DebugLinkState", - 103: "MessageType_DebugLinkStop", - 104: "MessageType_DebugLinkLog", - 110: "MessageType_DebugLinkMemoryRead", - 111: "MessageType_DebugLinkMemory", - 112: "MessageType_DebugLinkMemoryWrite", - 113: "MessageType_DebugLinkFlashErase", - 450: "MessageType_EthereumGetPublicKey", - 451: "MessageType_EthereumPublicKey", - 56: "MessageType_EthereumGetAddress", - 57: "MessageType_EthereumAddress", - 58: "MessageType_EthereumSignTx", - 59: "MessageType_EthereumTxRequest", - 60: "MessageType_EthereumTxAck", - 64: "MessageType_EthereumSignMessage", - 65: "MessageType_EthereumVerifyMessage", - 66: "MessageType_EthereumMessageSignature", - 67: "MessageType_NEMGetAddress", - 68: "MessageType_NEMAddress", - 69: "MessageType_NEMSignTx", - 70: "MessageType_NEMSignedTx", - 75: "MessageType_NEMDecryptMessage", - 76: "MessageType_NEMDecryptedMessage", - 114: "MessageType_LiskGetAddress", - 115: "MessageType_LiskAddress", - 116: "MessageType_LiskSignTx", - 117: "MessageType_LiskSignedTx", - 118: "MessageType_LiskSignMessage", - 119: "MessageType_LiskMessageSignature", - 120: "MessageType_LiskVerifyMessage", - 121: "MessageType_LiskGetPublicKey", - 122: "MessageType_LiskPublicKey", - 150: "MessageType_TezosGetAddress", - 151: "MessageType_TezosAddress", - 152: "MessageType_TezosSignTx", - 153: "MessageType_TezosSignedTx", - 154: "MessageType_TezosGetPublicKey", - 155: "MessageType_TezosPublicKey", - 202: "MessageType_StellarSignTx", - 203: "MessageType_StellarTxOpRequest", - 207: "MessageType_StellarGetAddress", - 208: "MessageType_StellarAddress", - 210: "MessageType_StellarCreateAccountOp", - 211: "MessageType_StellarPaymentOp", - 212: "MessageType_StellarPathPaymentOp", - 213: "MessageType_StellarManageOfferOp", - 214: "MessageType_StellarCreatePassiveOfferOp", - 215: "MessageType_StellarSetOptionsOp", - 216: "MessageType_StellarChangeTrustOp", - 217: "MessageType_StellarAllowTrustOp", - 218: "MessageType_StellarAccountMergeOp", - 220: "MessageType_StellarManageDataOp", - 221: "MessageType_StellarBumpSequenceOp", - 230: "MessageType_StellarSignedTx", - 250: "MessageType_TronGetAddress", - 251: "MessageType_TronAddress", - 252: "MessageType_TronSignTx", - 253: "MessageType_TronSignedTx", - 303: "MessageType_CardanoSignTx", - 304: "MessageType_CardanoTxRequest", - 305: "MessageType_CardanoGetPublicKey", - 306: "MessageType_CardanoPublicKey", - 307: "MessageType_CardanoGetAddress", - 308: "MessageType_CardanoAddress", - 309: "MessageType_CardanoTxAck", - 310: "MessageType_CardanoSignedTx", - 350: "MessageType_OntologyGetAddress", - 351: "MessageType_OntologyAddress", - 352: "MessageType_OntologyGetPublicKey", - 353: "MessageType_OntologyPublicKey", - 354: "MessageType_OntologySignTransfer", - 355: "MessageType_OntologySignedTransfer", - 356: "MessageType_OntologySignWithdrawOng", - 357: "MessageType_OntologySignedWithdrawOng", - 358: "MessageType_OntologySignOntIdRegister", - 359: "MessageType_OntologySignedOntIdRegister", - 360: "MessageType_OntologySignOntIdAddAttributes", - 361: "MessageType_OntologySignedOntIdAddAttributes", - 400: "MessageType_RippleGetAddress", - 401: "MessageType_RippleAddress", - 402: "MessageType_RippleSignTx", - 403: "MessageType_RippleSignedTx", - 501: "MessageType_MoneroTransactionInitRequest", - 502: "MessageType_MoneroTransactionInitAck", - 503: "MessageType_MoneroTransactionSetInputRequest", - 504: "MessageType_MoneroTransactionSetInputAck", - 505: "MessageType_MoneroTransactionInputsPermutationRequest", - 506: "MessageType_MoneroTransactionInputsPermutationAck", - 507: "MessageType_MoneroTransactionInputViniRequest", - 508: "MessageType_MoneroTransactionInputViniAck", - 509: "MessageType_MoneroTransactionAllInputsSetRequest", - 510: "MessageType_MoneroTransactionAllInputsSetAck", - 511: "MessageType_MoneroTransactionSetOutputRequest", - 512: "MessageType_MoneroTransactionSetOutputAck", - 513: "MessageType_MoneroTransactionAllOutSetRequest", - 514: "MessageType_MoneroTransactionAllOutSetAck", - 515: "MessageType_MoneroTransactionSignInputRequest", - 516: "MessageType_MoneroTransactionSignInputAck", - 517: "MessageType_MoneroTransactionFinalRequest", - 518: "MessageType_MoneroTransactionFinalAck", - 530: "MessageType_MoneroKeyImageExportInitRequest", - 531: "MessageType_MoneroKeyImageExportInitAck", - 532: "MessageType_MoneroKeyImageSyncStepRequest", - 533: "MessageType_MoneroKeyImageSyncStepAck", - 534: "MessageType_MoneroKeyImageSyncFinalRequest", - 535: "MessageType_MoneroKeyImageSyncFinalAck", - 540: "MessageType_MoneroGetAddress", - 541: "MessageType_MoneroAddress", - 542: "MessageType_MoneroGetWatchKey", - 543: "MessageType_MoneroWatchKey", - 546: "MessageType_DebugMoneroDiagRequest", - 547: "MessageType_DebugMoneroDiagAck", - 550: "MessageType_MoneroGetTxKeyRequest", - 551: "MessageType_MoneroGetTxKeyAck", - 552: "MessageType_MoneroLiveRefreshStartRequest", - 553: "MessageType_MoneroLiveRefreshStartAck", - 554: "MessageType_MoneroLiveRefreshStepRequest", - 555: "MessageType_MoneroLiveRefreshStepAck", - 556: "MessageType_MoneroLiveRefreshFinalRequest", - 557: "MessageType_MoneroLiveRefreshFinalAck", - 600: "MessageType_EosGetPublicKey", - 601: "MessageType_EosPublicKey", - 602: "MessageType_EosSignTx", - 603: "MessageType_EosTxActionRequest", - 604: "MessageType_EosTxActionAck", - 605: "MessageType_EosSignedTx", - 700: "MessageType_BinanceGetAddress", - 701: "MessageType_BinanceAddress", - 702: "MessageType_BinanceGetPublicKey", - 703: "MessageType_BinancePublicKey", - 704: "MessageType_BinanceSignTx", - 705: "MessageType_BinanceTxRequest", - 706: "MessageType_BinanceTransferMsg", - 707: "MessageType_BinanceOrderMsg", - 708: "MessageType_BinanceCancelMsg", - 709: "MessageType_BinanceSignedTx", -} - -var MessageType_value = map[string]int32{ - "MessageType_Initialize": 0, - "MessageType_Ping": 1, - "MessageType_Success": 2, - "MessageType_Failure": 3, - "MessageType_ChangePin": 4, - "MessageType_WipeDevice": 5, - "MessageType_GetEntropy": 9, - "MessageType_Entropy": 10, - "MessageType_LoadDevice": 13, - "MessageType_ResetDevice": 14, - "MessageType_Features": 17, - "MessageType_PinMatrixRequest": 18, - "MessageType_PinMatrixAck": 19, - "MessageType_Cancel": 20, - "MessageType_ClearSession": 24, - "MessageType_ApplySettings": 25, - "MessageType_ButtonRequest": 26, - "MessageType_ButtonAck": 27, - "MessageType_ApplyFlags": 28, - "MessageType_BackupDevice": 34, - "MessageType_EntropyRequest": 35, - "MessageType_EntropyAck": 36, - "MessageType_PassphraseRequest": 41, - "MessageType_PassphraseAck": 42, - "MessageType_PassphraseStateRequest": 77, - "MessageType_PassphraseStateAck": 78, - "MessageType_RecoveryDevice": 45, - "MessageType_WordRequest": 46, - "MessageType_WordAck": 47, - "MessageType_GetFeatures": 55, - "MessageType_SetU2FCounter": 63, - "MessageType_FirmwareErase": 6, - "MessageType_FirmwareUpload": 7, - "MessageType_FirmwareRequest": 8, - "MessageType_SelfTest": 32, - "MessageType_GetPublicKey": 11, - "MessageType_PublicKey": 12, - "MessageType_SignTx": 15, - "MessageType_TxRequest": 21, - "MessageType_TxAck": 22, - "MessageType_GetAddress": 29, - "MessageType_Address": 30, - "MessageType_SignMessage": 38, - "MessageType_VerifyMessage": 39, - "MessageType_MessageSignature": 40, - "MessageType_CipherKeyValue": 23, - "MessageType_CipheredKeyValue": 48, - "MessageType_SignIdentity": 53, - "MessageType_SignedIdentity": 54, - "MessageType_GetECDHSessionKey": 61, - "MessageType_ECDHSessionKey": 62, - "MessageType_CosiCommit": 71, - "MessageType_CosiCommitment": 72, - "MessageType_CosiSign": 73, - "MessageType_CosiSignature": 74, - "MessageType_DebugLinkDecision": 100, - "MessageType_DebugLinkGetState": 101, - "MessageType_DebugLinkState": 102, - "MessageType_DebugLinkStop": 103, - "MessageType_DebugLinkLog": 104, - "MessageType_DebugLinkMemoryRead": 110, - "MessageType_DebugLinkMemory": 111, - "MessageType_DebugLinkMemoryWrite": 112, - "MessageType_DebugLinkFlashErase": 113, - "MessageType_EthereumGetPublicKey": 450, - "MessageType_EthereumPublicKey": 451, - "MessageType_EthereumGetAddress": 56, - "MessageType_EthereumAddress": 57, - "MessageType_EthereumSignTx": 58, - "MessageType_EthereumTxRequest": 59, - "MessageType_EthereumTxAck": 60, - "MessageType_EthereumSignMessage": 64, - "MessageType_EthereumVerifyMessage": 65, - "MessageType_EthereumMessageSignature": 66, - "MessageType_NEMGetAddress": 67, - "MessageType_NEMAddress": 68, - "MessageType_NEMSignTx": 69, - "MessageType_NEMSignedTx": 70, - "MessageType_NEMDecryptMessage": 75, - "MessageType_NEMDecryptedMessage": 76, - "MessageType_LiskGetAddress": 114, - "MessageType_LiskAddress": 115, - "MessageType_LiskSignTx": 116, - "MessageType_LiskSignedTx": 117, - "MessageType_LiskSignMessage": 118, - "MessageType_LiskMessageSignature": 119, - "MessageType_LiskVerifyMessage": 120, - "MessageType_LiskGetPublicKey": 121, - "MessageType_LiskPublicKey": 122, - "MessageType_TezosGetAddress": 150, - "MessageType_TezosAddress": 151, - "MessageType_TezosSignTx": 152, - "MessageType_TezosSignedTx": 153, - "MessageType_TezosGetPublicKey": 154, - "MessageType_TezosPublicKey": 155, - "MessageType_StellarSignTx": 202, - "MessageType_StellarTxOpRequest": 203, - "MessageType_StellarGetAddress": 207, - "MessageType_StellarAddress": 208, - "MessageType_StellarCreateAccountOp": 210, - "MessageType_StellarPaymentOp": 211, - "MessageType_StellarPathPaymentOp": 212, - "MessageType_StellarManageOfferOp": 213, - "MessageType_StellarCreatePassiveOfferOp": 214, - "MessageType_StellarSetOptionsOp": 215, - "MessageType_StellarChangeTrustOp": 216, - "MessageType_StellarAllowTrustOp": 217, - "MessageType_StellarAccountMergeOp": 218, - "MessageType_StellarManageDataOp": 220, - "MessageType_StellarBumpSequenceOp": 221, - "MessageType_StellarSignedTx": 230, - "MessageType_TronGetAddress": 250, - "MessageType_TronAddress": 251, - "MessageType_TronSignTx": 252, - "MessageType_TronSignedTx": 253, - "MessageType_CardanoSignTx": 303, - "MessageType_CardanoTxRequest": 304, - "MessageType_CardanoGetPublicKey": 305, - "MessageType_CardanoPublicKey": 306, - "MessageType_CardanoGetAddress": 307, - "MessageType_CardanoAddress": 308, - "MessageType_CardanoTxAck": 309, - "MessageType_CardanoSignedTx": 310, - "MessageType_OntologyGetAddress": 350, - "MessageType_OntologyAddress": 351, - "MessageType_OntologyGetPublicKey": 352, - "MessageType_OntologyPublicKey": 353, - "MessageType_OntologySignTransfer": 354, - "MessageType_OntologySignedTransfer": 355, - "MessageType_OntologySignWithdrawOng": 356, - "MessageType_OntologySignedWithdrawOng": 357, - "MessageType_OntologySignOntIdRegister": 358, - "MessageType_OntologySignedOntIdRegister": 359, - "MessageType_OntologySignOntIdAddAttributes": 360, - "MessageType_OntologySignedOntIdAddAttributes": 361, - "MessageType_RippleGetAddress": 400, - "MessageType_RippleAddress": 401, - "MessageType_RippleSignTx": 402, - "MessageType_RippleSignedTx": 403, - "MessageType_MoneroTransactionInitRequest": 501, - "MessageType_MoneroTransactionInitAck": 502, - "MessageType_MoneroTransactionSetInputRequest": 503, - "MessageType_MoneroTransactionSetInputAck": 504, - "MessageType_MoneroTransactionInputsPermutationRequest": 505, - "MessageType_MoneroTransactionInputsPermutationAck": 506, - "MessageType_MoneroTransactionInputViniRequest": 507, - "MessageType_MoneroTransactionInputViniAck": 508, - "MessageType_MoneroTransactionAllInputsSetRequest": 509, - "MessageType_MoneroTransactionAllInputsSetAck": 510, - "MessageType_MoneroTransactionSetOutputRequest": 511, - "MessageType_MoneroTransactionSetOutputAck": 512, - "MessageType_MoneroTransactionAllOutSetRequest": 513, - "MessageType_MoneroTransactionAllOutSetAck": 514, - "MessageType_MoneroTransactionSignInputRequest": 515, - "MessageType_MoneroTransactionSignInputAck": 516, - "MessageType_MoneroTransactionFinalRequest": 517, - "MessageType_MoneroTransactionFinalAck": 518, - "MessageType_MoneroKeyImageExportInitRequest": 530, - "MessageType_MoneroKeyImageExportInitAck": 531, - "MessageType_MoneroKeyImageSyncStepRequest": 532, - "MessageType_MoneroKeyImageSyncStepAck": 533, - "MessageType_MoneroKeyImageSyncFinalRequest": 534, - "MessageType_MoneroKeyImageSyncFinalAck": 535, - "MessageType_MoneroGetAddress": 540, - "MessageType_MoneroAddress": 541, - "MessageType_MoneroGetWatchKey": 542, - "MessageType_MoneroWatchKey": 543, - "MessageType_DebugMoneroDiagRequest": 546, - "MessageType_DebugMoneroDiagAck": 547, - "MessageType_MoneroGetTxKeyRequest": 550, - "MessageType_MoneroGetTxKeyAck": 551, - "MessageType_MoneroLiveRefreshStartRequest": 552, - "MessageType_MoneroLiveRefreshStartAck": 553, - "MessageType_MoneroLiveRefreshStepRequest": 554, - "MessageType_MoneroLiveRefreshStepAck": 555, - "MessageType_MoneroLiveRefreshFinalRequest": 556, - "MessageType_MoneroLiveRefreshFinalAck": 557, - "MessageType_EosGetPublicKey": 600, - "MessageType_EosPublicKey": 601, - "MessageType_EosSignTx": 602, - "MessageType_EosTxActionRequest": 603, - "MessageType_EosTxActionAck": 604, - "MessageType_EosSignedTx": 605, - "MessageType_BinanceGetAddress": 700, - "MessageType_BinanceAddress": 701, - "MessageType_BinanceGetPublicKey": 702, - "MessageType_BinancePublicKey": 703, - "MessageType_BinanceSignTx": 704, - "MessageType_BinanceTxRequest": 705, - "MessageType_BinanceTransferMsg": 706, - "MessageType_BinanceOrderMsg": 707, - "MessageType_BinanceCancelMsg": 708, - "MessageType_BinanceSignedTx": 709, -} +// Enum value maps for MessageType. +var ( + MessageType_name = map[int32]string{ + 0: "MessageType_Initialize", + 1: "MessageType_Ping", + 2: "MessageType_Success", + 3: "MessageType_Failure", + 4: "MessageType_ChangePin", + 5: "MessageType_WipeDevice", + 9: "MessageType_GetEntropy", + 10: "MessageType_Entropy", + 13: "MessageType_LoadDevice", + 14: "MessageType_ResetDevice", + 17: "MessageType_Features", + 18: "MessageType_PinMatrixRequest", + 19: "MessageType_PinMatrixAck", + 20: "MessageType_Cancel", + 24: "MessageType_ClearSession", + 25: "MessageType_ApplySettings", + 26: "MessageType_ButtonRequest", + 27: "MessageType_ButtonAck", + 28: "MessageType_ApplyFlags", + 34: "MessageType_BackupDevice", + 35: "MessageType_EntropyRequest", + 36: "MessageType_EntropyAck", + 41: "MessageType_PassphraseRequest", + 42: "MessageType_PassphraseAck", + 77: "MessageType_PassphraseStateRequest", + 78: "MessageType_PassphraseStateAck", + 45: "MessageType_RecoveryDevice", + 46: "MessageType_WordRequest", + 47: "MessageType_WordAck", + 55: "MessageType_GetFeatures", + 63: "MessageType_SetU2FCounter", + 6: "MessageType_FirmwareErase", + 7: "MessageType_FirmwareUpload", + 8: "MessageType_FirmwareRequest", + 32: "MessageType_SelfTest", + 11: "MessageType_GetPublicKey", + 12: "MessageType_PublicKey", + 15: "MessageType_SignTx", + 21: "MessageType_TxRequest", + 22: "MessageType_TxAck", + 29: "MessageType_GetAddress", + 30: "MessageType_Address", + 38: "MessageType_SignMessage", + 39: "MessageType_VerifyMessage", + 40: "MessageType_MessageSignature", + 23: "MessageType_CipherKeyValue", + 48: "MessageType_CipheredKeyValue", + 53: "MessageType_SignIdentity", + 54: "MessageType_SignedIdentity", + 61: "MessageType_GetECDHSessionKey", + 62: "MessageType_ECDHSessionKey", + 71: "MessageType_CosiCommit", + 72: "MessageType_CosiCommitment", + 73: "MessageType_CosiSign", + 74: "MessageType_CosiSignature", + 100: "MessageType_DebugLinkDecision", + 101: "MessageType_DebugLinkGetState", + 102: "MessageType_DebugLinkState", + 103: "MessageType_DebugLinkStop", + 104: "MessageType_DebugLinkLog", + 110: "MessageType_DebugLinkMemoryRead", + 111: "MessageType_DebugLinkMemory", + 112: "MessageType_DebugLinkMemoryWrite", + 113: "MessageType_DebugLinkFlashErase", + 450: "MessageType_EthereumGetPublicKey", + 451: "MessageType_EthereumPublicKey", + 56: "MessageType_EthereumGetAddress", + 57: "MessageType_EthereumAddress", + 58: "MessageType_EthereumSignTx", + 59: "MessageType_EthereumTxRequest", + 60: "MessageType_EthereumTxAck", + 64: "MessageType_EthereumSignMessage", + 65: "MessageType_EthereumVerifyMessage", + 66: "MessageType_EthereumMessageSignature", + 67: "MessageType_NEMGetAddress", + 68: "MessageType_NEMAddress", + 69: "MessageType_NEMSignTx", + 70: "MessageType_NEMSignedTx", + 75: "MessageType_NEMDecryptMessage", + 76: "MessageType_NEMDecryptedMessage", + 114: "MessageType_LiskGetAddress", + 115: "MessageType_LiskAddress", + 116: "MessageType_LiskSignTx", + 117: "MessageType_LiskSignedTx", + 118: "MessageType_LiskSignMessage", + 119: "MessageType_LiskMessageSignature", + 120: "MessageType_LiskVerifyMessage", + 121: "MessageType_LiskGetPublicKey", + 122: "MessageType_LiskPublicKey", + 150: "MessageType_TezosGetAddress", + 151: "MessageType_TezosAddress", + 152: "MessageType_TezosSignTx", + 153: "MessageType_TezosSignedTx", + 154: "MessageType_TezosGetPublicKey", + 155: "MessageType_TezosPublicKey", + 202: "MessageType_StellarSignTx", + 203: "MessageType_StellarTxOpRequest", + 207: "MessageType_StellarGetAddress", + 208: "MessageType_StellarAddress", + 210: "MessageType_StellarCreateAccountOp", + 211: "MessageType_StellarPaymentOp", + 212: "MessageType_StellarPathPaymentOp", + 213: "MessageType_StellarManageOfferOp", + 214: "MessageType_StellarCreatePassiveOfferOp", + 215: "MessageType_StellarSetOptionsOp", + 216: "MessageType_StellarChangeTrustOp", + 217: "MessageType_StellarAllowTrustOp", + 218: "MessageType_StellarAccountMergeOp", + 220: "MessageType_StellarManageDataOp", + 221: "MessageType_StellarBumpSequenceOp", + 230: "MessageType_StellarSignedTx", + 250: "MessageType_TronGetAddress", + 251: "MessageType_TronAddress", + 252: "MessageType_TronSignTx", + 253: "MessageType_TronSignedTx", + 303: "MessageType_CardanoSignTx", + 304: "MessageType_CardanoTxRequest", + 305: "MessageType_CardanoGetPublicKey", + 306: "MessageType_CardanoPublicKey", + 307: "MessageType_CardanoGetAddress", + 308: "MessageType_CardanoAddress", + 309: "MessageType_CardanoTxAck", + 310: "MessageType_CardanoSignedTx", + 350: "MessageType_OntologyGetAddress", + 351: "MessageType_OntologyAddress", + 352: "MessageType_OntologyGetPublicKey", + 353: "MessageType_OntologyPublicKey", + 354: "MessageType_OntologySignTransfer", + 355: "MessageType_OntologySignedTransfer", + 356: "MessageType_OntologySignWithdrawOng", + 357: "MessageType_OntologySignedWithdrawOng", + 358: "MessageType_OntologySignOntIdRegister", + 359: "MessageType_OntologySignedOntIdRegister", + 360: "MessageType_OntologySignOntIdAddAttributes", + 361: "MessageType_OntologySignedOntIdAddAttributes", + 400: "MessageType_RippleGetAddress", + 401: "MessageType_RippleAddress", + 402: "MessageType_RippleSignTx", + 403: "MessageType_RippleSignedTx", + 501: "MessageType_MoneroTransactionInitRequest", + 502: "MessageType_MoneroTransactionInitAck", + 503: "MessageType_MoneroTransactionSetInputRequest", + 504: "MessageType_MoneroTransactionSetInputAck", + 505: "MessageType_MoneroTransactionInputsPermutationRequest", + 506: "MessageType_MoneroTransactionInputsPermutationAck", + 507: "MessageType_MoneroTransactionInputViniRequest", + 508: "MessageType_MoneroTransactionInputViniAck", + 509: "MessageType_MoneroTransactionAllInputsSetRequest", + 510: "MessageType_MoneroTransactionAllInputsSetAck", + 511: "MessageType_MoneroTransactionSetOutputRequest", + 512: "MessageType_MoneroTransactionSetOutputAck", + 513: "MessageType_MoneroTransactionAllOutSetRequest", + 514: "MessageType_MoneroTransactionAllOutSetAck", + 515: "MessageType_MoneroTransactionSignInputRequest", + 516: "MessageType_MoneroTransactionSignInputAck", + 517: "MessageType_MoneroTransactionFinalRequest", + 518: "MessageType_MoneroTransactionFinalAck", + 530: "MessageType_MoneroKeyImageExportInitRequest", + 531: "MessageType_MoneroKeyImageExportInitAck", + 532: "MessageType_MoneroKeyImageSyncStepRequest", + 533: "MessageType_MoneroKeyImageSyncStepAck", + 534: "MessageType_MoneroKeyImageSyncFinalRequest", + 535: "MessageType_MoneroKeyImageSyncFinalAck", + 540: "MessageType_MoneroGetAddress", + 541: "MessageType_MoneroAddress", + 542: "MessageType_MoneroGetWatchKey", + 543: "MessageType_MoneroWatchKey", + 546: "MessageType_DebugMoneroDiagRequest", + 547: "MessageType_DebugMoneroDiagAck", + 550: "MessageType_MoneroGetTxKeyRequest", + 551: "MessageType_MoneroGetTxKeyAck", + 552: "MessageType_MoneroLiveRefreshStartRequest", + 553: "MessageType_MoneroLiveRefreshStartAck", + 554: "MessageType_MoneroLiveRefreshStepRequest", + 555: "MessageType_MoneroLiveRefreshStepAck", + 556: "MessageType_MoneroLiveRefreshFinalRequest", + 557: "MessageType_MoneroLiveRefreshFinalAck", + 600: "MessageType_EosGetPublicKey", + 601: "MessageType_EosPublicKey", + 602: "MessageType_EosSignTx", + 603: "MessageType_EosTxActionRequest", + 604: "MessageType_EosTxActionAck", + 605: "MessageType_EosSignedTx", + 700: "MessageType_BinanceGetAddress", + 701: "MessageType_BinanceAddress", + 702: "MessageType_BinanceGetPublicKey", + 703: "MessageType_BinancePublicKey", + 704: "MessageType_BinanceSignTx", + 705: "MessageType_BinanceTxRequest", + 706: "MessageType_BinanceTransferMsg", + 707: "MessageType_BinanceOrderMsg", + 708: "MessageType_BinanceCancelMsg", + 709: "MessageType_BinanceSignedTx", + } + MessageType_value = map[string]int32{ + "MessageType_Initialize": 0, + "MessageType_Ping": 1, + "MessageType_Success": 2, + "MessageType_Failure": 3, + "MessageType_ChangePin": 4, + "MessageType_WipeDevice": 5, + "MessageType_GetEntropy": 9, + "MessageType_Entropy": 10, + "MessageType_LoadDevice": 13, + "MessageType_ResetDevice": 14, + "MessageType_Features": 17, + "MessageType_PinMatrixRequest": 18, + "MessageType_PinMatrixAck": 19, + "MessageType_Cancel": 20, + "MessageType_ClearSession": 24, + "MessageType_ApplySettings": 25, + "MessageType_ButtonRequest": 26, + "MessageType_ButtonAck": 27, + "MessageType_ApplyFlags": 28, + "MessageType_BackupDevice": 34, + "MessageType_EntropyRequest": 35, + "MessageType_EntropyAck": 36, + "MessageType_PassphraseRequest": 41, + "MessageType_PassphraseAck": 42, + "MessageType_PassphraseStateRequest": 77, + "MessageType_PassphraseStateAck": 78, + "MessageType_RecoveryDevice": 45, + "MessageType_WordRequest": 46, + "MessageType_WordAck": 47, + "MessageType_GetFeatures": 55, + "MessageType_SetU2FCounter": 63, + "MessageType_FirmwareErase": 6, + "MessageType_FirmwareUpload": 7, + "MessageType_FirmwareRequest": 8, + "MessageType_SelfTest": 32, + "MessageType_GetPublicKey": 11, + "MessageType_PublicKey": 12, + "MessageType_SignTx": 15, + "MessageType_TxRequest": 21, + "MessageType_TxAck": 22, + "MessageType_GetAddress": 29, + "MessageType_Address": 30, + "MessageType_SignMessage": 38, + "MessageType_VerifyMessage": 39, + "MessageType_MessageSignature": 40, + "MessageType_CipherKeyValue": 23, + "MessageType_CipheredKeyValue": 48, + "MessageType_SignIdentity": 53, + "MessageType_SignedIdentity": 54, + "MessageType_GetECDHSessionKey": 61, + "MessageType_ECDHSessionKey": 62, + "MessageType_CosiCommit": 71, + "MessageType_CosiCommitment": 72, + "MessageType_CosiSign": 73, + "MessageType_CosiSignature": 74, + "MessageType_DebugLinkDecision": 100, + "MessageType_DebugLinkGetState": 101, + "MessageType_DebugLinkState": 102, + "MessageType_DebugLinkStop": 103, + "MessageType_DebugLinkLog": 104, + "MessageType_DebugLinkMemoryRead": 110, + "MessageType_DebugLinkMemory": 111, + "MessageType_DebugLinkMemoryWrite": 112, + "MessageType_DebugLinkFlashErase": 113, + "MessageType_EthereumGetPublicKey": 450, + "MessageType_EthereumPublicKey": 451, + "MessageType_EthereumGetAddress": 56, + "MessageType_EthereumAddress": 57, + "MessageType_EthereumSignTx": 58, + "MessageType_EthereumTxRequest": 59, + "MessageType_EthereumTxAck": 60, + "MessageType_EthereumSignMessage": 64, + "MessageType_EthereumVerifyMessage": 65, + "MessageType_EthereumMessageSignature": 66, + "MessageType_NEMGetAddress": 67, + "MessageType_NEMAddress": 68, + "MessageType_NEMSignTx": 69, + "MessageType_NEMSignedTx": 70, + "MessageType_NEMDecryptMessage": 75, + "MessageType_NEMDecryptedMessage": 76, + "MessageType_LiskGetAddress": 114, + "MessageType_LiskAddress": 115, + "MessageType_LiskSignTx": 116, + "MessageType_LiskSignedTx": 117, + "MessageType_LiskSignMessage": 118, + "MessageType_LiskMessageSignature": 119, + "MessageType_LiskVerifyMessage": 120, + "MessageType_LiskGetPublicKey": 121, + "MessageType_LiskPublicKey": 122, + "MessageType_TezosGetAddress": 150, + "MessageType_TezosAddress": 151, + "MessageType_TezosSignTx": 152, + "MessageType_TezosSignedTx": 153, + "MessageType_TezosGetPublicKey": 154, + "MessageType_TezosPublicKey": 155, + "MessageType_StellarSignTx": 202, + "MessageType_StellarTxOpRequest": 203, + "MessageType_StellarGetAddress": 207, + "MessageType_StellarAddress": 208, + "MessageType_StellarCreateAccountOp": 210, + "MessageType_StellarPaymentOp": 211, + "MessageType_StellarPathPaymentOp": 212, + "MessageType_StellarManageOfferOp": 213, + "MessageType_StellarCreatePassiveOfferOp": 214, + "MessageType_StellarSetOptionsOp": 215, + "MessageType_StellarChangeTrustOp": 216, + "MessageType_StellarAllowTrustOp": 217, + "MessageType_StellarAccountMergeOp": 218, + "MessageType_StellarManageDataOp": 220, + "MessageType_StellarBumpSequenceOp": 221, + "MessageType_StellarSignedTx": 230, + "MessageType_TronGetAddress": 250, + "MessageType_TronAddress": 251, + "MessageType_TronSignTx": 252, + "MessageType_TronSignedTx": 253, + "MessageType_CardanoSignTx": 303, + "MessageType_CardanoTxRequest": 304, + "MessageType_CardanoGetPublicKey": 305, + "MessageType_CardanoPublicKey": 306, + "MessageType_CardanoGetAddress": 307, + "MessageType_CardanoAddress": 308, + "MessageType_CardanoTxAck": 309, + "MessageType_CardanoSignedTx": 310, + "MessageType_OntologyGetAddress": 350, + "MessageType_OntologyAddress": 351, + "MessageType_OntologyGetPublicKey": 352, + "MessageType_OntologyPublicKey": 353, + "MessageType_OntologySignTransfer": 354, + "MessageType_OntologySignedTransfer": 355, + "MessageType_OntologySignWithdrawOng": 356, + "MessageType_OntologySignedWithdrawOng": 357, + "MessageType_OntologySignOntIdRegister": 358, + "MessageType_OntologySignedOntIdRegister": 359, + "MessageType_OntologySignOntIdAddAttributes": 360, + "MessageType_OntologySignedOntIdAddAttributes": 361, + "MessageType_RippleGetAddress": 400, + "MessageType_RippleAddress": 401, + "MessageType_RippleSignTx": 402, + "MessageType_RippleSignedTx": 403, + "MessageType_MoneroTransactionInitRequest": 501, + "MessageType_MoneroTransactionInitAck": 502, + "MessageType_MoneroTransactionSetInputRequest": 503, + "MessageType_MoneroTransactionSetInputAck": 504, + "MessageType_MoneroTransactionInputsPermutationRequest": 505, + "MessageType_MoneroTransactionInputsPermutationAck": 506, + "MessageType_MoneroTransactionInputViniRequest": 507, + "MessageType_MoneroTransactionInputViniAck": 508, + "MessageType_MoneroTransactionAllInputsSetRequest": 509, + "MessageType_MoneroTransactionAllInputsSetAck": 510, + "MessageType_MoneroTransactionSetOutputRequest": 511, + "MessageType_MoneroTransactionSetOutputAck": 512, + "MessageType_MoneroTransactionAllOutSetRequest": 513, + "MessageType_MoneroTransactionAllOutSetAck": 514, + "MessageType_MoneroTransactionSignInputRequest": 515, + "MessageType_MoneroTransactionSignInputAck": 516, + "MessageType_MoneroTransactionFinalRequest": 517, + "MessageType_MoneroTransactionFinalAck": 518, + "MessageType_MoneroKeyImageExportInitRequest": 530, + "MessageType_MoneroKeyImageExportInitAck": 531, + "MessageType_MoneroKeyImageSyncStepRequest": 532, + "MessageType_MoneroKeyImageSyncStepAck": 533, + "MessageType_MoneroKeyImageSyncFinalRequest": 534, + "MessageType_MoneroKeyImageSyncFinalAck": 535, + "MessageType_MoneroGetAddress": 540, + "MessageType_MoneroAddress": 541, + "MessageType_MoneroGetWatchKey": 542, + "MessageType_MoneroWatchKey": 543, + "MessageType_DebugMoneroDiagRequest": 546, + "MessageType_DebugMoneroDiagAck": 547, + "MessageType_MoneroGetTxKeyRequest": 550, + "MessageType_MoneroGetTxKeyAck": 551, + "MessageType_MoneroLiveRefreshStartRequest": 552, + "MessageType_MoneroLiveRefreshStartAck": 553, + "MessageType_MoneroLiveRefreshStepRequest": 554, + "MessageType_MoneroLiveRefreshStepAck": 555, + "MessageType_MoneroLiveRefreshFinalRequest": 556, + "MessageType_MoneroLiveRefreshFinalAck": 557, + "MessageType_EosGetPublicKey": 600, + "MessageType_EosPublicKey": 601, + "MessageType_EosSignTx": 602, + "MessageType_EosTxActionRequest": 603, + "MessageType_EosTxActionAck": 604, + "MessageType_EosSignedTx": 605, + "MessageType_BinanceGetAddress": 700, + "MessageType_BinanceAddress": 701, + "MessageType_BinanceGetPublicKey": 702, + "MessageType_BinancePublicKey": 703, + "MessageType_BinanceSignTx": 704, + "MessageType_BinanceTxRequest": 705, + "MessageType_BinanceTransferMsg": 706, + "MessageType_BinanceOrderMsg": 707, + "MessageType_BinanceCancelMsg": 708, + "MessageType_BinanceSignedTx": 709, + } +) func (x MessageType) Enum() *MessageType { p := new(MessageType) @@ -640,250 +645,722 @@ func (x MessageType) Enum() *MessageType { } func (x MessageType) String() string { - return proto.EnumName(MessageType_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (x *MessageType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(MessageType_value, data, "MessageType") +func (MessageType) Descriptor() protoreflect.EnumDescriptor { + return file_messages_proto_enumTypes[0].Descriptor() +} + +func (MessageType) Type() protoreflect.EnumType { + return &file_messages_proto_enumTypes[0] +} + +func (x MessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *MessageType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = MessageType(value) + *x = MessageType(num) return nil } +// Deprecated: Use MessageType.Descriptor instead. func (MessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_4dc296cbfe5ffcd5, []int{0} + return file_messages_proto_rawDescGZIP(), []int{0} } -var E_WireIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50002, - Name: "hw.trezor.messages.wire_in", - Tag: "varint,50002,opt,name=wire_in", - Filename: "messages.proto", +var file_messages_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50002, + Name: "hw.trezor.messages.wire_in", + Tag: "varint,50002,opt,name=wire_in", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50003, + Name: "hw.trezor.messages.wire_out", + Tag: "varint,50003,opt,name=wire_out", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50004, + Name: "hw.trezor.messages.wire_debug_in", + Tag: "varint,50004,opt,name=wire_debug_in", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50005, + Name: "hw.trezor.messages.wire_debug_out", + Tag: "varint,50005,opt,name=wire_debug_out", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50006, + Name: "hw.trezor.messages.wire_tiny", + Tag: "varint,50006,opt,name=wire_tiny", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50007, + Name: "hw.trezor.messages.wire_bootloader", + Tag: "varint,50007,opt,name=wire_bootloader", + Filename: "messages.proto", + }, + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 50008, + Name: "hw.trezor.messages.wire_no_fsm", + Tag: "varint,50008,opt,name=wire_no_fsm", + Filename: "messages.proto", + }, } -var E_WireOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50003, - Name: "hw.trezor.messages.wire_out", - Tag: "varint,50003,opt,name=wire_out", - Filename: "messages.proto", +// Extension fields to descriptorpb.EnumValueOptions. +var ( + // optional bool wire_in = 50002; + E_WireIn = &file_messages_proto_extTypes[0] // message can be transmitted via wire from PC to TREZOR + // optional bool wire_out = 50003; + E_WireOut = &file_messages_proto_extTypes[1] // message can be transmitted via wire from TREZOR to PC + // optional bool wire_debug_in = 50004; + E_WireDebugIn = &file_messages_proto_extTypes[2] // message can be transmitted via debug wire from PC to TREZOR + // optional bool wire_debug_out = 50005; + E_WireDebugOut = &file_messages_proto_extTypes[3] // message can be transmitted via debug wire from TREZOR to PC + // optional bool wire_tiny = 50006; + E_WireTiny = &file_messages_proto_extTypes[4] // message is handled by TREZOR when the USB stack is in tiny mode + // optional bool wire_bootloader = 50007; + E_WireBootloader = &file_messages_proto_extTypes[5] // message is only handled by TREZOR Bootloader + // optional bool wire_no_fsm = 50008; + E_WireNoFsm = &file_messages_proto_extTypes[6] // message is not handled by TREZOR unless the USB stack is in tiny mode +) + +var File_messages_proto protoreflect.FileDescriptor + +var file_messages_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x12, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x73, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0xb9, 0x3f, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x10, 0x00, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x1a, 0x0a, 0x10, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x67, + 0x10, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, + 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x10, 0x03, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x69, 0x6e, 0x10, + 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x10, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x10, 0x09, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x10, 0x0a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x6f, 0x61, 0x64, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x10, 0x0d, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x65, 0x73, 0x65, + 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x0e, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x1e, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x10, 0x11, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, + 0x26, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, + 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, + 0x12, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x41, 0x63, 0x6b, 0x10, 0x13, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, + 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x10, 0x14, 0x1a, 0x08, 0x90, 0xb5, 0x18, + 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x10, 0x18, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x10, 0x19, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, + 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x1a, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0x1b, 0x1a, 0x0c, + 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x10, 0x1c, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, + 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x22, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x10, 0x23, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x41, + 0x63, 0x6b, 0x10, 0x24, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, + 0x72, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x29, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x41, 0x63, 0x6b, + 0x10, 0x2a, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, + 0x12, 0x2c, 0x0a, 0x22, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x4d, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, + 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x61, + 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41, 0x63, 0x6b, + 0x10, 0x4e, 0x1a, 0x0c, 0x90, 0xb5, 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, + 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x2d, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x10, 0x2e, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x57, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x6b, + 0x10, 0x2f, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x10, 0x37, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, 0x74, 0x55, 0x32, + 0x46, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x10, 0x3f, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, + 0x12, 0x27, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x45, 0x72, 0x61, 0x73, 0x65, 0x10, 0x06, 0x1a, + 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1a, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, + 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x10, 0x07, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0x08, 0x1a, 0x08, 0x98, 0xb5, 0x18, 0x01, 0xb8, 0xb5, 0x18, 0x01, 0x12, 0x22, + 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x65, + 0x6c, 0x66, 0x54, 0x65, 0x73, 0x74, 0x10, 0x20, 0x1a, 0x08, 0x90, 0xb5, 0x18, 0x01, 0xb8, 0xb5, + 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x0b, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, + 0x0c, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1c, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x0f, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x15, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1b, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x78, 0x41, 0x63, 0x6b, 0x10, 0x16, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x1d, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x1d, 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x1e, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, + 0x26, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x10, 0x27, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x28, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x10, 0x17, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x64, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x10, 0x30, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x10, 0x35, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x10, 0x36, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x47, 0x65, 0x74, 0x45, + 0x43, 0x44, 0x48, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0x3d, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x4b, 0x65, 0x79, 0x10, 0x3e, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x47, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, + 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, + 0x69, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x48, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x1e, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x10, 0x49, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x43, 0x6f, 0x73, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x10, 0x4a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2f, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, + 0x6b, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x64, 0x1a, 0x0c, 0xa0, 0xb5, 0x18, + 0x01, 0xb0, 0xb5, 0x18, 0x01, 0xc0, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x1d, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, + 0x6e, 0x6b, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x65, 0x1a, 0x08, 0xa0, 0xb5, + 0x18, 0x01, 0xb0, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x10, 0x66, 0x1a, 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x6f, 0x70, 0x10, 0x67, 0x1a, 0x04, 0xa0, 0xb5, 0x18, + 0x01, 0x12, 0x22, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4c, 0x6f, 0x67, 0x10, 0x68, 0x1a, + 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x10, 0x6e, 0x1a, 0x04, 0xa0, 0xb5, 0x18, 0x01, + 0x12, 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x10, + 0x6f, 0x1a, 0x04, 0xa8, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, + 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x57, 0x72, 0x69, 0x74, 0x65, 0x10, 0x70, 0x1a, 0x04, 0xa0, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, 0x4c, 0x69, 0x6e, 0x6b, 0x46, 0x6c, 0x61, 0x73, + 0x68, 0x45, 0x72, 0x61, 0x73, 0x65, 0x10, 0x71, 0x1a, 0x04, 0xa0, 0xb5, 0x18, 0x01, 0x12, 0x2b, + 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x10, 0xc2, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xc3, 0x03, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x47, 0x65, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x38, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x39, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x53, 0x69, + 0x67, 0x6e, 0x54, 0x78, 0x10, 0x3a, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x3b, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x10, 0x3c, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x40, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x41, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x2e, 0x0a, 0x24, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x42, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, + 0x43, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0x44, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x1f, 0x0a, 0x15, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x53, 0x69, 0x67, 0x6e, + 0x54, 0x78, 0x10, 0x45, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x46, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, + 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, + 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x4b, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x45, 0x4d, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x4c, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, + 0x72, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x10, 0x73, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x20, 0x0a, 0x16, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x53, 0x69, + 0x67, 0x6e, 0x54, 0x78, 0x10, 0x74, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x75, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x25, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4c, 0x69, 0x73, 0x6b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, + 0x76, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x77, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x10, 0x78, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, + 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x79, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4c, 0x69, 0x73, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x10, 0x7a, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x47, 0x65, + 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x96, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, + 0x01, 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x97, 0x01, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x54, + 0x78, 0x10, 0x98, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x53, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0x99, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x10, 0x9a, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x65, 0x7a, 0x6f, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x9b, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xca, + 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x54, 0x78, + 0x4f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xcb, 0x01, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x10, 0xcf, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, + 0x6c, 0x61, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xd0, 0x01, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4f, 0x70, 0x10, 0xd2, 0x01, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x4f, 0x70, 0x10, 0xd3, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, + 0x61, 0x72, 0x50, 0x61, 0x74, 0x68, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x10, + 0xd4, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x4f, 0x70, 0x10, 0xd5, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x4f, 0x66, 0x66, 0x65, 0x72, 0x4f, 0x70, + 0x10, 0xd6, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, + 0x53, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x70, 0x10, 0xd7, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x54, 0x72, 0x75, 0x73, 0x74, 0x4f, 0x70, 0x10, 0xd8, 0x01, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x4f, 0x70, 0x10, 0xd9, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2c, + 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, + 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x4f, 0x70, 0x10, 0xda, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, + 0x6c, 0x61, 0x72, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4f, 0x70, 0x10, + 0xdc, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2c, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x42, + 0x75, 0x6d, 0x70, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x10, 0xdd, 0x01, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x53, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x72, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xe6, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x25, + 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, + 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xfa, 0x01, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x10, 0xfb, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x21, 0x0a, 0x16, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, 0x53, 0x69, 0x67, + 0x6e, 0x54, 0x78, 0x10, 0xfc, 0x01, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x54, 0x72, 0x6f, 0x6e, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xfd, 0x01, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xaf, + 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x54, 0x78, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xb0, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x10, 0xb1, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, + 0x61, 0x6e, 0x6f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xb2, 0x02, 0x1a, + 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x47, 0x65, 0x74, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xb3, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, + 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, + 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xb4, 0x02, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, 0x6e, 0x6f, 0x54, 0x78, 0x41, + 0x63, 0x6b, 0x10, 0xb5, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x43, 0x61, 0x72, 0x64, 0x61, + 0x6e, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xb6, 0x02, 0x1a, 0x04, 0x98, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x47, 0x65, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xde, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, + 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, + 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xdf, 0x02, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x47, 0x65, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xe0, 0x02, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x10, 0xe1, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2b, 0x0a, + 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x10, 0xe2, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, + 0x10, 0xe3, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2e, 0x0a, 0x23, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x69, 0x67, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x4f, 0x6e, 0x67, + 0x10, 0xe4, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x4f, + 0x6e, 0x67, 0x10, 0xe5, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x6e, 0x74, 0x49, 0x64, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x10, 0xe6, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, + 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x6e, 0x74, 0x49, 0x64, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x10, 0xe7, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x35, 0x0a, 0x2a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x6e, 0x74, + 0x49, 0x64, 0x41, 0x64, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x10, + 0xe8, 0x02, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x37, 0x0a, 0x2c, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4f, 0x6e, 0x74, 0x6f, 0x6c, 0x6f, 0x67, 0x79, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x6e, 0x74, 0x49, 0x64, 0x41, 0x64, 0x64, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x10, 0xe9, 0x02, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0x90, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x91, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x23, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x92, 0x03, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x52, 0x69, 0x70, 0x70, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x54, 0x78, 0x10, 0x93, 0x03, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x69, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xf5, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x2f, 0x0a, 0x24, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x69, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xf6, 0x03, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x37, 0x0a, 0x2c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xf7, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xf8, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x40, 0x0a, 0x35, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xf9, 0x03, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x3c, 0x0a, 0x31, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x50, 0x65, 0x72, 0x6d, 0x75, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0xfa, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x56, 0x69, 0x6e, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x10, 0xfb, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x56, 0x69, 0x6e, 0x69, 0x41, 0x63, 0x6b, 0x10, 0xfc, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x3b, 0x0a, 0x30, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x41, 0x6c, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x10, 0xfd, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x37, 0x0a, + 0x2c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, + 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, + 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x53, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xfe, 0x03, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xff, 0x03, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x80, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6c, 0x6c, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x81, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x41, 0x6c, 0x6c, 0x4f, 0x75, 0x74, 0x53, 0x65, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x82, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x38, 0x0a, 0x2d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x83, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x63, 0x6b, 0x10, 0x84, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x10, 0x85, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x41, 0x63, 0x6b, 0x10, 0x86, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x36, + 0x0a, 0x2b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, + 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x92, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x32, 0x0a, 0x27, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x41, 0x63, + 0x6b, 0x10, 0x93, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, + 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x65, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x94, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, + 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, + 0x6e, 0x63, 0x53, 0x74, 0x65, 0x70, 0x41, 0x63, 0x6b, 0x10, 0x95, 0x04, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x12, 0x35, 0x0a, 0x2a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x53, 0x79, 0x6e, 0x63, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x10, 0x96, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x31, 0x0a, 0x26, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4b, + 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x46, 0x69, 0x6e, 0x61, 0x6c, + 0x41, 0x63, 0x6b, 0x10, 0x97, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x9c, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x10, 0x9d, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x47, 0x65, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4b, 0x65, 0x79, 0x10, 0x9e, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x4b, 0x65, 0x79, 0x10, 0x9f, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2d, 0x0a, 0x22, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x44, 0x69, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xa2, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x44, 0x69, 0x61, 0x67, 0x41, 0x63, 0x6b, 0x10, 0xa3, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2c, 0x0a, 0x21, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x47, 0x65, 0x74, 0x54, + 0x78, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xa6, 0x04, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x47, 0x65, 0x74, 0x54, 0x78, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x6b, 0x10, 0xa7, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, + 0x0a, 0x29, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, + 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xa8, 0x04, 0x1a, 0x04, + 0x90, 0xb5, 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x41, 0x63, 0x6b, 0x10, 0xa9, 0x04, + 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x33, 0x0a, 0x28, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x10, 0xaa, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x2f, 0x0a, 0x24, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, + 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x65, 0x70, + 0x41, 0x63, 0x6b, 0x10, 0xab, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x34, 0x0a, 0x29, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, + 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xac, 0x04, 0x1a, 0x04, 0x90, 0xb5, + 0x18, 0x01, 0x12, 0x30, 0x0a, 0x25, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x72, 0x6f, 0x4c, 0x69, 0x76, 0x65, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x6b, 0x10, 0xad, 0x04, 0x1a, 0x04, + 0x98, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x10, 0xd8, 0x04, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x23, 0x0a, 0x18, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xd9, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, + 0x01, 0x12, 0x20, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x45, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xda, 0x04, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x29, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x54, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xdb, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x25, + 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, + 0x73, 0x54, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x10, 0xdc, 0x04, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x22, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x45, 0x6f, 0x73, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, + 0x10, 0xdd, 0x04, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x28, 0x0a, 0x1d, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, + 0x47, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0xbc, 0x05, 0x1a, 0x04, 0x90, + 0xb5, 0x18, 0x01, 0x12, 0x25, 0x0a, 0x1a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x10, 0xbd, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x2a, 0x0a, 0x1f, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xbe, 0x05, + 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0xbf, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, + 0x24, 0x0a, 0x19, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, + 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0xc0, 0x05, 0x1a, + 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xc1, 0x05, 0x1a, 0x04, 0x98, 0xb5, 0x18, 0x01, 0x12, 0x29, + 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, + 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x4d, 0x73, 0x67, + 0x10, 0xc2, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x73, 0x67, 0x10, 0xc3, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, + 0x01, 0x12, 0x27, 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4d, 0x73, + 0x67, 0x10, 0xc4, 0x05, 0x1a, 0x04, 0x90, 0xb5, 0x18, 0x01, 0x12, 0x26, 0x0a, 0x1b, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x42, 0x69, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x54, 0x78, 0x10, 0xc5, 0x05, 0x1a, 0x04, 0x98, 0xb5, + 0x18, 0x01, 0x3a, 0x3c, 0x0a, 0x07, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x69, 0x6e, 0x12, 0x21, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xd2, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x77, 0x69, 0x72, 0x65, 0x49, 0x6e, + 0x3a, 0x3e, 0x0a, 0x08, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xd3, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x69, 0x72, 0x65, 0x4f, 0x75, 0x74, + 0x3a, 0x47, 0x0a, 0x0d, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x69, + 0x6e, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd4, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x69, + 0x72, 0x65, 0x44, 0x65, 0x62, 0x75, 0x67, 0x49, 0x6e, 0x3a, 0x49, 0x0a, 0x0e, 0x77, 0x69, 0x72, + 0x65, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x6f, 0x75, 0x74, 0x12, 0x21, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, + 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd5, + 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x69, 0x72, 0x65, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x4f, 0x75, 0x74, 0x3a, 0x40, 0x0a, 0x09, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x74, 0x69, 0x6e, + 0x79, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd6, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, + 0x72, 0x65, 0x54, 0x69, 0x6e, 0x79, 0x3a, 0x4c, 0x0a, 0x0f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x62, + 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd7, 0x86, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x77, 0x69, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x72, 0x3a, 0x43, 0x0a, 0x0b, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x6e, 0x6f, 0x5f, + 0x66, 0x73, 0x6d, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd8, 0x86, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x77, 0x69, 0x72, 0x65, 0x4e, 0x6f, 0x46, 0x73, 0x6d, 0x42, 0x6f, 0x0a, 0x23, 0x63, 0x6f, 0x6d, + 0x2e, 0x73, 0x61, 0x74, 0x6f, 0x73, 0x68, 0x69, 0x6c, 0x61, 0x62, 0x73, 0x2e, 0x74, 0x72, 0x65, + 0x7a, 0x6f, 0x72, 0x2e, 0x6c, 0x69, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x42, 0x0d, 0x54, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5a, + 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, } -var E_WireDebugIn = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50004, - Name: "hw.trezor.messages.wire_debug_in", - Tag: "varint,50004,opt,name=wire_debug_in", - Filename: "messages.proto", +var ( + file_messages_proto_rawDescOnce sync.Once + file_messages_proto_rawDescData = file_messages_proto_rawDesc +) + +func file_messages_proto_rawDescGZIP() []byte { + file_messages_proto_rawDescOnce.Do(func() { + file_messages_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_proto_rawDescData) + }) + return file_messages_proto_rawDescData } -var E_WireDebugOut = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50005, - Name: "hw.trezor.messages.wire_debug_out", - Tag: "varint,50005,opt,name=wire_debug_out", - Filename: "messages.proto", +var file_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_messages_proto_goTypes = []interface{}{ + (MessageType)(0), // 0: hw.trezor.messages.MessageType + (*descriptorpb.EnumValueOptions)(nil), // 1: google.protobuf.EnumValueOptions +} +var file_messages_proto_depIdxs = []int32{ + 1, // 0: hw.trezor.messages.wire_in:extendee -> google.protobuf.EnumValueOptions + 1, // 1: hw.trezor.messages.wire_out:extendee -> google.protobuf.EnumValueOptions + 1, // 2: hw.trezor.messages.wire_debug_in:extendee -> google.protobuf.EnumValueOptions + 1, // 3: hw.trezor.messages.wire_debug_out:extendee -> google.protobuf.EnumValueOptions + 1, // 4: hw.trezor.messages.wire_tiny:extendee -> google.protobuf.EnumValueOptions + 1, // 5: hw.trezor.messages.wire_bootloader:extendee -> google.protobuf.EnumValueOptions + 1, // 6: hw.trezor.messages.wire_no_fsm:extendee -> google.protobuf.EnumValueOptions + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 0, // [0:7] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -var E_WireTiny = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50006, - Name: "hw.trezor.messages.wire_tiny", - Tag: "varint,50006,opt,name=wire_tiny", - Filename: "messages.proto", -} - -var E_WireBootloader = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50007, - Name: "hw.trezor.messages.wire_bootloader", - Tag: "varint,50007,opt,name=wire_bootloader", - Filename: "messages.proto", -} - -var E_WireNoFsm = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.EnumValueOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 50008, - Name: "hw.trezor.messages.wire_no_fsm", - Tag: "varint,50008,opt,name=wire_no_fsm", - Filename: "messages.proto", -} - -func init() { - proto.RegisterEnum("hw.trezor.messages.MessageType", MessageType_name, MessageType_value) - proto.RegisterExtension(E_WireIn) - proto.RegisterExtension(E_WireOut) - proto.RegisterExtension(E_WireDebugIn) - proto.RegisterExtension(E_WireDebugOut) - proto.RegisterExtension(E_WireTiny) - proto.RegisterExtension(E_WireBootloader) - proto.RegisterExtension(E_WireNoFsm) -} - -func init() { proto.RegisterFile("messages.proto", fileDescriptor_4dc296cbfe5ffcd5) } - -var fileDescriptor_4dc296cbfe5ffcd5 = []byte{ - // 2430 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x9a, 0xd9, 0x73, 0x1c, 0xc5, - 0x1d, 0xc7, 0xb3, 0xab, 0x11, 0x88, 0xf6, 0x41, 0x23, 0xb0, 0x2d, 0xaf, 0x2f, 0xf9, 0xc0, 0x96, - 0x2f, 0xd9, 0x10, 0x0c, 0x44, 0x38, 0x60, 0x69, 0xb5, 0x12, 0x8a, 0xb5, 0x5a, 0x97, 0x76, 0xb1, - 0x1f, 0x5d, 0xa3, 0x9d, 0xd6, 0x6e, 0x97, 0x67, 0x67, 0x86, 0x9e, 0x1e, 0x49, 0xeb, 0xa7, 0x9c, - 0x3c, 0x13, 0x48, 0xc0, 0xb9, 0xa9, 0xa4, 0x2a, 0x21, 0x57, 0x85, 0x1c, 0x4e, 0x25, 0x55, 0x39, - 0x08, 0x24, 0x2f, 0xc9, 0x43, 0x52, 0x9c, 0x86, 0x40, 0xee, 0x90, 0xe4, 0x0f, 0xc8, 0xc5, 0x91, - 0xa4, 0x7a, 0xa6, 0xbb, 0xe7, 0xd8, 0xdf, 0xae, 0x36, 0x6f, 0x58, 0xf3, 0xf9, 0x7d, 0x7f, 0x47, - 0xff, 0xfa, 0x37, 0xdd, 0xb3, 0xa0, 0xcd, 0x2d, 0xe2, 0xfb, 0x66, 0x83, 0xf8, 0xe3, 0x1e, 0x73, - 0xb9, 0x3b, 0x3c, 0xdc, 0x5c, 0x1d, 0xe7, 0x8c, 0x5c, 0x76, 0xd9, 0xb8, 0x7a, 0x52, 0x18, 0x6d, - 0xb8, 0x6e, 0xc3, 0x26, 0x27, 0x42, 0x62, 0x29, 0x58, 0x3e, 0x61, 0x11, 0xbf, 0xce, 0xa8, 0xc7, - 0x5d, 0x16, 0x59, 0x1d, 0xf9, 0xfe, 0x7d, 0x68, 0x43, 0x39, 0xc2, 0x6b, 0x6d, 0x8f, 0x0c, 0x1f, - 0x40, 0x5b, 0x13, 0xff, 0xbc, 0x38, 0xe7, 0x50, 0x4e, 0x4d, 0x9b, 0x5e, 0x26, 0xf8, 0x5d, 0x85, - 0xa1, 0x87, 0xaf, 0x8e, 0xe4, 0x9e, 0xba, 0x3a, 0x92, 0x1b, 0x2e, 0x20, 0x9c, 0xa4, 0xce, 0x51, - 0xa7, 0x81, 0x73, 0x05, 0x43, 0x3c, 0x1f, 0xde, 0x85, 0x6e, 0x4e, 0x3e, 0xab, 0x06, 0xf5, 0x3a, - 0xf1, 0x7d, 0x9c, 0x2f, 0x18, 0x57, 0x80, 0xc7, 0x33, 0x26, 0xb5, 0x03, 0x46, 0xf0, 0x80, 0x7c, - 0xbc, 0x07, 0x6d, 0x49, 0x3e, 0x2e, 0x36, 0x4d, 0xa7, 0x41, 0xce, 0x51, 0x07, 0x1b, 0x52, 0x7e, - 0x34, 0x1d, 0xe0, 0x05, 0xea, 0x91, 0x69, 0xb2, 0x42, 0xeb, 0x04, 0x0f, 0xc2, 0xc4, 0x2c, 0xe1, - 0x25, 0x87, 0x33, 0xd7, 0x6b, 0xe3, 0x1b, 0xe0, 0x10, 0xd5, 0x63, 0x24, 0x63, 0xc8, 0x08, 0xcc, - 0xbb, 0xa6, 0x25, 0x5d, 0x6c, 0x92, 0x02, 0x7b, 0xd1, 0xb6, 0x24, 0xb1, 0x48, 0x7c, 0xc2, 0x25, - 0xb2, 0x59, 0x22, 0xbb, 0xd1, 0x2d, 0xa9, 0x3c, 0x89, 0xc9, 0x03, 0x46, 0x7c, 0x7c, 0x93, 0x74, - 0x72, 0x10, 0xed, 0xcc, 0x94, 0xb0, 0x6c, 0x72, 0x46, 0xd7, 0x16, 0xc9, 0x83, 0x01, 0xf1, 0x39, - 0x1e, 0x96, 0xdc, 0x11, 0x34, 0x02, 0x72, 0x93, 0xf5, 0x4b, 0xf8, 0xe6, 0xc2, 0x46, 0xb5, 0x24, - 0x4f, 0x47, 0x81, 0x0f, 0xa7, 0x8a, 0x67, 0x3a, 0x75, 0x62, 0xe3, 0x5b, 0x12, 0x0b, 0xb7, 0x2f, - 0xad, 0x56, 0xb4, 0x89, 0xc9, 0xaa, 0xc4, 0xf7, 0xa9, 0xeb, 0xe0, 0x11, 0x19, 0xf9, 0x7e, 0xb4, - 0x3d, 0xc9, 0x4c, 0x7a, 0x9e, 0xdd, 0xae, 0x12, 0xce, 0xa9, 0xd3, 0xf0, 0xf1, 0x76, 0x18, 0x9a, - 0x0a, 0x38, 0x77, 0x1d, 0x15, 0x7b, 0x41, 0xc6, 0x7e, 0x28, 0xbd, 0x98, 0x11, 0x24, 0x02, 0xdf, - 0xd1, 0x11, 0xf8, 0xd6, 0x0e, 0x97, 0x33, 0xb6, 0xd9, 0xf0, 0xf1, 0x4e, 0xe9, 0x2f, 0x13, 0xf8, - 0x94, 0x59, 0xbf, 0x14, 0x78, 0xb2, 0xe4, 0xfb, 0x24, 0x73, 0x00, 0x15, 0x80, 0x65, 0x55, 0x41, - 0xed, 0x87, 0x57, 0x57, 0x52, 0x22, 0xaa, 0x03, 0x52, 0xe7, 0x10, 0xda, 0x95, 0x2a, 0xb9, 0xe9, - 0xfb, 0x5e, 0x93, 0x99, 0x3e, 0x51, 0x52, 0x87, 0xa5, 0xd4, 0xd1, 0x74, 0x11, 0x62, 0x50, 0xa8, - 0x1d, 0xc9, 0xe4, 0x78, 0x0c, 0xed, 0x83, 0xe1, 0x2a, 0x37, 0xb9, 0x96, 0x2e, 0x4b, 0xe9, 0x93, - 0x68, 0x77, 0x0f, 0x5a, 0xe8, 0x2f, 0x64, 0xf4, 0x33, 0xd9, 0x2f, 0x92, 0xba, 0xbb, 0x42, 0x58, - 0x5b, 0xd6, 0xe8, 0x38, 0xdc, 0xb9, 0x17, 0x5c, 0x66, 0x29, 0xd7, 0xe3, 0xf0, 0x0e, 0x15, 0x88, - 0xf0, 0x77, 0x02, 0x56, 0x98, 0x25, 0x5c, 0xf7, 0xf6, 0x5d, 0x70, 0x73, 0x54, 0x09, 0x7f, 0xe0, - 0xf6, 0x99, 0xa2, 0x1b, 0x38, 0x9c, 0x30, 0x7c, 0x9f, 0xae, 0x72, 0x0a, 0x9a, 0xa1, 0xac, 0xb5, - 0x6a, 0x32, 0x52, 0x12, 0x49, 0xe2, 0xeb, 0xa2, 0x9e, 0xfd, 0x9e, 0x00, 0xc7, 0xd2, 0x89, 0x29, - 0xf0, 0x01, 0xcf, 0x76, 0x4d, 0x0b, 0x5f, 0x9f, 0x20, 0x0f, 0xa3, 0x1d, 0x10, 0xa9, 0x12, 0x1c, - 0x2a, 0x0c, 0x5d, 0x51, 0xe8, 0xbe, 0xf4, 0xf6, 0xac, 0x12, 0x7b, 0xb9, 0x26, 0x98, 0xd1, 0x84, - 0x5c, 0xa6, 0xe7, 0x66, 0x09, 0x3f, 0x17, 0x2c, 0xd9, 0xb4, 0x7e, 0x96, 0xb4, 0xf1, 0x06, 0x99, - 0x45, 0x66, 0x5e, 0xc5, 0xc0, 0x46, 0x59, 0xcd, 0x9d, 0xe9, 0x3d, 0x59, 0xa5, 0x0d, 0xa7, 0xb6, - 0x86, 0x6f, 0x84, 0xcd, 0x6b, 0x7a, 0xfb, 0x6f, 0x91, 0xe6, 0x3b, 0xd0, 0x4d, 0x69, 0x40, 0x2c, - 0xc5, 0xd6, 0xae, 0x93, 0x6e, 0xd2, 0xb2, 0x98, 0x98, 0xb6, 0xbb, 0xe0, 0x49, 0xa7, 0x1e, 0xef, - 0x96, 0xea, 0x99, 0xb5, 0x14, 0xc1, 0xc9, 0x7f, 0xe3, 0x83, 0xf0, 0x5a, 0x9e, 0x27, 0x8c, 0x2e, - 0xb7, 0x15, 0x74, 0x48, 0x42, 0x99, 0x61, 0x26, 0xff, 0x5b, 0xc8, 0x85, 0x9d, 0x81, 0xc7, 0xa4, - 0xbf, 0x4c, 0x8f, 0x16, 0xa9, 0xd7, 0x24, 0xec, 0x2c, 0x69, 0x9f, 0x37, 0xed, 0x80, 0xe0, 0x6d, - 0xb0, 0x5a, 0x44, 0x11, 0x4b, 0x73, 0x27, 0xa5, 0x5a, 0x66, 0x7d, 0x84, 0xbb, 0x39, 0x8b, 0x38, - 0x9c, 0xf2, 0x36, 0x3e, 0x05, 0xcf, 0x04, 0xc1, 0x10, 0x4b, 0x53, 0x77, 0xea, 0x41, 0xb5, 0x2b, - 0xfb, 0xca, 0x28, 0x4e, 0xdf, 0x2f, 0x07, 0xa3, 0x58, 0xcd, 0xf7, 0x76, 0x19, 0x31, 0x69, 0xea, - 0x5e, 0x78, 0xc4, 0x14, 0x5d, 0x9f, 0x16, 0xdd, 0x56, 0x8b, 0x72, 0x3c, 0x0b, 0xeb, 0xc4, 0x44, - 0x8b, 0x38, 0x1c, 0xdf, 0x2f, 0x75, 0x32, 0xef, 0x10, 0x41, 0x89, 0x04, 0xf0, 0x1c, 0xbc, 0x36, - 0xea, 0x79, 0x54, 0xf3, 0xf7, 0x49, 0x91, 0x13, 0xe9, 0xdc, 0xa6, 0xc9, 0x52, 0xd0, 0x98, 0xa7, - 0xce, 0xa5, 0x69, 0x52, 0xa7, 0xe1, 0xdc, 0xb7, 0x0a, 0x1b, 0x9f, 0x48, 0x0e, 0x92, 0xa3, 0x5d, - 0x0c, 0x66, 0x09, 0x0f, 0x87, 0x0f, 0x26, 0x85, 0x21, 0x65, 0x90, 0x4d, 0x44, 0xc3, 0x11, 0xb9, - 0x5c, 0x30, 0x9e, 0x04, 0x02, 0x4d, 0x50, 0xae, 0x87, 0x1b, 0x05, 0xe3, 0x09, 0x60, 0x39, 0x35, - 0x34, 0xef, 0x36, 0x70, 0x53, 0x0a, 0x1d, 0x46, 0x7b, 0x40, 0xa6, 0x4c, 0x5a, 0x2e, 0x6b, 0x2f, - 0x12, 0xd3, 0xc2, 0x8e, 0x94, 0xbb, 0x35, 0x3d, 0x0c, 0x32, 0x28, 0x76, 0xa5, 0xe2, 0x11, 0x34, - 0xda, 0x03, 0xbb, 0xc0, 0x28, 0x27, 0xd8, 0x93, 0x92, 0xdd, 0xbc, 0xcf, 0xd8, 0xa6, 0xdf, 0x8c, - 0x06, 0xd7, 0x83, 0x12, 0x3d, 0x9a, 0x96, 0x2d, 0x71, 0xd1, 0xc2, 0x41, 0x2b, 0x35, 0x43, 0x9e, - 0x19, 0x90, 0xeb, 0x38, 0x96, 0xae, 0xb8, 0x82, 0x63, 0xf2, 0x59, 0x75, 0x3c, 0x1a, 0x4b, 0xbf, - 0x16, 0x12, 0xb2, 0x6a, 0x6b, 0xdf, 0x2d, 0x35, 0x33, 0xe9, 0x2b, 0x52, 0x61, 0xef, 0x81, 0x77, - 0xa4, 0xc2, 0xe4, 0x98, 0x9a, 0x80, 0xdf, 0x88, 0x8a, 0x8a, 0xc7, 0xd5, 0x3d, 0x52, 0x2e, 0xb3, - 0xd0, 0x31, 0x28, 0xc6, 0xd6, 0x69, 0xa9, 0x96, 0x29, 0x63, 0xd2, 0xa7, 0x1a, 0x2c, 0x67, 0x24, - 0x7a, 0x14, 0xed, 0x85, 0xd0, 0xf4, 0x14, 0x9a, 0x94, 0xf0, 0x38, 0x3a, 0x00, 0xc1, 0x1d, 0xd3, - 0x68, 0x0a, 0x0e, 0x76, 0xa1, 0x54, 0x4e, 0xd4, 0xb1, 0x08, 0xcf, 0xd8, 0x85, 0x52, 0x59, 0x11, - 0xd3, 0xf0, 0x91, 0x75, 0xa1, 0x54, 0x96, 0xd5, 0x2b, 0xc1, 0x6f, 0x4c, 0x09, 0x10, 0xab, 0xb6, - 0x86, 0x67, 0xe0, 0x01, 0xb4, 0x50, 0x2a, 0x4f, 0x93, 0x3a, 0x6b, 0x7b, 0x5c, 0xe5, 0x78, 0x16, - 0xae, 0x5d, 0x0c, 0x12, 0x4b, 0xa1, 0xf3, 0xf0, 0xd2, 0xce, 0x53, 0xff, 0x52, 0x22, 0x3f, 0x06, - 0x07, 0x27, 0x28, 0x85, 0xf8, 0x5d, 0xce, 0xc3, 0xd4, 0xbf, 0x24, 0x33, 0xe4, 0xf0, 0xe9, 0x4c, - 0x11, 0x61, 0x8a, 0x81, 0x54, 0xc9, 0x34, 0xa4, 0x62, 0x54, 0xd4, 0x2b, 0x52, 0x2a, 0xb3, 0x1f, - 0x05, 0xd6, 0xb1, 0x80, 0xab, 0x70, 0xd5, 0x04, 0x9b, 0xee, 0x8c, 0x35, 0xf8, 0x8d, 0x22, 0x4b, - 0x11, 0xef, 0xaf, 0x36, 0x3c, 0x50, 0x05, 0x17, 0x43, 0x97, 0xf5, 0xc9, 0x3d, 0x95, 0x48, 0x8d, - 0x5c, 0x76, 0xfd, 0x44, 0x61, 0x1f, 0xcb, 0x69, 0xb1, 0x91, 0x0e, 0x4e, 0x41, 0x8f, 0xe7, 0xf4, - 0x3b, 0x6c, 0x5b, 0x07, 0x24, 0x8b, 0x7b, 0x25, 0xa7, 0x5f, 0x16, 0xdb, 0x41, 0x26, 0x2c, 0xef, - 0x27, 0x72, 0x7a, 0x34, 0xec, 0x82, 0xc2, 0x8a, 0xe3, 0xff, 0x64, 0x4e, 0x8f, 0x86, 0x42, 0x07, - 0x19, 0x63, 0x9f, 0xca, 0xe9, 0xfe, 0x49, 0x9f, 0xe2, 0x38, 0xb1, 0x6d, 0x93, 0xc9, 0xe0, 0x7e, - 0x9e, 0xd3, 0x0d, 0xb9, 0x1b, 0xa0, 0x6a, 0x6b, 0x15, 0x4f, 0xcd, 0x86, 0x5f, 0x74, 0x89, 0x50, - 0xa2, 0x89, 0xd2, 0xfd, 0xb2, 0x4b, 0x84, 0x92, 0x54, 0xd8, 0xaf, 0x94, 0xe0, 0xf1, 0xf4, 0x91, - 0x5a, 0x62, 0x45, 0x46, 0xc2, 0x23, 0x72, 0x5d, 0x1c, 0x38, 0x2b, 0x1e, 0x7e, 0x2e, 0xa7, 0xa7, - 0xd8, 0x4e, 0x00, 0x3f, 0x67, 0xb6, 0xc5, 0x4b, 0xb7, 0xe2, 0xe1, 0xe7, 0x73, 0x7a, 0xea, 0x8c, - 0x82, 0x20, 0x6f, 0xc6, 0xf0, 0x0b, 0xbd, 0xe1, 0xb2, 0xe9, 0x98, 0x0d, 0x52, 0x59, 0x5e, 0x26, - 0xac, 0xe2, 0xe1, 0x17, 0x15, 0x7c, 0x3b, 0x3a, 0xd4, 0x35, 0x62, 0x71, 0xc6, 0xa7, 0x2b, 0xda, - 0xe6, 0xa5, 0x9c, 0xde, 0x11, 0x7b, 0xa0, 0x75, 0x20, 0xbc, 0xe2, 0x71, 0xea, 0x3a, 0x7e, 0xc5, - 0xc3, 0x2f, 0xf7, 0x0e, 0x26, 0xba, 0x45, 0xd7, 0x58, 0xe0, 0x8b, 0xc8, 0xaf, 0xf5, 0x16, 0x9e, - 0xb4, 0x6d, 0x77, 0x55, 0xb1, 0xaf, 0x28, 0xf6, 0x58, 0x7a, 0x10, 0x2b, 0x36, 0x2a, 0x72, 0x99, - 0xb0, 0x06, 0xa9, 0x78, 0xf8, 0xd5, 0xde, 0xca, 0x51, 0x4d, 0xa6, 0x4d, 0x6e, 0x56, 0x3c, 0xfc, - 0x5a, 0x6f, 0xe5, 0xa9, 0xa0, 0xe5, 0x55, 0x45, 0x03, 0x39, 0x75, 0xa1, 0xfc, 0x7a, 0x4e, 0xef, - 0xe4, 0x1d, 0x5d, 0x9a, 0x32, 0xdc, 0x0d, 0x6f, 0xe4, 0xf4, 0xb4, 0x49, 0xf7, 0x38, 0x73, 0x9d, - 0x44, 0xa3, 0xbd, 0x99, 0xd3, 0x83, 0x6b, 0x5b, 0x16, 0x53, 0xcc, 0x5b, 0x39, 0x7d, 0x48, 0xde, - 0x9a, 0x65, 0xe4, 0x26, 0x78, 0xbb, 0xdb, 0x56, 0x97, 0x48, 0x18, 0xd2, 0x3b, 0x5d, 0xf6, 0x53, - 0xd1, 0x64, 0x96, 0xe9, 0xb8, 0x52, 0xea, 0x1b, 0x79, 0xb8, 0x49, 0x25, 0x15, 0xbf, 0x69, 0x9f, - 0xca, 0xeb, 0x0f, 0x03, 0x7b, 0x00, 0x30, 0xb5, 0xe3, 0xbf, 0xd9, 0x5b, 0x34, 0x06, 0xbf, 0x95, - 0x87, 0xb7, 0x68, 0x2c, 0xaa, 0xaa, 0xf2, 0xed, 0x3c, 0xbc, 0x45, 0x25, 0xa9, 0xb0, 0xef, 0xe4, - 0xf5, 0x3b, 0x76, 0x04, 0x4c, 0x47, 0x9c, 0x07, 0xae, 0xe6, 0xe1, 0x45, 0x4d, 0x54, 0x26, 0xac, - 0xe0, 0x77, 0x95, 0x58, 0x66, 0xd6, 0x54, 0x1c, 0xee, 0xda, 0x6e, 0xa3, 0x9d, 0x08, 0xef, 0x37, - 0x5d, 0x24, 0x15, 0xaa, 0xb8, 0xdf, 0xe6, 0xf5, 0x15, 0x7e, 0xb4, 0x8b, 0x64, 0x5c, 0x9d, 0xdf, - 0xe5, 0xe1, 0x73, 0x9a, 0x82, 0x63, 0xf2, 0xf7, 0xeb, 0xc8, 0x86, 0x8b, 0xcd, 0x4c, 0xc7, 0x5f, - 0x26, 0x0c, 0xff, 0x41, 0xc9, 0x66, 0xc6, 0x58, 0x12, 0x26, 0x96, 0xc6, 0xff, 0xa8, 0xb4, 0xc7, - 0xd1, 0xfe, 0x6e, 0xf8, 0x05, 0xca, 0x9b, 0x16, 0x33, 0x57, 0x2b, 0x4e, 0x03, 0xff, 0x49, 0xc9, - 0x9f, 0x44, 0xb7, 0x76, 0x97, 0x4f, 0x5a, 0xfc, 0x39, 0xaf, 0x3f, 0x3e, 0x74, 0xb5, 0xa8, 0x38, - 0x7c, 0xce, 0x5a, 0x24, 0x0d, 0xea, 0x8b, 0xbb, 0xfc, 0x1b, 0x79, 0x78, 0xae, 0xa5, 0x7d, 0xa4, - 0x6d, 0xfe, 0xa2, 0xbc, 0x9c, 0x42, 0x47, 0x7a, 0x7a, 0x99, 0xb4, 0xac, 0x49, 0xce, 0x19, 0x5d, - 0x0a, 0x38, 0xf1, 0xf1, 0x5f, 0x95, 0xab, 0xbb, 0xd0, 0xb1, 0x75, 0x5c, 0xa5, 0x0d, 0xff, 0x96, - 0xd7, 0xa7, 0x85, 0xd4, 0x26, 0x58, 0xa4, 0x9e, 0x67, 0x93, 0x44, 0xef, 0x3c, 0x3c, 0x00, 0xbf, - 0x6f, 0x23, 0x50, 0x51, 0x1f, 0x1d, 0x80, 0x3b, 0x3b, 0xa2, 0xe4, 0x6e, 0x7e, 0x64, 0x00, 0xde, - 0x25, 0x31, 0x14, 0x36, 0xf6, 0xa3, 0x0a, 0x7b, 0x37, 0x1a, 0x4b, 0xdd, 0x9f, 0x5d, 0x87, 0x30, - 0x37, 0x5c, 0x79, 0xb3, 0x2e, 0x66, 0xfc, 0x9c, 0x43, 0xb9, 0x1a, 0x00, 0x7f, 0x1f, 0xd0, 0x17, - 0xbb, 0x03, 0xeb, 0x1a, 0x89, 0x6d, 0xf6, 0x0f, 0x65, 0x90, 0xa9, 0x5c, 0x87, 0x41, 0x95, 0xf0, - 0x39, 0xc7, 0x0b, 0xb4, 0xa7, 0x7f, 0x2a, 0xc3, 0xf5, 0xc2, 0x53, 0x86, 0xc2, 0xdb, 0xbf, 0x94, - 0xd1, 0x19, 0x74, 0x6a, 0x9d, 0xf0, 0xbc, 0x80, 0xfb, 0xe7, 0x08, 0x6b, 0x05, 0xdc, 0x14, 0x7f, - 0x50, 0x6e, 0xff, 0xad, 0x14, 0x4e, 0xa3, 0xdb, 0xfe, 0x3f, 0x05, 0xe1, 0xff, 0x4d, 0x65, 0x7d, - 0x37, 0x3a, 0xbe, 0xbe, 0xf5, 0x79, 0xea, 0x50, 0xe5, 0xf7, 0x2d, 0x65, 0x79, 0x07, 0x3a, 0xdc, - 0x9f, 0xa5, 0xf0, 0xf7, 0xb6, 0xb2, 0xba, 0x07, 0x9d, 0xec, 0x69, 0x35, 0x69, 0xdb, 0x51, 0xc0, - 0x55, 0xa2, 0x2b, 0xfc, 0x4e, 0xbf, 0x4b, 0x93, 0x34, 0x16, 0x5e, 0xff, 0xd3, 0x6f, 0x96, 0xe2, - 0x98, 0x10, 0xf0, 0xc4, 0xa2, 0xfe, 0xb7, 0xdf, 0x2c, 0xb5, 0xa5, 0xf0, 0xf7, 0x7e, 0xa3, 0x4f, - 0x7f, 0x93, 0xb6, 0x5d, 0x09, 0x78, 0x22, 0xc5, 0x0f, 0x18, 0x7d, 0xfa, 0xd3, 0x96, 0xc2, 0xdf, - 0x07, 0xfb, 0xf5, 0x17, 0x7e, 0xf4, 0x49, 0x36, 0xed, 0x87, 0xfa, 0xf5, 0xa7, 0x2d, 0x85, 0xbf, - 0x0f, 0xf7, 0x6b, 0x35, 0x43, 0x1d, 0xd3, 0x56, 0xbe, 0x3e, 0x62, 0xc0, 0x03, 0x13, 0xb6, 0x12, - 0x7e, 0x1e, 0x52, 0x16, 0x77, 0xa2, 0xa3, 0x9d, 0x16, 0x67, 0x49, 0x7b, 0xae, 0x65, 0x36, 0x48, - 0x69, 0xcd, 0x73, 0x19, 0x4f, 0x6e, 0xfa, 0x47, 0x94, 0x5d, 0x66, 0xd0, 0x76, 0xb3, 0x13, 0xbe, - 0x1e, 0xed, 0x99, 0x93, 0xb2, 0xa9, 0xb6, 0x9d, 0x7a, 0x95, 0x13, 0x7d, 0x5a, 0xff, 0x58, 0xcf, - 0x9c, 0xb2, 0x56, 0xc2, 0xcf, 0xc7, 0x0d, 0x78, 0xa0, 0x77, 0x5a, 0xa4, 0x8a, 0xf7, 0x98, 0x32, - 0xbb, 0x0d, 0x1d, 0xec, 0xc3, 0x4c, 0x78, 0x7a, 0xdc, 0x80, 0x47, 0x79, 0x64, 0x92, 0x18, 0xe5, - 0x9f, 0x36, 0xe0, 0x51, 0x1e, 0x81, 0x8a, 0xfa, 0x8c, 0x01, 0x9f, 0x7a, 0xb4, 0xdc, 0x05, 0x93, - 0xd7, 0x9b, 0xe2, 0xbd, 0xfe, 0x59, 0x03, 0x9e, 0xe7, 0x11, 0xa9, 0xb1, 0xcf, 0x19, 0xf0, 0xc5, - 0x24, 0xfc, 0x50, 0x14, 0xb1, 0xd3, 0xd4, 0x6c, 0xa8, 0x0a, 0x7c, 0xde, 0x80, 0xef, 0x50, 0x19, - 0x5c, 0x64, 0xfe, 0x05, 0xa5, 0x9c, 0x39, 0x2d, 0xeb, 0x50, 0x6b, 0x6b, 0x67, 0x89, 0xfe, 0xa9, - 0xe3, 0x8b, 0x06, 0x7c, 0x60, 0x49, 0xd3, 0x42, 0xf7, 0x4b, 0x3d, 0x7b, 0x64, 0x9e, 0xae, 0x90, - 0x45, 0xb2, 0xcc, 0x88, 0xdf, 0xac, 0x72, 0x93, 0xe9, 0x6e, 0x7c, 0xd2, 0x80, 0x8f, 0x16, 0xb0, - 0x95, 0xf0, 0xf3, 0x65, 0xa3, 0xd7, 0xab, 0x24, 0x65, 0x11, 0xb7, 0xe2, 0x57, 0x94, 0x1b, 0xf0, - 0x4d, 0x97, 0x31, 0x12, 0x5e, 0xbe, 0xda, 0x6f, 0x36, 0xa9, 0x46, 0xfc, 0x5a, 0xbf, 0xd9, 0xe8, - 0x3e, 0xfc, 0xba, 0x01, 0x7f, 0x0a, 0x28, 0x65, 0x6e, 0xdc, 0xd7, 0x0c, 0xf8, 0x7e, 0x50, 0x4a, - 0xde, 0xb7, 0x5f, 0x31, 0xf4, 0x67, 0x96, 0x2d, 0x19, 0x48, 0x9e, 0x26, 0x5e, 0xed, 0xd2, 0x27, - 0x25, 0xd7, 0x17, 0x07, 0xe9, 0xe4, 0xbb, 0xf3, 0xd7, 0x06, 0x7c, 0xff, 0x49, 0xa0, 0x22, 0x81, - 0xd7, 0x0c, 0xf8, 0xfe, 0x53, 0x4a, 0x7c, 0x58, 0x78, 0xbd, 0xcb, 0xee, 0x98, 0xa2, 0x8e, 0xe9, - 0xd4, 0x93, 0x07, 0xa7, 0x1f, 0x0c, 0xc2, 0xbb, 0x43, 0x92, 0x0a, 0xfb, 0xe1, 0x20, 0x7c, 0x73, - 0x89, 0x05, 0xe3, 0xa2, 0xfc, 0x68, 0x10, 0xbe, 0xb9, 0x48, 0x36, 0x06, 0x7f, 0x3c, 0x08, 0xdf, - 0xae, 0x24, 0x28, 0x2b, 0xf8, 0x74, 0x6f, 0xb9, 0xf8, 0x76, 0xf5, 0x93, 0x41, 0xf8, 0xaa, 0xa1, - 0x40, 0x79, 0x18, 0x2f, 0xfb, 0x0d, 0xfc, 0xcc, 0x20, 0x7c, 0xd5, 0x90, 0x68, 0x85, 0x59, 0x11, - 0xf7, 0x6c, 0x6f, 0xdf, 0xd1, 0x8f, 0xb4, 0x02, 0xfc, 0x69, 0x6f, 0x41, 0xbd, 0x30, 0x3f, 0x93, - 0x31, 0x4e, 0x9c, 0x46, 0xd7, 0xaf, 0x52, 0x46, 0x2e, 0x52, 0x67, 0x78, 0xef, 0x78, 0xf4, 0x4b, - 0xff, 0xb8, 0xfa, 0xa5, 0x7f, 0xbc, 0xe4, 0x04, 0xad, 0xf0, 0xe7, 0x12, 0xf9, 0x95, 0x60, 0xe4, - 0xb9, 0x87, 0x06, 0x46, 0x73, 0x63, 0x43, 0x8b, 0xd7, 0x09, 0x9b, 0x39, 0x67, 0xe2, 0x5e, 0x34, - 0x14, 0x5a, 0xbb, 0x01, 0xef, 0xc7, 0xfc, 0x79, 0x69, 0x1e, 0xba, 0xac, 0x04, 0x7c, 0x62, 0x16, - 0x6d, 0x0a, 0xed, 0x2d, 0x31, 0xad, 0xfa, 0x8c, 0xe1, 0x05, 0x29, 0xb2, 0x41, 0x58, 0x86, 0x63, - 0x6e, 0xce, 0x99, 0x98, 0x43, 0x9b, 0x13, 0x42, 0x7d, 0x86, 0xf3, 0xa2, 0x54, 0xda, 0xa8, 0x95, - 0x44, 0x4c, 0x67, 0xd0, 0x0d, 0xa1, 0x14, 0xa7, 0x4e, 0xbb, 0x1f, 0x95, 0x97, 0xa4, 0x4a, 0x58, - 0x89, 0x1a, 0x75, 0xda, 0x13, 0xf3, 0xe8, 0xc6, 0x50, 0x61, 0xc9, 0x75, 0xb9, 0xed, 0x9a, 0x16, - 0x61, 0xfd, 0xe8, 0xbc, 0x2c, 0x75, 0xc2, 0x44, 0xa6, 0xb4, 0xe9, 0x44, 0x11, 0x85, 0x99, 0x5e, - 0x74, 0xdc, 0x8b, 0xcb, 0x7e, 0xab, 0x1f, 0xa5, 0x6b, 0x52, 0x29, 0xcc, 0x63, 0xc1, 0x9d, 0xf1, - 0x5b, 0x53, 0x77, 0xa0, 0xfd, 0x75, 0xb7, 0x35, 0xee, 0x9b, 0xdc, 0xf5, 0x9b, 0xd4, 0x36, 0x97, - 0x7c, 0xf5, 0xff, 0x79, 0xd8, 0x74, 0x49, 0x4b, 0x4d, 0x6d, 0xaa, 0x85, 0x7f, 0x94, 0x9d, 0xf3, - 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x69, 0x67, 0x5d, 0x1f, 0x22, 0x00, 0x00, +func init() { file_messages_proto_init() } +func file_messages_proto_init() { + if File_messages_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_messages_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 7, + NumServices: 0, + }, + GoTypes: file_messages_proto_goTypes, + DependencyIndexes: file_messages_proto_depIdxs, + EnumInfos: file_messages_proto_enumTypes, + ExtensionInfos: file_messages_proto_extTypes, + }.Build() + File_messages_proto = out.File + file_messages_proto_rawDesc = nil + file_messages_proto_goTypes = nil + file_messages_proto_depIdxs = nil } diff --git a/accounts/usbwallet/trezor/messages.proto b/accounts/usbwallet/trezor/messages.proto index 3e0482e344..02ff4e0fb2 100644 --- a/accounts/usbwallet/trezor/messages.proto +++ b/accounts/usbwallet/trezor/messages.proto @@ -9,10 +9,13 @@ package hw.trezor.messages; * Messages for TREZOR communication */ +option go_package = "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet/trezor"; + // Sugar for easier handling in Java option java_package = "com.satoshilabs.trezor.lib.protobuf"; option java_outer_classname = "TrezorMessage"; + import "google/protobuf/descriptor.proto"; /** diff --git a/accounts/usbwallet/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go index af4d2d0d0a..4697156ce0 100644 --- a/accounts/usbwallet/trezor/trezor.go +++ b/accounts/usbwallet/trezor/trezor.go @@ -42,7 +42,7 @@ // - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go` // - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...` -//go:generate protoc -I/usr/local/include:. --go_out=import_path=trezor:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto +//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto // Package trezor contains the wire protocol. package trezor From 1fcc36a2dc8439cc2e443bdf284425c3f831fa70 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 269/280] build: add check for stale generated files (#30037) Co-authored-by: Felix Lange --- .../usbwallet/trezor/messages-common.pb.go | 26 +++++------ .../usbwallet/trezor/messages-ethereum.pb.go | 24 +++++----- .../trezor/messages-management.pb.go | 46 +++++++++---------- accounts/usbwallet/trezor/messages.pb.go | 4 +- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/accounts/usbwallet/trezor/messages-common.pb.go b/accounts/usbwallet/trezor/messages-common.pb.go index 3c62f40274..58c3f65b2e 100644 --- a/accounts/usbwallet/trezor/messages-common.pb.go +++ b/accounts/usbwallet/trezor/messages-common.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v5.27.1 // source: messages-common.proto @@ -1010,7 +1010,7 @@ func file_messages_common_proto_rawDescGZIP() []byte { var file_messages_common_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_messages_common_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_messages_common_proto_goTypes = []interface{}{ +var file_messages_common_proto_goTypes = []any{ (Failure_FailureType)(0), // 0: hw.trezor.messages.common.Failure.FailureType (ButtonRequest_ButtonRequestType)(0), // 1: hw.trezor.messages.common.ButtonRequest.ButtonRequestType (PinMatrixRequest_PinMatrixRequestType)(0), // 2: hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestType @@ -1043,7 +1043,7 @@ func file_messages_common_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_messages_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Success); i { case 0: return &v.state @@ -1055,7 +1055,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Failure); i { case 0: return &v.state @@ -1067,7 +1067,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*ButtonRequest); i { case 0: return &v.state @@ -1079,7 +1079,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*ButtonAck); i { case 0: return &v.state @@ -1091,7 +1091,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*PinMatrixRequest); i { case 0: return &v.state @@ -1103,7 +1103,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*PinMatrixAck); i { case 0: return &v.state @@ -1115,7 +1115,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*PassphraseRequest); i { case 0: return &v.state @@ -1127,7 +1127,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*PassphraseAck); i { case 0: return &v.state @@ -1139,7 +1139,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*PassphraseStateRequest); i { case 0: return &v.state @@ -1151,7 +1151,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*PassphraseStateAck); i { case 0: return &v.state @@ -1163,7 +1163,7 @@ func file_messages_common_proto_init() { return nil } } - file_messages_common_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_messages_common_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*HDNodeType); i { case 0: return &v.state diff --git a/accounts/usbwallet/trezor/messages-ethereum.pb.go b/accounts/usbwallet/trezor/messages-ethereum.pb.go index 075b05bef0..6ab25df0c3 100644 --- a/accounts/usbwallet/trezor/messages-ethereum.pb.go +++ b/accounts/usbwallet/trezor/messages-ethereum.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v5.27.1 // source: messages-ethereum.proto @@ -831,7 +831,7 @@ func file_messages_ethereum_proto_rawDescGZIP() []byte { } var file_messages_ethereum_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_messages_ethereum_proto_goTypes = []interface{}{ +var file_messages_ethereum_proto_goTypes = []any{ (*EthereumGetPublicKey)(nil), // 0: hw.trezor.messages.ethereum.EthereumGetPublicKey (*EthereumPublicKey)(nil), // 1: hw.trezor.messages.ethereum.EthereumPublicKey (*EthereumGetAddress)(nil), // 2: hw.trezor.messages.ethereum.EthereumGetAddress @@ -860,7 +860,7 @@ func file_messages_ethereum_proto_init() { } file_messages_common_proto_init() if !protoimpl.UnsafeEnabled { - file_messages_ethereum_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*EthereumGetPublicKey); i { case 0: return &v.state @@ -872,7 +872,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*EthereumPublicKey); i { case 0: return &v.state @@ -884,7 +884,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*EthereumGetAddress); i { case 0: return &v.state @@ -896,7 +896,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*EthereumAddress); i { case 0: return &v.state @@ -908,7 +908,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*EthereumSignTx); i { case 0: return &v.state @@ -920,7 +920,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*EthereumTxRequest); i { case 0: return &v.state @@ -932,7 +932,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*EthereumTxAck); i { case 0: return &v.state @@ -944,7 +944,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*EthereumSignMessage); i { case 0: return &v.state @@ -956,7 +956,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*EthereumMessageSignature); i { case 0: return &v.state @@ -968,7 +968,7 @@ func file_messages_ethereum_proto_init() { return nil } } - file_messages_ethereum_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_messages_ethereum_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*EthereumVerifyMessage); i { case 0: return &v.state diff --git a/accounts/usbwallet/trezor/messages-management.pb.go b/accounts/usbwallet/trezor/messages-management.pb.go index b27fe67519..af435184b1 100644 --- a/accounts/usbwallet/trezor/messages-management.pb.go +++ b/accounts/usbwallet/trezor/messages-management.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v5.27.1 // source: messages-management.proto @@ -1955,7 +1955,7 @@ func file_messages_management_proto_rawDescGZIP() []byte { var file_messages_management_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_messages_management_proto_msgTypes = make([]protoimpl.MessageInfo, 21) -var file_messages_management_proto_goTypes = []interface{}{ +var file_messages_management_proto_goTypes = []any{ (ApplySettings_PassphraseSourceType)(0), // 0: hw.trezor.messages.management.ApplySettings.PassphraseSourceType (RecoveryDevice_RecoveryDeviceType)(0), // 1: hw.trezor.messages.management.RecoveryDevice.RecoveryDeviceType (WordRequest_WordRequestType)(0), // 2: hw.trezor.messages.management.WordRequest.WordRequestType @@ -2001,7 +2001,7 @@ func file_messages_management_proto_init() { } file_messages_common_proto_init() if !protoimpl.UnsafeEnabled { - file_messages_management_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Initialize); i { case 0: return &v.state @@ -2013,7 +2013,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*GetFeatures); i { case 0: return &v.state @@ -2025,7 +2025,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*Features); i { case 0: return &v.state @@ -2037,7 +2037,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*ClearSession); i { case 0: return &v.state @@ -2049,7 +2049,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*ApplySettings); i { case 0: return &v.state @@ -2061,7 +2061,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*ApplyFlags); i { case 0: return &v.state @@ -2073,7 +2073,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*ChangePin); i { case 0: return &v.state @@ -2085,7 +2085,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*Ping); i { case 0: return &v.state @@ -2097,7 +2097,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*Cancel); i { case 0: return &v.state @@ -2109,7 +2109,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*GetEntropy); i { case 0: return &v.state @@ -2121,7 +2121,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*Entropy); i { case 0: return &v.state @@ -2133,7 +2133,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[11].Exporter = func(v any, i int) any { switch v := v.(*WipeDevice); i { case 0: return &v.state @@ -2145,7 +2145,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*LoadDevice); i { case 0: return &v.state @@ -2157,7 +2157,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[13].Exporter = func(v any, i int) any { switch v := v.(*ResetDevice); i { case 0: return &v.state @@ -2169,7 +2169,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*BackupDevice); i { case 0: return &v.state @@ -2181,7 +2181,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[15].Exporter = func(v any, i int) any { switch v := v.(*EntropyRequest); i { case 0: return &v.state @@ -2193,7 +2193,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*EntropyAck); i { case 0: return &v.state @@ -2205,7 +2205,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*RecoveryDevice); i { case 0: return &v.state @@ -2217,7 +2217,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*WordRequest); i { case 0: return &v.state @@ -2229,7 +2229,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[19].Exporter = func(v any, i int) any { switch v := v.(*WordAck); i { case 0: return &v.state @@ -2241,7 +2241,7 @@ func file_messages_management_proto_init() { return nil } } - file_messages_management_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_messages_management_proto_msgTypes[20].Exporter = func(v any, i int) any { switch v := v.(*SetU2FCounter); i { case 0: return &v.state diff --git a/accounts/usbwallet/trezor/messages.pb.go b/accounts/usbwallet/trezor/messages.pb.go index 5cc7b222cb..39b8493273 100644 --- a/accounts/usbwallet/trezor/messages.pb.go +++ b/accounts/usbwallet/trezor/messages.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v5.27.1 // source: messages.proto @@ -1320,7 +1320,7 @@ func file_messages_proto_rawDescGZIP() []byte { } var file_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_messages_proto_goTypes = []interface{}{ +var file_messages_proto_goTypes = []any{ (MessageType)(0), // 0: hw.trezor.messages.MessageType (*descriptorpb.EnumValueOptions)(nil), // 1: google.protobuf.EnumValueOptions } From 52ac8ae22b4907b3dc3e090b2e8b27d3622b62ef Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 270/280] accounts/abi/bind: use embed pkg to split go source template to file (#30098) --- accounts/abi/bind/source.go.tpl | 486 +++++++++++++++++++++++++++++++ accounts/abi/bind/template.go | 497 +------------------------------- 2 files changed, 494 insertions(+), 489 deletions(-) create mode 100644 accounts/abi/bind/source.go.tpl diff --git a/accounts/abi/bind/source.go.tpl b/accounts/abi/bind/source.go.tpl new file mode 100644 index 0000000000..f1f75b6388 --- /dev/null +++ b/accounts/abi/bind/source.go.tpl @@ -0,0 +1,486 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package {{.Package}} + +import ( + "math/big" + "strings" + "errors" + + ethereum "github.com/XinFinOrg/XDPoSChain" + "github.com/XinFinOrg/XDPoSChain/accounts/abi" + "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" + "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/core/types" + "github.com/XinFinOrg/XDPoSChain/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.ErrNotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +{{$structs := .Structs}} +{{range $structs}} + // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. + type {{.Name}} struct { + {{range $field := .Fields}} + {{$field.Name}} {{$field.Type}}{{end}} + } +{{end}} + +{{range $contract := .Contracts}} + // {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract. + var {{.Type}}MetaData = &bind.MetaData{ + ABI: "{{.InputABI}}", + {{if $contract.FuncSigs -}} + Sigs: map[string]string{ + {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", + {{end}} + }, + {{end -}} + {{if .InputBin -}} + Bin: "0x{{.InputBin}}", + {{end}} + } + // {{.Type}}ABI is the input ABI used to generate the binding from. + // Deprecated: Use {{.Type}}MetaData.ABI instead. + var {{.Type}}ABI = {{.Type}}MetaData.ABI + + {{if $contract.FuncSigs}} + // Deprecated: Use {{.Type}}MetaData.Sigs instead. + // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. + var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs + {{end}} + + {{if .InputBin}} + // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. + // Deprecated: Use {{.Type}}MetaData.Bin instead. + var {{.Type}}Bin = {{.Type}}MetaData.Bin + + // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. + func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { + parsed, err := {{.Type}}MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + {{range $pattern, $name := .Libraries}} + {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) + {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) + {{end}} + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil + } + {{end}} + + // {{.Type}} is an auto generated Go binding around an Ethereum contract. + type {{.Type}} struct { + {{.Type}}Caller // Read-only binding to the contract + {{.Type}}Transactor // Write-only binding to the contract + {{.Type}}Filterer // Log filterer for contract events + } + + // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract. + type {{.Type}}Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract. + type {{.Type}}Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events. + type {{.Type}}Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls + } + + // {{.Type}}Session is an auto generated Go binding around an Ethereum contract, + // with pre-set call and transact options. + type {{.Type}}Session struct { + Contract *{{.Type}} // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + } + + // {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract, + // with pre-set call options. + type {{.Type}}CallerSession struct { + Contract *{{.Type}}Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + } + + // {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract, + // with pre-set transact options. + type {{.Type}}TransactorSession struct { + Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + } + + // {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract. + type {{.Type}}Raw struct { + Contract *{{.Type}} // Generic contract binding to access the raw methods on + } + + // {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. + type {{.Type}}CallerRaw struct { + Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on + } + + // {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. + type {{.Type}}TransactorRaw struct { + Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on + } + + // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) { + contract, err := bind{{.Type}}(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil + } + + // New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) { + contract, err := bind{{.Type}}(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &{{.Type}}Caller{contract: contract}, nil + } + + // New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) { + contract, err := bind{{.Type}}(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &{{.Type}}Transactor{contract: contract}, nil + } + + // New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract. + func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) { + contract, err := bind{{.Type}}(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &{{.Type}}Filterer{contract: contract}, nil + } + + // bind{{.Type}} binds a generic wrapper to an already deployed contract. + func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + } + + // Call invokes the (constant) contract method with params as input values and + // sets the output to result. The result type might be a single field for simple + // returns, a slice of interfaces for anonymous returns and a struct for named + // returns. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...) + } + + // Transfer initiates a plain transaction to move funds to the contract, calling + // its default method if one is available. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts) + } + + // Transact invokes the (paid) contract method with params as input values. + func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...) + } + + // Call invokes the (constant) contract method with params as input values and + // sets the output to result. The result type might be a single field for simple + // returns, a slice of interfaces for anonymous returns and a struct for named + // returns. + func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...) + } + + // Transfer initiates a plain transaction to move funds to the contract, calling + // its default method if one is available. + func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.contract.Transfer(opts) + } + + // Transact invokes the (paid) contract method with params as input values. + func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) + } + + {{range .Calls}} + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { + var out []interface{} + err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + {{if .Structured}} + outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) + if err != nil { + return *outstruct, err + } + {{range $i, $t := .Normalized.Outputs}} + outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return *outstruct, err + {{else}} + if err != nil { + return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err + } + {{range $i, $t := .Normalized.Outputs}} + out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err + {{end}} + } + + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + {{end}} + + {{range .Transacts}} + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) + } + + // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) + } + {{end}} + + {{if .Fallback}} + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + + // Fallback is a paid mutator transaction binding the contract fallback function. + // + // Solidity: {{.Fallback.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) + } + {{end}} + + {{if .Receive}} + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + + // Receive is a paid mutator transaction binding the contract receive function. + // + // Solidity: {{.Receive.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { + return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) + } + {{end}} + + {{range .Events}} + // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract. + type {{$contract.Type}}{{.Normalized.Name}}Iterator struct { + Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration + } + // Next advances the iterator to the subsequent event, returning whether there + // are any more events found. In case of a retrieval or parsing error, false is + // returned and Error() can be queried for the exact failure. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool { + // If the iterator failed, stop iterating + if (it.fail != nil) { + return false + } + // If the iterator completed, deliver directly whatever's available + if (it.done) { + select { + case log := <-it.logs: + it.Event = new({{$contract.Type}}{{.Normalized.Name}}) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new({{$contract.Type}}{{.Normalized.Name}}) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } + } + // Error returns any retrieval or parsing error occurred during filtering. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error { + return it.fail + } + // Close terminates the iteration process, releasing any pending underlying + // resources. + func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error { + it.sub.Unsubscribe() + return nil + } + + // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract. + type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}} + {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}} + Raw types.Log // Blockchain specific contextual infos + } + + // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { + {{range .Normalized.Inputs}} + {{if .Indexed}}var {{.Name}}Rule []interface{} + for _, {{.Name}}Item := range {{.Name}} { + {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) + }{{end}}{{end}} + + logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) + if err != nil { + return nil, err + } + return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil + } + + // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { + {{range .Normalized.Inputs}} + {{if .Indexed}}var {{.Name}}Rule []interface{} + for _, {{.Name}}Item := range {{.Name}} { + {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) + }{{end}}{{end}} + + logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil + } + + // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. + // + // Solidity: {{.Original.String}} + func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { + event := new({{$contract.Type}}{{.Normalized.Name}}) + if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil + } + + {{end}} +{{end}} diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 7033ff04d1..5d05f07971 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -16,7 +16,11 @@ package bind -import "github.com/XinFinOrg/XDPoSChain/accounts/abi" +import ( + _ "embed" + + "github.com/XinFinOrg/XDPoSChain/accounts/abi" +) // tmplData is the data structure required to fill the binding template. type tmplData struct { @@ -80,491 +84,6 @@ var tmplSource = map[Lang]string{ // tmplSourceGo is the Go source template that the generated Go contract binding // is based on. -const tmplSourceGo = ` -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package {{.Package}} - -import ( - "math/big" - "strings" - "errors" - - ethereum "github.com/XinFinOrg/XDPoSChain" - "github.com/XinFinOrg/XDPoSChain/accounts/abi" - "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" - "github.com/XinFinOrg/XDPoSChain/common" - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.ErrNotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -{{$structs := .Structs}} -{{range $structs}} - // {{.Name}} is an auto generated low-level Go binding around an user-defined struct. - type {{.Name}} struct { - {{range $field := .Fields}} - {{$field.Name}} {{$field.Type}}{{end}} - } -{{end}} - -{{range $contract := .Contracts}} - // {{.Type}}MetaData contains all meta data concerning the {{.Type}} contract. - var {{.Type}}MetaData = &bind.MetaData{ - ABI: "{{.InputABI}}", - {{if $contract.FuncSigs -}} - Sigs: map[string]string{ - {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}", - {{end}} - }, - {{end -}} - {{if .InputBin -}} - Bin: "0x{{.InputBin}}", - {{end}} - } - // {{.Type}}ABI is the input ABI used to generate the binding from. - // Deprecated: Use {{.Type}}MetaData.ABI instead. - var {{.Type}}ABI = {{.Type}}MetaData.ABI - - {{if $contract.FuncSigs}} - // Deprecated: Use {{.Type}}MetaData.Sigs instead. - // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation. - var {{.Type}}FuncSigs = {{.Type}}MetaData.Sigs - {{end}} - - {{if .InputBin}} - // {{.Type}}Bin is the compiled bytecode used for deploying new contracts. - // Deprecated: Use {{.Type}}MetaData.Bin instead. - var {{.Type}}Bin = {{.Type}}MetaData.Bin - - // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it. - func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) { - parsed, err := {{.Type}}MetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - {{range $pattern, $name := .Libraries}} - {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend) - {{$contract.Type}}Bin = strings.ReplaceAll({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:]) - {{end}} - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}}) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil - } - {{end}} - - // {{.Type}} is an auto generated Go binding around an Ethereum contract. - type {{.Type}} struct { - {{.Type}}Caller // Read-only binding to the contract - {{.Type}}Transactor // Write-only binding to the contract - {{.Type}}Filterer // Log filterer for contract events - } - - // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract. - type {{.Type}}Caller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract. - type {{.Type}}Transactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events. - type {{.Type}}Filterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls - } - - // {{.Type}}Session is an auto generated Go binding around an Ethereum contract, - // with pre-set call and transact options. - type {{.Type}}Session struct { - Contract *{{.Type}} // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session - } - - // {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract, - // with pre-set call options. - type {{.Type}}CallerSession struct { - Contract *{{.Type}}Caller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - } - - // {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract, - // with pre-set transact options. - type {{.Type}}TransactorSession struct { - Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session - } - - // {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract. - type {{.Type}}Raw struct { - Contract *{{.Type}} // Generic contract binding to access the raw methods on - } - - // {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. - type {{.Type}}CallerRaw struct { - Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on - } - - // {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. - type {{.Type}}TransactorRaw struct { - Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on - } - - // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) { - contract, err := bind{{.Type}}(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil - } - - // New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) { - contract, err := bind{{.Type}}(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &{{.Type}}Caller{contract: contract}, nil - } - - // New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) { - contract, err := bind{{.Type}}(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &{{.Type}}Transactor{contract: contract}, nil - } - - // New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract. - func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) { - contract, err := bind{{.Type}}(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &{{.Type}}Filterer{contract: contract}, nil - } - - // bind{{.Type}} binds a generic wrapper to an already deployed contract. - func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil - } - - // Call invokes the (constant) contract method with params as input values and - // sets the output to result. The result type might be a single field for simple - // returns, a slice of interfaces for anonymous returns and a struct for named - // returns. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.contract.Call(opts, result, method, params...) - } - - // Transfer initiates a plain transaction to move funds to the contract, calling - // its default method if one is available. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts) - } - - // Transact invokes the (paid) contract method with params as input values. - func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transact(opts, method, params...) - } - - // Call invokes the (constant) contract method with params as input values and - // sets the output to result. The result type might be a single field for simple - // returns, a slice of interfaces for anonymous returns and a struct for named - // returns. - func (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _{{$contract.Type}}.Contract.contract.Call(opts, result, method, params...) - } - - // Transfer initiates a plain transaction to move funds to the contract, calling - // its default method if one is available. - func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.contract.Transfer(opts) - } - - // Transact invokes the (paid) contract method with params as input values. - func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...) - } - - {{range .Calls}} - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) { - var out []interface{} - err := _{{$contract.Type}}.contract.Call(opts, &out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - {{if .Structured}} - outstruct := new(struct{ {{range .Normalized.Outputs}} {{.Name}} {{bindtype .Type $structs}}; {{end}} }) - if err != nil { - return *outstruct, err - } - {{range $i, $t := .Normalized.Outputs}} - outstruct.{{.Name}} = *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} - - return *outstruct, err - {{else}} - if err != nil { - return {{range $i, $_ := .Normalized.Outputs}}*new({{bindtype .Type $structs}}), {{end}} err - } - {{range $i, $t := .Normalized.Outputs}} - out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} - - return {{range $i, $t := .Normalized.Outputs}}out{{$i}}, {{end}} err - {{end}} - } - - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - {{end}} - - {{range .Transacts}} - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) - } - - // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}}) - } - {{end}} - - {{if .Fallback}} - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.RawTransact(opts, calldata) - } - - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) Fallback(calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) - } - - // Fallback is a paid mutator transaction binding the contract fallback function. - // - // Solidity: {{.Fallback.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Fallback(&_{{$contract.Type}}.TransactOpts, calldata) - } - {{end}} - - {{if .Receive}} - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { - return _{{$contract.Type}}.contract.RawTransact(opts, nil) // calldata is disallowed for receive function - } - - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Session) Receive() (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) - } - - // Receive is a paid mutator transaction binding the contract receive function. - // - // Solidity: {{.Receive.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) Receive() (*types.Transaction, error) { - return _{{$contract.Type}}.Contract.Receive(&_{{$contract.Type}}.TransactOpts) - } - {{end}} - - {{range .Events}} - // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract. - type {{$contract.Type}}{{.Normalized.Name}}Iterator struct { - Event *{{$contract.Type}}{{.Normalized.Name}} // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration - } - // Next advances the iterator to the subsequent event, returning whether there - // are any more events found. In case of a retrieval or parsing error, false is - // returned and Error() can be queried for the exact failure. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Next() bool { - // If the iterator failed, stop iterating - if (it.fail != nil) { - return false - } - // If the iterator completed, deliver directly whatever's available - if (it.done) { - select { - case log := <-it.logs: - it.Event = new({{$contract.Type}}{{.Normalized.Name}}) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new({{$contract.Type}}{{.Normalized.Name}}) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } - } - // Error returns any retrieval or parsing error occurred during filtering. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error { - return it.fail - } - // Close terminates the iteration process, releasing any pending underlying - // resources. - func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error { - it.sub.Unsubscribe() - return nil - } - - // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract. - type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}} - {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}} - Raw types.Log // Blockchain specific contextual infos - } - - // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) { - {{range .Normalized.Inputs}} - {{if .Indexed}}var {{.Name}}Rule []interface{} - for _, {{.Name}}Item := range {{.Name}} { - {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) - }{{end}}{{end}} - - logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) - if err != nil { - return nil, err - } - return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil - } - - // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) { - {{range .Normalized.Inputs}} - {{if .Indexed}}var {{.Name}}Rule []interface{} - for _, {{.Name}}Item := range {{.Name}} { - {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item) - }{{end}}{{end}} - - logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}}) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new({{$contract.Type}}{{.Normalized.Name}}) - if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil - } - - // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}. - // - // Solidity: {{.Original.String}} - func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { - event := new({{$contract.Type}}{{.Normalized.Name}}) - if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil - } - - {{end}} -{{end}} -` +// +//go:embed source.go.tpl +var tmplSourceGo string From 0cbaccd1066db6d963ce92f5dea22927ab05ab44 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 271/280] accounts/keystore: simplify tests using t.TempDir() (#30150) --- accounts/keystore/account_cache_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 12dab2a53b..a35cc478c0 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -114,7 +114,7 @@ func TestWatchNewFile(t *testing.T) { func TestWatchNoDir(t *testing.T) { t.Parallel() // Create ks but not the directory that it watches. - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) + dir := filepath.Join(t.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) ks := NewKeyStore(dir, LightScryptN, LightScryptP) list := ks.Accounts() if len(list) > 0 { @@ -126,7 +126,6 @@ func TestWatchNoDir(t *testing.T) { } // Create the directory and copy a key file into it. os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) file := filepath.Join(dir, "aaa") if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil { t.Fatal(err) From 5beff83a6db57013b36efdc40a1ca25803ec1847 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 272/280] all: remove deprecated protobuf dependencies (#30232) The package `github.com/golang/protobuf/proto` is deprecated in favor `google.golang.org/protobuf/proto`. We should update the codes to recommended package. Signed-off-by: Icarus Wu --- accounts/usbwallet/trezor.go | 2 +- accounts/usbwallet/trezor/trezor.go | 6 +++--- go.mod | 1 - go.sum | 3 --- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index 52ca4b2d83..b9fd80c58f 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -34,7 +34,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/log" - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In diff --git a/accounts/usbwallet/trezor/trezor.go b/accounts/usbwallet/trezor/trezor.go index 4697156ce0..01d0b3e84a 100644 --- a/accounts/usbwallet/trezor/trezor.go +++ b/accounts/usbwallet/trezor/trezor.go @@ -39,8 +39,8 @@ // - Download the latest protoc https://github.com/protocolbuffers/protobuf/releases // - Build with the usual `./configure && make` and ensure it's on your $PATH // - Delete all the .proto and .pb.go files, pull in fresh ones from Trezor -// - Grab the latest Go plugin `go get -u github.com/golang/protobuf/protoc-gen-go` -// - Vendor in the latest Go plugin `govendor fetch github.com/golang/protobuf/...` +// - Grab the latest Go plugin `go get -u google.golang.org/protobuf/cmd/protoc-gen-go` +// - Vendor in the latest Go plugin `govendor fetch google.golang.org/protobuf/...` //go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto @@ -50,7 +50,7 @@ package trezor import ( "reflect" - "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/proto" ) // Type returns the protocol buffer type number of a specific message. If the diff --git a/go.mod b/go.mod index d95af86f6a..02275b383f 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,6 @@ require ( github.com/edsrzf/mmap-go v1.0.0 github.com/fatih/color v1.13.0 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 - github.com/golang/protobuf v1.5.3 github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/gorilla/websocket v1.4.2 github.com/holiman/uint256 v1.2.4 diff --git a/go.sum b/go.sum index 1693b7fa7e..7a8de51c4f 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -293,7 +291,6 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From c6a8f7970253049f3966542d242ccb1bb44503cc Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 273/280] accounts/abi/bind: add accessList support to base bond contract (#30195) Adding the correct accessList parameter when calling a contract can reduce gas consumption. However, the current version only allows adding the accessList manually when constructing the transaction. This PR can provide convenience for saving gas. --- accounts/abi/bind/base.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index f1bdfbbd33..4c239ba4ee 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -59,11 +59,12 @@ type TransactOpts struct { Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state) Signer SignerFn // Method to use for signing the transaction (mandatory) - Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds) - GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) - GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle) - GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle) - GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) + Value *big.Int // Funds to transfer along the transaction (nil = 0 = no funds) + GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle) + GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle) + GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle) + GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate) + AccessList types.AccessList // Access list to set for the transaction execution (nil = no access list) Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) @@ -300,20 +301,21 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add return nil, err } baseTx := &types.DynamicFeeTx{ - To: contract, - Nonce: nonce, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Gas: gasLimit, - Value: value, - Data: input, + To: contract, + Nonce: nonce, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Gas: gasLimit, + Value: value, + Data: input, + AccessList: opts.AccessList, } return types.NewTx(baseTx), nil } func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) { - if opts.GasFeeCap != nil || opts.GasTipCap != nil { - return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but EIP-1559 is not active yet") + if opts.GasFeeCap != nil || opts.GasTipCap != nil || opts.AccessList != nil { + return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas or accessList specified but EIP-1559 is not active yet") } // Normalize value value := opts.Value From 11d3afd84957c8d33b926f2345c1c33214235269 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 274/280] accounts/abi: handle ABIs with contract type parameter (#30315) convert parameter of type contract to the basic `address` type --------- Co-authored-by: Martin HS --- accounts/abi/abi_test.go | 7 +++++++ accounts/abi/type.go | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 263738b318..bda27380ed 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1219,3 +1219,10 @@ func TestUnpackRevert(t *testing.T) { }) } } + +func TestInternalContractType(t *testing.T) { + jsonData := `[{"inputs":[{"components":[{"internalType":"uint256","name":"dailyLimit","type":"uint256"},{"internalType":"uint256","name":"txLimit","type":"uint256"},{"internalType":"uint256","name":"accountDailyLimit","type":"uint256"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bool","name":"onlyWhitelisted","type":"bool"}],"internalType":"struct IMessagePassingBridge.BridgeLimits","name":"bridgeLimits","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.AccountLimit","name":"accountDailyLimit","type":"tuple"},{"components":[{"internalType":"uint256","name":"lastTransferReset","type":"uint256"},{"internalType":"uint256","name":"bridged24Hours","type":"uint256"}],"internalType":"struct IMessagePassingBridge.BridgeDailyLimit","name":"bridgeDailyLimit","type":"tuple"},{"internalType":"contract INameService","name":"nameService","type":"INameService"},{"internalType":"bool","name":"isClosed","type":"bool"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"canBridge","outputs":[{"internalType":"bool","name":"isWithinLimit","type":"bool"},{"internalType":"string","name":"error","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFrom18ToTokenDecimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"name":"normalizeFromTokenTo18Decimals","outputs":[{"internalType":"uint256","name":"normalized","type":"uint256"}],"stateMutability":"pure","type":"function"}]` + if _, err := JSON(strings.NewReader(jsonData)); err != nil { + t.Fatal(err) + } +} diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 55b4735ef7..b19a1b8e77 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -218,7 +218,12 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty typ.T = FunctionTy typ.Size = 24 default: - return Type{}, fmt.Errorf("unsupported arg type: %s", t) + if strings.HasPrefix(internalType, "contract ") { + typ.Size = 20 + typ.T = AddressTy + } else { + return Type{}, fmt.Errorf("unsupported arg type: %s", t) + } } return From ced65923dbf426f378189a8d9b24d71492483c04 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 275/280] accounts/abi/bind: check SendTransaction error in tests (#30349) In few tests the returned error from `SendTransaction` is not being checked. This PR checks the returned err in tests. Returning errors also revealed tx in `TestCommitReturnValue` is not actually being sent, and returns err ` only replay-protected (EIP-155) transactions allowed over RPC`. Fixed the transaction by using the `testTx` function. --- accounts/abi/bind/backends/simulated_test.go | 20 ++++++++++++++++---- accounts/abi/bind/util_test.go | 12 +++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 187582fd89..62b72cbccc 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -1376,29 +1376,38 @@ func TestForkResendTx(t *testing.T) { defer sim.Close() // 1. parent := sim.blockchain.CurrentBlock() + // 2. head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) - _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) - tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) - sim.SendTransaction(context.Background(), tx) + tx, err := types.SignTx(_tx, types.HomesteadSigner{}, testKey) + if err != nil { + t.Fatalf("could not sign transaction: %v", err) + } + if err = sim.SendTransaction(context.Background(), tx); err != nil { + t.Fatalf("sending transaction: %v", err) + } sim.Commit() + // 3. receipt, _ := sim.TransactionReceipt(context.Background(), tx.Hash()) if h := receipt.BlockNumber.Uint64(); h != 1 { t.Errorf("TX included in wrong block: %d", h) } + // 4. if err := sim.Fork(context.Background(), parent.Hash()); err != nil { t.Errorf("forking: %v", err) } + // 5. sim.Commit() if err := sim.SendTransaction(context.Background(), tx); err != nil { t.Errorf("sending transaction: %v", err) } sim.Commit() + // 6. receipt, _ = sim.TransactionReceipt(context.Background(), tx.Hash()) if h := receipt.BlockNumber.Uint64(); h != 2 { @@ -1425,7 +1434,10 @@ func TestCommitReturnValue(t *testing.T) { gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) - sim.SendTransaction(context.Background(), tx) + if err := sim.SendTransaction(context.Background(), tx); err != nil { + t.Errorf("sending transaction: %v", err) + } + h2 := sim.Commit() // Create another block in the original chain diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 89deb2c559..839d31cb73 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -86,7 +86,9 @@ func TestWaitDeployed(t *testing.T) { }() // Send and mine the transaction. - backend.SendTransaction(ctx, tx) + if err := backend.SendTransaction(ctx, tx); err != nil { + t.Errorf("test %q: failed to send transaction: %v", name, err) + } backend.Commit() select { @@ -125,7 +127,9 @@ func TestWaitDeployedCornerCases(t *testing.T) { tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - backend.SendTransaction(ctx, tx) + if err := backend.SendTransaction(ctx, tx); err != nil { + t.Errorf("failed to send transaction: %q", err) + } backend.Commit() notContractCreation := errors.New("tx is not contract creation") if _, err := bind.WaitDeployed(ctx, backend, tx); err.Error() != notContractCreation.Error() { @@ -143,6 +147,8 @@ func TestWaitDeployedCornerCases(t *testing.T) { } }() - backend.SendTransaction(ctx, tx) + if err := backend.SendTransaction(ctx, tx); err != nil { + t.Errorf("failed to send transaction: %q", err) + } cancel() } From 72e5ee7f172d8c7bd262b5171811790a4ea2b9fa Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 276/280] accounts/abi: golangci-lint 1.61.0 (#30587) --- accounts/abi/abi_test.go | 1 - accounts/abi/bind/bind.go | 2 +- accounts/abi/event_test.go | 1 - accounts/abi/pack_test.go | 1 - accounts/abi/reflect_test.go | 1 - accounts/abi/topics_test.go | 3 --- accounts/abi/unpack_test.go | 1 - 7 files changed, 1 insertion(+), 9 deletions(-) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index bda27380ed..cbac74d4fb 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -1200,7 +1200,6 @@ func TestUnpackRevert(t *testing.T) { {"4e487b7100000000000000000000000000000000000000000000000000000000000000ff", "unknown panic code: 0xff", nil}, } for index, c := range cases { - index, c := index, c t.Run(fmt.Sprintf("case %d", index), func(t *testing.T) { t.Parallel() got, err := UnpackRevert(common.Hex2Bytes(c.input)) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 92fd330406..f5c6cbab98 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -253,7 +253,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string] } // Parse library references. for pattern, name := range libs { - matched, err := regexp.Match("__\\$"+pattern+"\\$__", []byte(contracts[types[i]].InputBin)) + matched, err := regexp.MatchString("__\\$"+pattern+"\\$__", contracts[types[i]].InputBin) if err != nil { log.Error("Could not search for pattern", "pattern", pattern, "contract", contracts[types[i]], "err", err) } diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index ed22bf9905..f36d7db5ec 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -331,7 +331,6 @@ func TestEventTupleUnpack(t *testing.T) { for _, tc := range testCases { assert := assert.New(t) - tc := tc t.Run(tc.name, func(t *testing.T) { err := unpackTestEventData(tc.dest, tc.data, tc.jsonLog, assert) if tc.error == "" { diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index 90f1348c50..6abc3c8a18 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -34,7 +34,6 @@ import ( func TestPack(t *testing.T) { t.Parallel() for i, test := range packUnpackTests { - i, test := i, test t.Run(strconv.Itoa(i), func(t *testing.T) { t.Parallel() encb, err := hex.DecodeString(test.packed) diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index 6c7ae57087..577fa6ca71 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -172,7 +172,6 @@ var reflectTests = []reflectTest{ func TestReflectNameToStruct(t *testing.T) { t.Parallel() for _, test := range reflectTests { - test := test t.Run(test.name, func(t *testing.T) { t.Parallel() m, err := mapArgNamesToStructFields(test.args, reflect.ValueOf(test.struc)) diff --git a/accounts/abi/topics_test.go b/accounts/abi/topics_test.go index 4f97cf7155..8cc509ad86 100644 --- a/accounts/abi/topics_test.go +++ b/accounts/abi/topics_test.go @@ -137,7 +137,6 @@ func TestMakeTopics(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() got, err := MakeTopics(tt.args.query...) @@ -373,7 +372,6 @@ func TestParseTopics(t *testing.T) { tests := setupTopicsTests() for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() createObj := tt.args.createObj() @@ -393,7 +391,6 @@ func TestParseTopicsIntoMap(t *testing.T) { tests := setupTopicsTests() for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() outMap := make(map[string]interface{}) diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index 31f2067baa..e0d3bfc6d7 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -389,7 +389,6 @@ func TestMethodMultiReturn(t *testing.T) { "Can not unpack into a slice with wrong types", }} for _, tc := range testCases { - tc := tc t.Run(tc.name, func(t *testing.T) { require := require.New(t) err := abi.UnpackIntoInterface(tc.dest, "multi", data) From db3dc1932c51e26f73215376654274dee7c2946f Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 277/280] accounts/usbwallet: support dynamic tx (#30180) Adds support non-legacy transaction-signing using ledger --------- Co-authored-by: Martin Holst Swende --- accounts/usbwallet/ledger.go | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index c10eec5e0e..9b9a4671d3 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -338,8 +338,22 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction return common.Address{}, nil, err } } else { - if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil { - return common.Address{}, nil, err + if tx.Type() == types.DynamicFeeTxType { + if txrlp, err = rlp.EncodeToBytes([]interface{}{chainID, tx.Nonce(), tx.GasTipCap(), tx.GasFeeCap(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), tx.AccessList()}); err != nil { + return common.Address{}, nil, err + } + // append type to transaction + txrlp = append([]byte{tx.Type()}, txrlp...) + } else if tx.Type() == types.AccessListTxType { + if txrlp, err = rlp.EncodeToBytes([]interface{}{chainID, tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), tx.AccessList()}); err != nil { + return common.Address{}, nil, err + } + // append type to transaction + txrlp = append([]byte{tx.Type()}, txrlp...) + } else if tx.Type() == types.LegacyTxType { + if txrlp, err = rlp.EncodeToBytes([]interface{}{tx.Nonce(), tx.GasPrice(), tx.Gas(), tx.To(), tx.Value(), tx.Data(), chainID, big.NewInt(0), big.NewInt(0)}); err != nil { + return common.Address{}, nil, err + } } } payload := append(path, txrlp...) @@ -353,7 +367,9 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction // Chunk size selection to mitigate an underlying RLP deserialization issue on the ledger app. // https://github.com/LedgerHQ/app-ethereum/issues/409 chunk := 255 - for ; len(payload)%chunk <= ledgerEip155Size; chunk-- { + if tx.Type() == types.LegacyTxType { + for ; len(payload)%chunk <= ledgerEip155Size; chunk-- { + } } for len(payload) > 0 { @@ -381,8 +397,11 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction if chainID == nil { signer = new(types.HomesteadSigner) } else { - signer = types.NewEIP155Signer(chainID) - signature[crypto.RecoveryIDOffset] -= byte(chainID.Uint64()*2 + 35) + signer = types.LatestSignerForChainID(chainID) + // For non-legacy transactions, V is 0 or 1, no need to subtract here. + if tx.Type() == types.LegacyTxType { + signature[64] -= byte(chainID.Uint64()*2 + 35) + } } signed, err := tx.WithSignature(signer, signature) if err != nil { From aa164fbbc102d8e3bde9c6b47b9f0c830e514830 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 278/280] accounts/abi: fix MakeTopics mutation of big.Int inputs (#30785) However, it also changed the behavior of the function from just _reading_ the input `*big.Int` via `Bytes()`, to leveraging `big.U256Bytes` which is documented as being _destructive_: This change updates `MakeTopics` to not mutate the original, and also applies the same change in signer/core/apitypes. --- accounts/abi/topics.go | 2 +- accounts/abi/topics_test.go | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/accounts/abi/topics.go b/accounts/abi/topics.go index 4f347ac0ce..9df7042c8e 100644 --- a/accounts/abi/topics.go +++ b/accounts/abi/topics.go @@ -42,7 +42,7 @@ func MakeTopics(query ...[]interface{}) ([][]common.Hash, error) { case common.Address: copy(topic[common.HashLength-common.AddressLength:], rule[:]) case *big.Int: - copy(topic[:], math.U256Bytes(rule)) + copy(topic[:], math.U256Bytes(new(big.Int).Set(rule))) case bool: if rule { topic[common.HashLength-1] = 1 diff --git a/accounts/abi/topics_test.go b/accounts/abi/topics_test.go index 8cc509ad86..3a81b89f6c 100644 --- a/accounts/abi/topics_test.go +++ b/accounts/abi/topics_test.go @@ -149,6 +149,23 @@ func TestMakeTopics(t *testing.T) { } }) } + + t.Run("does not mutate big.Int", func(t *testing.T) { + t.Parallel() + want := [][]common.Hash{{common.HexToHash("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")}} + + in := big.NewInt(-1) + got, err := MakeTopics([]interface{}{in}) + if err != nil { + t.Fatalf("makeTopics() error = %v", err) + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("makeTopics() = %v, want %v", got, want) + } + if orig := big.NewInt(-1); in.Cmp(orig) != 0 { + t.Fatalf("makeTopics() mutated an input parameter from %v to %v", orig, in) + } + }) } type args struct { From 6f37e85e80ba177a1d38abb34343cdc9811631ae Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 279/280] accounts/abi: support unpacking solidity errors (#30738) This PR adds the error fragments to `func (abi ABI) getArguments` which allows typed decoding of errors. --- accounts/abi/abi.go | 7 ++++-- accounts/abi/abi_test.go | 33 ++++++++++++++++++++++++ internal/testrand/rand.go | 53 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 internal/testrand/rand.go diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index a0f63518ab..9e95065b4c 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -84,7 +84,7 @@ func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) { func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { // since there can't be naming collisions with contracts and events, - // we need to decide whether we're calling a method or an event + // we need to decide whether we're calling a method, event or an error var args Arguments if method, ok := abi.Methods[name]; ok { if len(data)%32 != 0 { @@ -95,8 +95,11 @@ func (abi ABI) getArguments(name string, data []byte) (Arguments, error) { if event, ok := abi.Events[name]; ok { args = event.Inputs } + if err, ok := abi.Errors[name]; ok { + args = err.Inputs + } if args == nil { - return nil, fmt.Errorf("abi: could not locate named method or event: %s", name) + return nil, fmt.Errorf("abi: could not locate named method, event or error: %s", name) } return args, nil } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index cbac74d4fb..2df0a3806b 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/crypto" + "github.com/XinFinOrg/XDPoSChain/internal/testrand" ) const jsondata = ` @@ -317,6 +318,38 @@ func TestCustomErrors(t *testing.T) { check("MyError", "MyError(uint256)") } +func TestCustomErrorUnpackIntoInterface(t *testing.T) { + t.Parallel() + errorName := "MyError" + json := fmt.Sprintf(`[{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"%s","type":"error"}]`, errorName) + abi, err := JSON(strings.NewReader(json)) + if err != nil { + t.Fatal(err) + } + type MyError struct { + Sender common.Address + Balance *big.Int + } + + sender := testrand.Address() + balance := new(big.Int).SetBytes(testrand.Bytes(8)) + encoded, err := abi.Errors[errorName].Inputs.Pack(sender, balance) + if err != nil { + t.Fatal(err) + } + result := MyError{} + err = abi.UnpackIntoInterface(&result, errorName, encoded) + if err != nil { + t.Fatal(err) + } + if result.Sender != sender { + t.Errorf("expected %x got %x", sender, result.Sender) + } + if result.Balance.Cmp(balance) != 0 { + t.Errorf("expected %v got %v", balance, result.Balance) + } +} + func TestMultiPack(t *testing.T) { t.Parallel() abi, err := JSON(strings.NewReader(jsondata)) diff --git a/internal/testrand/rand.go b/internal/testrand/rand.go new file mode 100644 index 0000000000..895e783b55 --- /dev/null +++ b/internal/testrand/rand.go @@ -0,0 +1,53 @@ +// Copyright 2023 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 . + +package testrand + +import ( + crand "crypto/rand" + "encoding/binary" + mrand "math/rand" + + "github.com/XinFinOrg/XDPoSChain/common" +) + +// prng is a pseudo random number generator seeded by strong randomness. +// The randomness is printed on startup in order to make failures reproducible. +var prng = initRand() + +func initRand() *mrand.Rand { + var seed [8]byte + crand.Read(seed[:]) + rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) + return rnd +} + +// Bytes generates a random byte slice with specified length. +func Bytes(n int) []byte { + r := make([]byte, n) + prng.Read(r) + return r +} + +// Hash generates a random hash. +func Hash() common.Hash { + return common.BytesToHash(Bytes(common.HashLength)) +} + +// Address generates a random address. +func Address() common.Address { + return common.BytesToAddress(Bytes(common.AddressLength)) +} From a8a96a804f7185981704fafe20043254a02de7e4 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:17 +0800 Subject: [PATCH 280/280] accounts/abi/bind: make it possible to wait for tx hash (#30079) This change adds methods which makes it possible for to wait for a transaction with a specific hash when deploying contracts during abi bind interaction. --------- Co-authored-by: Marius van der Wijden --- accounts/abi/bind/util.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go index 0b16b6764c..4de3e3596b 100644 --- a/accounts/abi/bind/util.go +++ b/accounts/abi/bind/util.go @@ -30,12 +30,18 @@ import ( // WaitMined waits for tx to be mined on the blockchain. // It stops waiting when the context is canceled. func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { + return WaitMinedHash(ctx, b, tx.Hash()) +} + +// WaitMinedHash waits for a transaction with the provided hash to be mined on the blockchain. +// It stops waiting when the context is canceled. +func WaitMinedHash(ctx context.Context, b DeployBackend, hash common.Hash) (*types.Receipt, error) { queryTicker := time.NewTicker(time.Second) defer queryTicker.Stop() - logger := log.New("hash", tx.Hash()) + logger := log.New("hash", hash) for { - receipt, err := b.TransactionReceipt(ctx, tx.Hash()) + receipt, err := b.TransactionReceipt(ctx, hash) if err == nil { return receipt, nil } @@ -61,7 +67,13 @@ func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) ( if tx.To() != nil { return common.Address{}, errors.New("tx is not contract creation") } - receipt, err := WaitMined(ctx, b, tx) + return WaitDeployedHash(ctx, b, tx.Hash()) +} + +// WaitDeployedHash waits for a contract deployment transaction with the provided hash and returns the on-chain +// contract address when it is mined. It stops waiting when ctx is canceled. +func WaitDeployedHash(ctx context.Context, b DeployBackend, hash common.Hash) (common.Address, error) { + receipt, err := WaitMinedHash(ctx, b, hash) if err != nil { return common.Address{}, err }