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  }