github.com/titbtcqash/go-ethereum@v1.9.7/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 "sync" 27 "testing" 28 ) 29 30 type testEncoder struct { 31 err error 32 } 33 34 func (e *testEncoder) EncodeRLP(w io.Writer) error { 35 if e == nil { 36 panic("EncodeRLP called on nil value") 37 } 38 if e.err != nil { 39 return e.err 40 } else { 41 w.Write([]byte{0, 1, 0, 1, 0, 1, 0, 1, 0, 1}) 42 } 43 return nil 44 } 45 46 type testEncoderValueMethod struct{} 47 48 func (e testEncoderValueMethod) EncodeRLP(w io.Writer) error { 49 w.Write([]byte{0xFA, 0xFE, 0xF0}) 50 return nil 51 } 52 53 type byteEncoder byte 54 55 func (e byteEncoder) EncodeRLP(w io.Writer) error { 56 w.Write(EmptyList) 57 return nil 58 } 59 60 type undecodableEncoder func() 61 62 func (f undecodableEncoder) EncodeRLP(w io.Writer) error { 63 w.Write([]byte{0xF5, 0xF5, 0xF5}) 64 return nil 65 } 66 67 type encodableReader struct { 68 A, B uint 69 } 70 71 func (e *encodableReader) Read(b []byte) (int, error) { 72 panic("called") 73 } 74 75 type namedByteType byte 76 77 var ( 78 _ = Encoder(&testEncoder{}) 79 _ = Encoder(byteEncoder(0)) 80 81 reader io.Reader = &encodableReader{1, 2} 82 ) 83 84 type encTest struct { 85 val interface{} 86 output, error string 87 } 88 89 var encTests = []encTest{ 90 // booleans 91 {val: true, output: "01"}, 92 {val: false, output: "80"}, 93 94 // integers 95 {val: uint32(0), output: "80"}, 96 {val: uint32(127), output: "7F"}, 97 {val: uint32(128), output: "8180"}, 98 {val: uint32(256), output: "820100"}, 99 {val: uint32(1024), output: "820400"}, 100 {val: uint32(0xFFFFFF), output: "83FFFFFF"}, 101 {val: uint32(0xFFFFFFFF), output: "84FFFFFFFF"}, 102 {val: uint64(0xFFFFFFFF), output: "84FFFFFFFF"}, 103 {val: uint64(0xFFFFFFFFFF), output: "85FFFFFFFFFF"}, 104 {val: uint64(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"}, 105 {val: uint64(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"}, 106 {val: uint64(0xFFFFFFFFFFFFFFFF), output: "88FFFFFFFFFFFFFFFF"}, 107 108 // big integers (should match uint for small values) 109 {val: big.NewInt(0), output: "80"}, 110 {val: big.NewInt(1), output: "01"}, 111 {val: big.NewInt(127), output: "7F"}, 112 {val: big.NewInt(128), output: "8180"}, 113 {val: big.NewInt(256), output: "820100"}, 114 {val: big.NewInt(1024), output: "820400"}, 115 {val: big.NewInt(0xFFFFFF), output: "83FFFFFF"}, 116 {val: big.NewInt(0xFFFFFFFF), output: "84FFFFFFFF"}, 117 {val: big.NewInt(0xFFFFFFFFFF), output: "85FFFFFFFFFF"}, 118 {val: big.NewInt(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"}, 119 {val: big.NewInt(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"}, 120 { 121 val: big.NewInt(0).SetBytes(unhex("102030405060708090A0B0C0D0E0F2")), 122 output: "8F102030405060708090A0B0C0D0E0F2", 123 }, 124 { 125 val: big.NewInt(0).SetBytes(unhex("0100020003000400050006000700080009000A000B000C000D000E01")), 126 output: "9C0100020003000400050006000700080009000A000B000C000D000E01", 127 }, 128 { 129 val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")), 130 output: "A1010000000000000000000000000000000000000000000000000000000000000000", 131 }, 132 133 // non-pointer big.Int 134 {val: *big.NewInt(0), output: "80"}, 135 {val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"}, 136 137 // negative ints are not supported 138 {val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"}, 139 140 // byte slices, strings 141 {val: []byte{}, output: "80"}, 142 {val: []byte{0x7E}, output: "7E"}, 143 {val: []byte{0x7F}, output: "7F"}, 144 {val: []byte{0x80}, output: "8180"}, 145 {val: []byte{1, 2, 3}, output: "83010203"}, 146 147 {val: []namedByteType{1, 2, 3}, output: "83010203"}, 148 {val: [...]namedByteType{1, 2, 3}, output: "83010203"}, 149 150 {val: "", output: "80"}, 151 {val: "\x7E", output: "7E"}, 152 {val: "\x7F", output: "7F"}, 153 {val: "\x80", output: "8180"}, 154 {val: "dog", output: "83646F67"}, 155 { 156 val: "Lorem ipsum dolor sit amet, consectetur adipisicing eli", 157 output: "B74C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C69", 158 }, 159 { 160 val: "Lorem ipsum dolor sit amet, consectetur adipisicing elit", 161 output: "B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974", 162 }, 163 { 164 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", 165 output: "B904004C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742E20437572616269747572206D6175726973206D61676E612C20737573636970697420736564207665686963756C61206E6F6E2C20696163756C697320666175636962757320746F72746F722E2050726F696E20737573636970697420756C74726963696573206D616C6573756164612E204475697320746F72746F7220656C69742C2064696374756D2071756973207472697374697175652065752C20756C7472696365732061742072697375732E204D6F72626920612065737420696D70657264696574206D6920756C6C616D636F7270657220616C6971756574207375736369706974206E6563206C6F72656D2E2041656E65616E2071756973206C656F206D6F6C6C69732C2076756C70757461746520656C6974207661726975732C20636F6E73657175617420656E696D2E204E756C6C6120756C74726963657320747572706973206A7573746F2C20657420706F73756572652075726E6120636F6E7365637465747572206E65632E2050726F696E206E6F6E20636F6E76616C6C6973206D657475732E20446F6E65632074656D706F7220697073756D20696E206D617572697320636F6E67756520736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E646973736520636F6E76616C6C69732073656D2076656C206D617373612066617563696275732C2065676574206C6163696E6961206C616375732074656D706F722E204E756C6C61207175697320756C747269636965732070757275732E2050726F696E20617563746F722072686F6E637573206E69626820636F6E64696D656E74756D206D6F6C6C69732E20416C697175616D20636F6E73657175617420656E696D206174206D65747573206C75637475732C206120656C656966656E6420707572757320656765737461732E20437572616269747572206174206E696268206D657475732E204E616D20626962656E64756D2C206E6571756520617420617563746F72207472697374697175652C206C6F72656D206C696265726F20616C697175657420617263752C206E6F6E20696E74657264756D2074656C6C7573206C65637475732073697420616D65742065726F732E20437261732072686F6E6375732C206D65747573206163206F726E617265206375727375732C20646F6C6F72206A7573746F20756C747269636573206D657475732C20617420756C6C616D636F7270657220766F6C7574706174", 166 }, 167 168 // slices 169 {val: []uint{}, output: "C0"}, 170 {val: []uint{1, 2, 3}, output: "C3010203"}, 171 { 172 // [ [], [[]], [ [], [[]] ] ] 173 val: []interface{}{[]interface{}{}, [][]interface{}{{}}, []interface{}{[]interface{}{}, [][]interface{}{{}}}}, 174 output: "C7C0C1C0C3C0C1C0", 175 }, 176 { 177 val: []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo"}, 178 output: "F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F", 179 }, 180 { 181 val: []interface{}{uint(1), uint(0xFFFFFF), []interface{}{[]uint{4, 5, 5}}, "abc"}, 182 output: "CE0183FFFFFFC4C304050583616263", 183 }, 184 { 185 val: [][]string{ 186 {"asdf", "qwer", "zxcv"}, 187 {"asdf", "qwer", "zxcv"}, 188 {"asdf", "qwer", "zxcv"}, 189 {"asdf", "qwer", "zxcv"}, 190 {"asdf", "qwer", "zxcv"}, 191 {"asdf", "qwer", "zxcv"}, 192 {"asdf", "qwer", "zxcv"}, 193 {"asdf", "qwer", "zxcv"}, 194 {"asdf", "qwer", "zxcv"}, 195 {"asdf", "qwer", "zxcv"}, 196 {"asdf", "qwer", "zxcv"}, 197 {"asdf", "qwer", "zxcv"}, 198 {"asdf", "qwer", "zxcv"}, 199 {"asdf", "qwer", "zxcv"}, 200 {"asdf", "qwer", "zxcv"}, 201 {"asdf", "qwer", "zxcv"}, 202 {"asdf", "qwer", "zxcv"}, 203 {"asdf", "qwer", "zxcv"}, 204 {"asdf", "qwer", "zxcv"}, 205 {"asdf", "qwer", "zxcv"}, 206 {"asdf", "qwer", "zxcv"}, 207 {"asdf", "qwer", "zxcv"}, 208 {"asdf", "qwer", "zxcv"}, 209 {"asdf", "qwer", "zxcv"}, 210 {"asdf", "qwer", "zxcv"}, 211 {"asdf", "qwer", "zxcv"}, 212 {"asdf", "qwer", "zxcv"}, 213 {"asdf", "qwer", "zxcv"}, 214 {"asdf", "qwer", "zxcv"}, 215 {"asdf", "qwer", "zxcv"}, 216 {"asdf", "qwer", "zxcv"}, 217 {"asdf", "qwer", "zxcv"}, 218 }, 219 output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376", 220 }, 221 222 // RawValue 223 {val: RawValue(unhex("01")), output: "01"}, 224 {val: RawValue(unhex("82FFFF")), output: "82FFFF"}, 225 {val: []RawValue{unhex("01"), unhex("02")}, output: "C20102"}, 226 227 // structs 228 {val: simplestruct{}, output: "C28080"}, 229 {val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"}, 230 {val: &recstruct{5, nil}, output: "C205C0"}, 231 {val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"}, 232 {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02"), unhex("03")}}, output: "C3010203"}, 233 {val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"}, 234 {val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"}, 235 {val: &tailRaw{A: 1, Tail: nil}, output: "C101"}, 236 {val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"}, 237 {val: &intField{X: 3}, error: "rlp: type int is not RLP-serializable (struct field rlp.intField.X)"}, 238 239 // nil 240 {val: (*uint)(nil), output: "80"}, 241 {val: (*string)(nil), output: "80"}, 242 {val: (*[]byte)(nil), output: "80"}, 243 {val: (*[10]byte)(nil), output: "80"}, 244 {val: (*big.Int)(nil), output: "80"}, 245 {val: (*[]string)(nil), output: "C0"}, 246 {val: (*[10]string)(nil), output: "C0"}, 247 {val: (*[]interface{})(nil), output: "C0"}, 248 {val: (*[]struct{ uint })(nil), output: "C0"}, 249 {val: (*interface{})(nil), output: "C0"}, 250 251 // nil struct fields 252 { 253 val: struct { 254 X *[]byte 255 }{}, 256 output: "C180", 257 }, 258 { 259 val: struct { 260 X *[2]byte 261 }{}, 262 output: "C180", 263 }, 264 { 265 val: struct { 266 X *uint64 267 }{}, 268 output: "C180", 269 }, 270 { 271 val: struct { 272 X *uint64 `rlp:"nilList"` 273 }{}, 274 output: "C1C0", 275 }, 276 { 277 val: struct { 278 X *[]uint64 279 }{}, 280 output: "C1C0", 281 }, 282 { 283 val: struct { 284 X *[]uint64 `rlp:"nilString"` 285 }{}, 286 output: "C180", 287 }, 288 289 // interfaces 290 {val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct 291 292 // Encoder 293 {val: (*testEncoder)(nil), output: "C0"}, 294 {val: &testEncoder{}, output: "00010001000100010001"}, 295 {val: &testEncoder{errors.New("test error")}, error: "test error"}, 296 {val: struct{ E testEncoderValueMethod }{}, output: "C3FAFEF0"}, 297 {val: struct{ E *testEncoderValueMethod }{}, output: "C1C0"}, 298 299 // Verify that the Encoder interface works for unsupported types like func(). 300 {val: undecodableEncoder(func() {}), output: "F5F5F5"}, 301 302 // Verify that pointer method testEncoder.EncodeRLP is called for 303 // addressable non-pointer values. 304 {val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"}, 305 {val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"}, 306 307 // Verify the error for non-addressable non-pointer Encoder. 308 {val: testEncoder{}, error: "rlp: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"}, 309 310 // Verify Encoder takes precedence over []byte. 311 {val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"}, 312 } 313 314 func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) { 315 for i, test := range encTests { 316 output, err := f(test.val) 317 if err != nil && test.error == "" { 318 t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T", 319 i, err, test.val, test.val) 320 continue 321 } 322 if test.error != "" && fmt.Sprint(err) != test.error { 323 t.Errorf("test %d: error mismatch\ngot %v\nwant %v\nvalue %#v\ntype %T", 324 i, err, test.error, test.val, test.val) 325 continue 326 } 327 if err == nil && !bytes.Equal(output, unhex(test.output)) { 328 t.Errorf("test %d: output mismatch:\ngot %X\nwant %s\nvalue %#v\ntype %T", 329 i, output, test.output, test.val, test.val) 330 } 331 } 332 } 333 334 func TestEncode(t *testing.T) { 335 runEncTests(t, func(val interface{}) ([]byte, error) { 336 b := new(bytes.Buffer) 337 err := Encode(b, val) 338 return b.Bytes(), err 339 }) 340 } 341 342 func TestEncodeToBytes(t *testing.T) { 343 runEncTests(t, EncodeToBytes) 344 } 345 346 func TestEncodeToReader(t *testing.T) { 347 runEncTests(t, func(val interface{}) ([]byte, error) { 348 _, r, err := EncodeToReader(val) 349 if err != nil { 350 return nil, err 351 } 352 return ioutil.ReadAll(r) 353 }) 354 } 355 356 func TestEncodeToReaderPiecewise(t *testing.T) { 357 runEncTests(t, func(val interface{}) ([]byte, error) { 358 size, r, err := EncodeToReader(val) 359 if err != nil { 360 return nil, err 361 } 362 363 // read output piecewise 364 output := make([]byte, size) 365 for start, end := 0, 0; start < size; start = end { 366 if remaining := size - start; remaining < 3 { 367 end += remaining 368 } else { 369 end = start + 3 370 } 371 n, err := r.Read(output[start:end]) 372 end = start + n 373 if err == io.EOF { 374 break 375 } else if err != nil { 376 return nil, err 377 } 378 } 379 return output, nil 380 }) 381 } 382 383 // This is a regression test verifying that encReader 384 // returns its encbuf to the pool only once. 385 func TestEncodeToReaderReturnToPool(t *testing.T) { 386 buf := make([]byte, 50) 387 wg := new(sync.WaitGroup) 388 for i := 0; i < 5; i++ { 389 wg.Add(1) 390 go func() { 391 for i := 0; i < 1000; i++ { 392 _, r, _ := EncodeToReader("foo") 393 ioutil.ReadAll(r) 394 r.Read(buf) 395 r.Read(buf) 396 r.Read(buf) 397 r.Read(buf) 398 } 399 wg.Done() 400 }() 401 } 402 wg.Wait() 403 }