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