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