github.com/aquanetwork/aquachain@v1.7.8/rlp/encode_test.go (about)

     1  // Copyright 2014 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain 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 aquachain 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 aquachain 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  	{val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"},
   222  
   223  	// nil
   224  	{val: (*uint)(nil), output: "80"},
   225  	{val: (*string)(nil), output: "80"},
   226  	{val: (*[]byte)(nil), output: "80"},
   227  	{val: (*[10]byte)(nil), output: "80"},
   228  	{val: (*big.Int)(nil), output: "80"},
   229  	{val: (*[]string)(nil), output: "C0"},
   230  	{val: (*[10]string)(nil), output: "C0"},
   231  	{val: (*[]interface{})(nil), output: "C0"},
   232  	{val: (*[]struct{ uint })(nil), output: "C0"},
   233  	{val: (*interface{})(nil), output: "C0"},
   234  
   235  	// interfaces
   236  	{val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct
   237  
   238  	// Encoder
   239  	{val: (*testEncoder)(nil), output: "00000000"},
   240  	{val: &testEncoder{}, output: "00010001000100010001"},
   241  	{val: &testEncoder{errors.New("test error")}, error: "test error"},
   242  	// verify that pointer method testEncoder.EncodeRLP is called for
   243  	// addressable non-pointer values.
   244  	{val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"},
   245  	{val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"},
   246  	// verify the error for non-addressable non-pointer Encoder
   247  	{val: testEncoder{}, error: "rlp: game over: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"},
   248  	// verify the special case for []byte
   249  	{val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"},
   250  }
   251  
   252  func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) {
   253  	for i, test := range encTests {
   254  		output, err := f(test.val)
   255  		if err != nil && test.error == "" {
   256  			t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T",
   257  				i, err, test.val, test.val)
   258  			continue
   259  		}
   260  		if test.error != "" && fmt.Sprint(err) != test.error {
   261  			t.Errorf("test %d: error mismatch\ngot   %v\nwant  %v\nvalue %#v\ntype  %T",
   262  				i, err, test.error, test.val, test.val)
   263  			continue
   264  		}
   265  		if err == nil && !bytes.Equal(output, unhex(test.output)) {
   266  			t.Errorf("test %d: output mismatch:\ngot   %X\nwant  %s\nvalue %#v\ntype  %T",
   267  				i, output, test.output, test.val, test.val)
   268  		}
   269  	}
   270  }
   271  
   272  func TestEncode(t *testing.T) {
   273  	runEncTests(t, func(val interface{}) ([]byte, error) {
   274  		b := new(bytes.Buffer)
   275  		err := Encode(b, val)
   276  		return b.Bytes(), err
   277  	})
   278  }
   279  
   280  func TestEncodeToBytes(t *testing.T) {
   281  	runEncTests(t, EncodeToBytes)
   282  }
   283  
   284  func TestEncodeToReader(t *testing.T) {
   285  	runEncTests(t, func(val interface{}) ([]byte, error) {
   286  		_, r, err := EncodeToReader(val)
   287  		if err != nil {
   288  			return nil, err
   289  		}
   290  		return ioutil.ReadAll(r)
   291  	})
   292  }
   293  
   294  func TestEncodeToReaderPiecewise(t *testing.T) {
   295  	runEncTests(t, func(val interface{}) ([]byte, error) {
   296  		size, r, err := EncodeToReader(val)
   297  		if err != nil {
   298  			return nil, err
   299  		}
   300  
   301  		// read output piecewise
   302  		output := make([]byte, size)
   303  		for start, end := 0, 0; start < size; start = end {
   304  			if remaining := size - start; remaining < 3 {
   305  				end += remaining
   306  			} else {
   307  				end = start + 3
   308  			}
   309  			n, err := r.Read(output[start:end])
   310  			end = start + n
   311  			if err == io.EOF {
   312  				break
   313  			} else if err != nil {
   314  				return nil, err
   315  			}
   316  		}
   317  		return output, nil
   318  	})
   319  }
   320  
   321  // This is a regression test verifying that encReader
   322  // returns its encbuf to the pool only once.
   323  func TestEncodeToReaderReturnToPool(t *testing.T) {
   324  	buf := make([]byte, 50)
   325  	wg := new(sync.WaitGroup)
   326  	for i := 0; i < 5; i++ {
   327  		wg.Add(1)
   328  		go func() {
   329  			for i := 0; i < 1000; i++ {
   330  				_, r, _ := EncodeToReader("foo")
   331  				ioutil.ReadAll(r)
   332  				r.Read(buf)
   333  				r.Read(buf)
   334  				r.Read(buf)
   335  				r.Read(buf)
   336  			}
   337  			wg.Done()
   338  		}()
   339  	}
   340  	wg.Wait()
   341  }