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  }