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