github.com/dominant-strategies/go-quai@v0.28.2/rlp/encode_test.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package rlp 18 19 import ( 20 "bytes" 21 "errors" 22 "fmt" 23 "io" 24 "io/ioutil" 25 "math/big" 26 "runtime" 27 "sync" 28 "testing" 29 30 "github.com/dominant-strategies/go-quai/common/math" 31 ) 32 33 type testEncoder struct { 34 err error 35 } 36 37 func (e *testEncoder) EncodeRLP(w io.Writer) error { 38 if e == nil { 39 panic("EncodeRLP called on nil value") 40 } 41 if e.err != nil { 42 return e.err 43 } 44 w.Write([]byte{0, 1, 0, 1, 0, 1, 0, 1, 0, 1}) 45 return nil 46 } 47 48 type testEncoderValueMethod struct{} 49 50 func (e testEncoderValueMethod) EncodeRLP(w io.Writer) error { 51 w.Write([]byte{0xFA, 0xFE, 0xF0}) 52 return nil 53 } 54 55 type byteEncoder byte 56 57 func (e byteEncoder) EncodeRLP(w io.Writer) error { 58 w.Write(EmptyList) 59 return nil 60 } 61 62 type undecodableEncoder func() 63 64 func (f undecodableEncoder) EncodeRLP(w io.Writer) error { 65 w.Write([]byte{0xF5, 0xF5, 0xF5}) 66 return nil 67 } 68 69 type encodableReader struct { 70 A, B uint 71 } 72 73 func (e *encodableReader) Read(b []byte) (int, error) { 74 panic("called") 75 } 76 77 type namedByteType byte 78 79 var ( 80 _ = Encoder(&testEncoder{}) 81 _ = Encoder(byteEncoder(0)) 82 83 reader io.Reader = &encodableReader{1, 2} 84 ) 85 86 type encTest struct { 87 val interface{} 88 output, error string 89 } 90 91 var encTests = []encTest{ 92 // booleans 93 {val: true, output: "01"}, 94 {val: false, output: "80"}, 95 96 // integers 97 {val: uint32(0), output: "80"}, 98 {val: uint32(127), output: "7F"}, 99 {val: uint32(128), output: "8180"}, 100 {val: uint32(256), output: "820100"}, 101 {val: uint32(1024), output: "820400"}, 102 {val: uint32(0xFFFFFF), output: "83FFFFFF"}, 103 {val: uint32(0xFFFFFFFF), output: "84FFFFFFFF"}, 104 {val: uint64(0xFFFFFFFF), output: "84FFFFFFFF"}, 105 {val: uint64(0xFFFFFFFFFF), output: "85FFFFFFFFFF"}, 106 {val: uint64(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"}, 107 {val: uint64(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"}, 108 {val: uint64(0xFFFFFFFFFFFFFFFF), output: "88FFFFFFFFFFFFFFFF"}, 109 110 // big integers (should match uint for small values) 111 {val: big.NewInt(0), output: "80"}, 112 {val: big.NewInt(1), output: "01"}, 113 {val: big.NewInt(127), output: "7F"}, 114 {val: big.NewInt(128), output: "8180"}, 115 {val: big.NewInt(256), output: "820100"}, 116 {val: big.NewInt(1024), output: "820400"}, 117 {val: big.NewInt(0xFFFFFF), output: "83FFFFFF"}, 118 {val: big.NewInt(0xFFFFFFFF), output: "84FFFFFFFF"}, 119 {val: big.NewInt(0xFFFFFFFFFF), output: "85FFFFFFFFFF"}, 120 {val: big.NewInt(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"}, 121 {val: big.NewInt(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"}, 122 { 123 val: big.NewInt(0).SetBytes(unhex("102030405060708090A0B0C0D0E0F2")), 124 output: "8F102030405060708090A0B0C0D0E0F2", 125 }, 126 { 127 val: big.NewInt(0).SetBytes(unhex("0100020003000400050006000700080009000A000B000C000D000E01")), 128 output: "9C0100020003000400050006000700080009000A000B000C000D000E01", 129 }, 130 { 131 val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")), 132 output: "A1010000000000000000000000000000000000000000000000000000000000000000", 133 }, 134 { 135 val: veryBigInt, 136 output: "89FFFFFFFFFFFFFFFFFF", 137 }, 138 { 139 val: veryVeryBigInt, 140 output: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001", 141 }, 142 143 // non-pointer big.Int 144 {val: *big.NewInt(0), output: "80"}, 145 {val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"}, 146 147 // negative ints are not supported 148 {val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"}, 149 150 // byte arrays 151 {val: [0]byte{}, output: "80"}, 152 {val: [1]byte{0}, output: "00"}, 153 {val: [1]byte{1}, output: "01"}, 154 {val: [1]byte{0x7F}, output: "7F"}, 155 {val: [1]byte{0x80}, output: "8180"}, 156 {val: [1]byte{0xFF}, output: "81FF"}, 157 {val: [3]byte{1, 2, 3}, output: "83010203"}, 158 {val: [57]byte{1, 2, 3}, output: "B839010203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, 159 160 // named byte type arrays 161 {val: [0]namedByteType{}, output: "80"}, 162 {val: [1]namedByteType{0}, output: "00"}, 163 {val: [1]namedByteType{1}, output: "01"}, 164 {val: [1]namedByteType{0x7F}, output: "7F"}, 165 {val: [1]namedByteType{0x80}, output: "8180"}, 166 {val: [1]namedByteType{0xFF}, output: "81FF"}, 167 {val: [3]namedByteType{1, 2, 3}, output: "83010203"}, 168 {val: [57]namedByteType{1, 2, 3}, output: "B839010203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, 169 170 // byte slices 171 {val: []byte{}, output: "80"}, 172 {val: []byte{0}, output: "00"}, 173 {val: []byte{0x7E}, output: "7E"}, 174 {val: []byte{0x7F}, output: "7F"}, 175 {val: []byte{0x80}, output: "8180"}, 176 {val: []byte{1, 2, 3}, output: "83010203"}, 177 178 // named byte type slices 179 {val: []namedByteType{}, output: "80"}, 180 {val: []namedByteType{0}, output: "00"}, 181 {val: []namedByteType{0x7E}, output: "7E"}, 182 {val: []namedByteType{0x7F}, output: "7F"}, 183 {val: []namedByteType{0x80}, output: "8180"}, 184 {val: []namedByteType{1, 2, 3}, output: "83010203"}, 185 186 // strings 187 {val: "", output: "80"}, 188 {val: "\x7E", output: "7E"}, 189 {val: "\x7F", output: "7F"}, 190 {val: "\x80", output: "8180"}, 191 {val: "dog", output: "83646F67"}, 192 { 193 val: "Lorem ipsum dolor sit amet, consectetur adipisicing eli", 194 output: "B74C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C69", 195 }, 196 { 197 val: "Lorem ipsum dolor sit amet, consectetur adipisicing elit", 198 output: "B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974", 199 }, 200 { 201 val: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat", 202 output: "B904004C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742E20437572616269747572206D6175726973206D61676E612C20737573636970697420736564207665686963756C61206E6F6E2C20696163756C697320666175636962757320746F72746F722E2050726F696E20737573636970697420756C74726963696573206D616C6573756164612E204475697320746F72746F7220656C69742C2064696374756D2071756973207472697374697175652065752C20756C7472696365732061742072697375732E204D6F72626920612065737420696D70657264696574206D6920756C6C616D636F7270657220616C6971756574207375736369706974206E6563206C6F72656D2E2041656E65616E2071756973206C656F206D6F6C6C69732C2076756C70757461746520656C6974207661726975732C20636F6E73657175617420656E696D2E204E756C6C6120756C74726963657320747572706973206A7573746F2C20657420706F73756572652075726E6120636F6E7365637465747572206E65632E2050726F696E206E6F6E20636F6E76616C6C6973206D657475732E20446F6E65632074656D706F7220697073756D20696E206D617572697320636F6E67756520736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E646973736520636F6E76616C6C69732073656D2076656C206D617373612066617563696275732C2065676574206C6163696E6961206C616375732074656D706F722E204E756C6C61207175697320756C747269636965732070757275732E2050726F696E20617563746F722072686F6E637573206E69626820636F6E64696D656E74756D206D6F6C6C69732E20416C697175616D20636F6E73657175617420656E696D206174206D65747573206C75637475732C206120656C656966656E6420707572757320656765737461732E20437572616269747572206174206E696268206D657475732E204E616D20626962656E64756D2C206E6571756520617420617563746F72207472697374697175652C206C6F72656D206C696265726F20616C697175657420617263752C206E6F6E20696E74657264756D2074656C6C7573206C65637475732073697420616D65742065726F732E20437261732072686F6E6375732C206D65747573206163206F726E617265206375727375732C20646F6C6F72206A7573746F20756C747269636573206D657475732C20617420756C6C616D636F7270657220766F6C7574706174", 203 }, 204 205 // slices 206 {val: []uint{}, output: "C0"}, 207 {val: []uint{1, 2, 3}, output: "C3010203"}, 208 { 209 // [ [], [[]], [ [], [[]] ] ] 210 val: []interface{}{[]interface{}{}, [][]interface{}{{}}, []interface{}{[]interface{}{}, [][]interface{}{{}}}}, 211 output: "C7C0C1C0C3C0C1C0", 212 }, 213 { 214 val: []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo"}, 215 output: "F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F", 216 }, 217 { 218 val: []interface{}{uint(1), uint(0xFFFFFF), []interface{}{[]uint{4, 5, 5}}, "abc"}, 219 output: "CE0183FFFFFFC4C304050583616263", 220 }, 221 { 222 val: [][]string{ 223 {"asdf", "qwer", "zxcv"}, 224 {"asdf", "qwer", "zxcv"}, 225 {"asdf", "qwer", "zxcv"}, 226 {"asdf", "qwer", "zxcv"}, 227 {"asdf", "qwer", "zxcv"}, 228 {"asdf", "qwer", "zxcv"}, 229 {"asdf", "qwer", "zxcv"}, 230 {"asdf", "qwer", "zxcv"}, 231 {"asdf", "qwer", "zxcv"}, 232 {"asdf", "qwer", "zxcv"}, 233 {"asdf", "qwer", "zxcv"}, 234 {"asdf", "qwer", "zxcv"}, 235 {"asdf", "qwer", "zxcv"}, 236 {"asdf", "qwer", "zxcv"}, 237 {"asdf", "qwer", "zxcv"}, 238 {"asdf", "qwer", "zxcv"}, 239 {"asdf", "qwer", "zxcv"}, 240 {"asdf", "qwer", "zxcv"}, 241 {"asdf", "qwer", "zxcv"}, 242 {"asdf", "qwer", "zxcv"}, 243 {"asdf", "qwer", "zxcv"}, 244 {"asdf", "qwer", "zxcv"}, 245 {"asdf", "qwer", "zxcv"}, 246 {"asdf", "qwer", "zxcv"}, 247 {"asdf", "qwer", "zxcv"}, 248 {"asdf", "qwer", "zxcv"}, 249 {"asdf", "qwer", "zxcv"}, 250 {"asdf", "qwer", "zxcv"}, 251 {"asdf", "qwer", "zxcv"}, 252 {"asdf", "qwer", "zxcv"}, 253 {"asdf", "qwer", "zxcv"}, 254 {"asdf", "qwer", "zxcv"}, 255 }, 256 output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376", 257 }, 258 259 // RawValue 260 {val: RawValue(unhex("01")), output: "01"}, 261 {val: RawValue(unhex("82FFFF")), output: "82FFFF"}, 262 {val: []RawValue{unhex("01"), unhex("02")}, output: "C20102"}, 263 264 // structs 265 {val: simplestruct{}, output: "C28080"}, 266 {val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"}, 267 {val: &recstruct{5, nil}, output: "C205C0"}, 268 {val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"}, 269 {val: &intField{X: 3}, error: "rlp: type int is not RLP-serializable (struct field rlp.intField.X)"}, 270 271 // struct tag "-" 272 {val: &ignoredField{A: 1, B: 2, C: 3}, output: "C20103"}, 273 274 // struct tag "tail" 275 {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02"), unhex("03")}}, output: "C3010203"}, 276 {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"}, 277 {val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"}, 278 {val: &tailRaw{A: 1, Tail: nil}, output: "C101"}, 279 280 // struct tag "optional" 281 {val: &optionalFields{}, output: "C180"}, 282 {val: &optionalFields{A: 1}, output: "C101"}, 283 {val: &optionalFields{A: 1, B: 2}, output: "C20102"}, 284 {val: &optionalFields{A: 1, B: 2, C: 3}, output: "C3010203"}, 285 {val: &optionalFields{A: 1, B: 0, C: 3}, output: "C3018003"}, 286 {val: &optionalAndTailField{A: 1}, output: "C101"}, 287 {val: &optionalAndTailField{A: 1, B: 2}, output: "C20102"}, 288 {val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"}, 289 {val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"}, 290 {val: &optionalBigIntField{A: 1}, output: "C101"}, 291 {val: &optionalPtrField{A: 1}, output: "C101"}, 292 {val: &optionalPtrFieldNil{A: 1}, output: "C101"}, 293 294 // nil 295 {val: (*uint)(nil), output: "80"}, 296 {val: (*string)(nil), output: "80"}, 297 {val: (*[]byte)(nil), output: "80"}, 298 {val: (*[10]byte)(nil), output: "80"}, 299 {val: (*big.Int)(nil), output: "80"}, 300 {val: (*[]string)(nil), output: "C0"}, 301 {val: (*[10]string)(nil), output: "C0"}, 302 {val: (*[]interface{})(nil), output: "C0"}, 303 {val: (*[]struct{ uint })(nil), output: "C0"}, 304 {val: (*interface{})(nil), output: "C0"}, 305 306 // nil struct fields 307 { 308 val: struct { 309 X *[]byte 310 }{}, 311 output: "C180", 312 }, 313 { 314 val: struct { 315 X *[2]byte 316 }{}, 317 output: "C180", 318 }, 319 { 320 val: struct { 321 X *uint64 322 }{}, 323 output: "C180", 324 }, 325 { 326 val: struct { 327 X *uint64 `rlp:"nilList"` 328 }{}, 329 output: "C1C0", 330 }, 331 { 332 val: struct { 333 X *[]uint64 334 }{}, 335 output: "C1C0", 336 }, 337 { 338 val: struct { 339 X *[]uint64 `rlp:"nilString"` 340 }{}, 341 output: "C180", 342 }, 343 344 // interfaces 345 {val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct 346 347 // Encoder 348 {val: (*testEncoder)(nil), output: "C0"}, 349 {val: &testEncoder{}, output: "00010001000100010001"}, 350 {val: &testEncoder{errors.New("test error")}, error: "test error"}, 351 {val: struct{ E testEncoderValueMethod }{}, output: "C3FAFEF0"}, 352 {val: struct{ E *testEncoderValueMethod }{}, output: "C1C0"}, 353 354 // Verify that the Encoder interface works for unsupported types like func(). 355 {val: undecodableEncoder(func() {}), output: "F5F5F5"}, 356 357 // Verify that pointer method testEncoder.EncodeRLP is called for 358 // addressable non-pointer values. 359 {val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"}, 360 {val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"}, 361 362 // Verify the error for non-addressable non-pointer Encoder. 363 {val: testEncoder{}, error: "rlp: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"}, 364 365 // Verify Encoder takes precedence over []byte. 366 {val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"}, 367 } 368 369 func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) { 370 for i, test := range encTests { 371 output, err := f(test.val) 372 if err != nil && test.error == "" { 373 t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T", 374 i, err, test.val, test.val) 375 continue 376 } 377 if test.error != "" && fmt.Sprint(err) != test.error { 378 t.Errorf("test %d: error mismatch\ngot %v\nwant %v\nvalue %#v\ntype %T", 379 i, err, test.error, test.val, test.val) 380 continue 381 } 382 if err == nil && !bytes.Equal(output, unhex(test.output)) { 383 t.Errorf("test %d: output mismatch:\ngot %X\nwant %s\nvalue %#v\ntype %T", 384 i, output, test.output, test.val, test.val) 385 } 386 } 387 } 388 389 func TestEncode(t *testing.T) { 390 runEncTests(t, func(val interface{}) ([]byte, error) { 391 b := new(bytes.Buffer) 392 err := Encode(b, val) 393 return b.Bytes(), err 394 }) 395 } 396 397 func TestEncodeToBytes(t *testing.T) { 398 runEncTests(t, EncodeToBytes) 399 } 400 401 func TestEncodeToReader(t *testing.T) { 402 runEncTests(t, func(val interface{}) ([]byte, error) { 403 _, r, err := EncodeToReader(val) 404 if err != nil { 405 return nil, err 406 } 407 return ioutil.ReadAll(r) 408 }) 409 } 410 411 func TestEncodeToReaderPiecewise(t *testing.T) { 412 runEncTests(t, func(val interface{}) ([]byte, error) { 413 size, r, err := EncodeToReader(val) 414 if err != nil { 415 return nil, err 416 } 417 418 // read output piecewise 419 output := make([]byte, size) 420 for start, end := 0, 0; start < size; start = end { 421 if remaining := size - start; remaining < 3 { 422 end += remaining 423 } else { 424 end = start + 3 425 } 426 n, err := r.Read(output[start:end]) 427 end = start + n 428 if err == io.EOF { 429 break 430 } else if err != nil { 431 return nil, err 432 } 433 } 434 return output, nil 435 }) 436 } 437 438 // This is a regression test verifying that encReader 439 // returns its encbuf to the pool only once. 440 func TestEncodeToReaderReturnToPool(t *testing.T) { 441 buf := make([]byte, 50) 442 wg := new(sync.WaitGroup) 443 for i := 0; i < 5; i++ { 444 wg.Add(1) 445 go func() { 446 for i := 0; i < 1000; i++ { 447 _, r, _ := EncodeToReader("foo") 448 ioutil.ReadAll(r) 449 r.Read(buf) 450 r.Read(buf) 451 r.Read(buf) 452 r.Read(buf) 453 } 454 wg.Done() 455 }() 456 } 457 wg.Wait() 458 } 459 460 var sink interface{} 461 462 func BenchmarkIntsize(b *testing.B) { 463 for i := 0; i < b.N; i++ { 464 sink = intsize(0x12345678) 465 } 466 } 467 468 func BenchmarkPutint(b *testing.B) { 469 buf := make([]byte, 8) 470 for i := 0; i < b.N; i++ { 471 putint(buf, 0x12345678) 472 sink = buf 473 } 474 } 475 476 func BenchmarkEncodeBigInts(b *testing.B) { 477 ints := make([]*big.Int, 200) 478 for i := range ints { 479 ints[i] = math.BigPow(2, int64(i)) 480 } 481 out := bytes.NewBuffer(make([]byte, 0, 4096)) 482 b.ResetTimer() 483 b.ReportAllocs() 484 485 for i := 0; i < b.N; i++ { 486 out.Reset() 487 if err := Encode(out, ints); err != nil { 488 b.Fatal(err) 489 } 490 } 491 } 492 493 func BenchmarkEncodeConcurrentInterface(b *testing.B) { 494 type struct1 struct { 495 A string 496 B *big.Int 497 C [20]byte 498 } 499 value := []interface{}{ 500 uint(999), 501 &struct1{A: "hello", B: big.NewInt(0xFFFFFFFF)}, 502 [10]byte{1, 2, 3, 4, 5, 6}, 503 []string{"yeah", "yeah", "yeah"}, 504 } 505 506 var wg sync.WaitGroup 507 for cpu := 0; cpu < runtime.NumCPU(); cpu++ { 508 wg.Add(1) 509 go func() { 510 defer wg.Done() 511 512 var buffer bytes.Buffer 513 for i := 0; i < b.N; i++ { 514 buffer.Reset() 515 err := Encode(&buffer, value) 516 if err != nil { 517 panic(err) 518 } 519 } 520 }() 521 } 522 wg.Wait() 523 } 524 525 type byteArrayStruct struct { 526 A [20]byte 527 B [32]byte 528 C [32]byte 529 } 530 531 func BenchmarkEncodeByteArrayStruct(b *testing.B) { 532 var out bytes.Buffer 533 var value byteArrayStruct 534 535 b.ReportAllocs() 536 for i := 0; i < b.N; i++ { 537 out.Reset() 538 if err := Encode(&out, &value); err != nil { 539 b.Fatal(err) 540 } 541 } 542 }