encode_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. package rlp
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "math/big"
  9. "testing"
  10. )
  11. type testEncoder struct {
  12. err error
  13. }
  14. func (e *testEncoder) EncodeRLP(w io.Writer) error {
  15. if e == nil {
  16. w.Write([]byte{0, 0, 0, 0})
  17. } else if e.err != nil {
  18. return e.err
  19. } else {
  20. w.Write([]byte{0, 1, 0, 1, 0, 1, 0, 1, 0, 1})
  21. }
  22. return nil
  23. }
  24. type byteEncoder byte
  25. func (e byteEncoder) EncodeRLP(w io.Writer) error {
  26. w.Write(EmptyList)
  27. return nil
  28. }
  29. type encodableReader struct {
  30. A, B uint
  31. }
  32. func (e *encodableReader) Read(b []byte) (int, error) {
  33. panic("called")
  34. }
  35. var (
  36. _ = Encoder(&testEncoder{})
  37. _ = Encoder(byteEncoder(0))
  38. reader io.Reader = &encodableReader{1, 2}
  39. )
  40. type encTest struct {
  41. val interface{}
  42. output, error string
  43. }
  44. var encTests = []encTest{
  45. // integers
  46. {val: uint32(0), output: "80"},
  47. {val: uint32(127), output: "7F"},
  48. {val: uint32(128), output: "8180"},
  49. {val: uint32(256), output: "820100"},
  50. {val: uint32(1024), output: "820400"},
  51. {val: uint32(0xFFFFFF), output: "83FFFFFF"},
  52. {val: uint32(0xFFFFFFFF), output: "84FFFFFFFF"},
  53. {val: uint64(0xFFFFFFFF), output: "84FFFFFFFF"},
  54. {val: uint64(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
  55. {val: uint64(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
  56. {val: uint64(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
  57. {val: uint64(0xFFFFFFFFFFFFFFFF), output: "88FFFFFFFFFFFFFFFF"},
  58. // big integers (should match uint for small values)
  59. {val: big.NewInt(0), output: "80"},
  60. {val: big.NewInt(1), output: "01"},
  61. {val: big.NewInt(127), output: "7F"},
  62. {val: big.NewInt(128), output: "8180"},
  63. {val: big.NewInt(256), output: "820100"},
  64. {val: big.NewInt(1024), output: "820400"},
  65. {val: big.NewInt(0xFFFFFF), output: "83FFFFFF"},
  66. {val: big.NewInt(0xFFFFFFFF), output: "84FFFFFFFF"},
  67. {val: big.NewInt(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
  68. {val: big.NewInt(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
  69. {val: big.NewInt(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
  70. {
  71. val: big.NewInt(0).SetBytes(unhex("102030405060708090A0B0C0D0E0F2")),
  72. output: "8F102030405060708090A0B0C0D0E0F2",
  73. },
  74. {
  75. val: big.NewInt(0).SetBytes(unhex("0100020003000400050006000700080009000A000B000C000D000E01")),
  76. output: "9C0100020003000400050006000700080009000A000B000C000D000E01",
  77. },
  78. {
  79. val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
  80. output: "A1010000000000000000000000000000000000000000000000000000000000000000",
  81. },
  82. // non-pointer big.Int
  83. {val: *big.NewInt(0), output: "80"},
  84. {val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"},
  85. // negative ints are not supported
  86. {val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"},
  87. // byte slices, strings
  88. {val: []byte{}, output: "80"},
  89. {val: []byte{1, 2, 3}, output: "83010203"},
  90. {val: "", output: "80"},
  91. {val: "dog", output: "83646F67"},
  92. {
  93. val: "Lorem ipsum dolor sit amet, consectetur adipisicing eli",
  94. output: "B74C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C69",
  95. },
  96. {
  97. val: "Lorem ipsum dolor sit amet, consectetur adipisicing elit",
  98. output: "B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974",
  99. },
  100. {
  101. 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",
  102. output: "B904004C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742E20437572616269747572206D6175726973206D61676E612C20737573636970697420736564207665686963756C61206E6F6E2C20696163756C697320666175636962757320746F72746F722E2050726F696E20737573636970697420756C74726963696573206D616C6573756164612E204475697320746F72746F7220656C69742C2064696374756D2071756973207472697374697175652065752C20756C7472696365732061742072697375732E204D6F72626920612065737420696D70657264696574206D6920756C6C616D636F7270657220616C6971756574207375736369706974206E6563206C6F72656D2E2041656E65616E2071756973206C656F206D6F6C6C69732C2076756C70757461746520656C6974207661726975732C20636F6E73657175617420656E696D2E204E756C6C6120756C74726963657320747572706973206A7573746F2C20657420706F73756572652075726E6120636F6E7365637465747572206E65632E2050726F696E206E6F6E20636F6E76616C6C6973206D657475732E20446F6E65632074656D706F7220697073756D20696E206D617572697320636F6E67756520736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E646973736520636F6E76616C6C69732073656D2076656C206D617373612066617563696275732C2065676574206C6163696E6961206C616375732074656D706F722E204E756C6C61207175697320756C747269636965732070757275732E2050726F696E20617563746F722072686F6E637573206E69626820636F6E64696D656E74756D206D6F6C6C69732E20416C697175616D20636F6E73657175617420656E696D206174206D65747573206C75637475732C206120656C656966656E6420707572757320656765737461732E20437572616269747572206174206E696268206D657475732E204E616D20626962656E64756D2C206E6571756520617420617563746F72207472697374697175652C206C6F72656D206C696265726F20616C697175657420617263752C206E6F6E20696E74657264756D2074656C6C7573206C65637475732073697420616D65742065726F732E20437261732072686F6E6375732C206D65747573206163206F726E617265206375727375732C20646F6C6F72206A7573746F20756C747269636573206D657475732C20617420756C6C616D636F7270657220766F6C7574706174",
  103. },
  104. // slices
  105. {val: []uint{}, output: "C0"},
  106. {val: []uint{1, 2, 3}, output: "C3010203"},
  107. {
  108. // [ [], [[]], [ [], [[]] ] ]
  109. val: []interface{}{[]interface{}{}, [][]interface{}{{}}, []interface{}{[]interface{}{}, [][]interface{}{{}}}},
  110. output: "C7C0C1C0C3C0C1C0",
  111. },
  112. {
  113. val: []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo"},
  114. output: "F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F",
  115. },
  116. {
  117. val: []interface{}{uint(1), uint(0xFFFFFF), []interface{}{[]uint{4, 5, 5}}, "abc"},
  118. output: "CE0183FFFFFFC4C304050583616263",
  119. },
  120. {
  121. val: [][]string{
  122. {"asdf", "qwer", "zxcv"},
  123. {"asdf", "qwer", "zxcv"},
  124. {"asdf", "qwer", "zxcv"},
  125. {"asdf", "qwer", "zxcv"},
  126. {"asdf", "qwer", "zxcv"},
  127. {"asdf", "qwer", "zxcv"},
  128. {"asdf", "qwer", "zxcv"},
  129. {"asdf", "qwer", "zxcv"},
  130. {"asdf", "qwer", "zxcv"},
  131. {"asdf", "qwer", "zxcv"},
  132. {"asdf", "qwer", "zxcv"},
  133. {"asdf", "qwer", "zxcv"},
  134. {"asdf", "qwer", "zxcv"},
  135. {"asdf", "qwer", "zxcv"},
  136. {"asdf", "qwer", "zxcv"},
  137. {"asdf", "qwer", "zxcv"},
  138. {"asdf", "qwer", "zxcv"},
  139. {"asdf", "qwer", "zxcv"},
  140. {"asdf", "qwer", "zxcv"},
  141. {"asdf", "qwer", "zxcv"},
  142. {"asdf", "qwer", "zxcv"},
  143. {"asdf", "qwer", "zxcv"},
  144. {"asdf", "qwer", "zxcv"},
  145. {"asdf", "qwer", "zxcv"},
  146. {"asdf", "qwer", "zxcv"},
  147. {"asdf", "qwer", "zxcv"},
  148. {"asdf", "qwer", "zxcv"},
  149. {"asdf", "qwer", "zxcv"},
  150. {"asdf", "qwer", "zxcv"},
  151. {"asdf", "qwer", "zxcv"},
  152. {"asdf", "qwer", "zxcv"},
  153. {"asdf", "qwer", "zxcv"},
  154. },
  155. output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376",
  156. },
  157. // structs
  158. {val: simplestruct{}, output: "C28080"},
  159. {val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"},
  160. {val: &recstruct{5, nil}, output: "C205C0"},
  161. {val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
  162. // flat
  163. {val: Flat(uint(1)), error: "rlp.Flat: uint did not encode as list"},
  164. {val: Flat(simplestruct{A: 3, B: "foo"}), output: "0383666F6F"},
  165. {
  166. // value generates more list headers after the Flat
  167. val: []interface{}{"foo", []uint{1, 2}, Flat([]uint{3, 4}), []uint{5, 6}, "bar"},
  168. output: "D083666F6FC201020304C2050683626172",
  169. },
  170. // nil
  171. {val: (*uint)(nil), output: "80"},
  172. {val: (*string)(nil), output: "80"},
  173. {val: (*[]byte)(nil), output: "80"},
  174. {val: (*[]string)(nil), output: "C0"},
  175. {val: (*[]interface{})(nil), output: "C0"},
  176. {val: (*[]struct{ uint })(nil), output: "C0"},
  177. {val: (*interface{})(nil), output: "C0"},
  178. // interfaces
  179. {val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct
  180. // Encoder
  181. {val: (*testEncoder)(nil), output: "00000000"},
  182. {val: &testEncoder{}, output: "00010001000100010001"},
  183. {val: &testEncoder{errors.New("test error")}, error: "test error"},
  184. // verify that pointer method testEncoder.EncodeRLP is called for
  185. // addressable non-pointer values.
  186. {val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"},
  187. {val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"},
  188. // verify the error for non-addressable non-pointer Encoder
  189. {val: testEncoder{}, error: "rlp: game over: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"},
  190. // verify the special case for []byte
  191. {val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"},
  192. }
  193. func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) {
  194. for i, test := range encTests {
  195. output, err := f(test.val)
  196. if err != nil && test.error == "" {
  197. t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T",
  198. i, err, test.val, test.val)
  199. continue
  200. }
  201. if test.error != "" && fmt.Sprint(err) != test.error {
  202. t.Errorf("test %d: error mismatch\ngot %v\nwant %v\nvalue %#v\ntype %T",
  203. i, err, test.error, test.val, test.val)
  204. continue
  205. }
  206. if err == nil && !bytes.Equal(output, unhex(test.output)) {
  207. t.Errorf("test %d: output mismatch:\ngot %X\nwant %s\nvalue %#v\ntype %T",
  208. i, output, test.output, test.val, test.val)
  209. }
  210. }
  211. }
  212. func TestEncode(t *testing.T) {
  213. runEncTests(t, func(val interface{}) ([]byte, error) {
  214. b := new(bytes.Buffer)
  215. err := Encode(b, val)
  216. return b.Bytes(), err
  217. })
  218. }
  219. func TestEncodeToBytes(t *testing.T) {
  220. runEncTests(t, EncodeToBytes)
  221. }
  222. func TestEncodeToReader(t *testing.T) {
  223. runEncTests(t, func(val interface{}) ([]byte, error) {
  224. _, r, err := EncodeToReader(val)
  225. if err != nil {
  226. return nil, err
  227. }
  228. return ioutil.ReadAll(r)
  229. })
  230. }
  231. func TestEncodeToReaderPiecewise(t *testing.T) {
  232. runEncTests(t, func(val interface{}) ([]byte, error) {
  233. size, r, err := EncodeToReader(val)
  234. if err != nil {
  235. return nil, err
  236. }
  237. // read output piecewise
  238. output := make([]byte, size)
  239. for start, end := 0, 0; start < size; start = end {
  240. if remaining := size - start; remaining < 3 {
  241. end += remaining
  242. } else {
  243. end = start + 3
  244. }
  245. n, err := r.Read(output[start:end])
  246. end = start + n
  247. if err == io.EOF {
  248. break
  249. } else if err != nil {
  250. return nil, err
  251. }
  252. }
  253. return output, nil
  254. })
  255. }