github.com/flashbots/go-ethereum@v1.9.7/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  		panic("EncodeRLP called on nil value")
    37  	}
    38  	if e.err != nil {
    39  		return e.err
    40  	} else {
    41  		w.Write([]byte{0, 1, 0, 1, 0, 1, 0, 1, 0, 1})
    42  	}
    43  	return nil
    44  }
    45  
    46  type testEncoderValueMethod struct{}
    47  
    48  func (e testEncoderValueMethod) EncodeRLP(w io.Writer) error {
    49  	w.Write([]byte{0xFA, 0xFE, 0xF0})
    50  	return nil
    51  }
    52  
    53  type byteEncoder byte
    54  
    55  func (e byteEncoder) EncodeRLP(w io.Writer) error {
    56  	w.Write(EmptyList)
    57  	return nil
    58  }
    59  
    60  type undecodableEncoder func()
    61  
    62  func (f undecodableEncoder) EncodeRLP(w io.Writer) error {
    63  	w.Write([]byte{0xF5, 0xF5, 0xF5})
    64  	return nil
    65  }
    66  
    67  type encodableReader struct {
    68  	A, B uint
    69  }
    70  
    71  func (e *encodableReader) Read(b []byte) (int, error) {
    72  	panic("called")
    73  }
    74  
    75  type namedByteType byte
    76  
    77  var (
    78  	_ = Encoder(&testEncoder{})
    79  	_ = Encoder(byteEncoder(0))
    80  
    81  	reader io.Reader = &encodableReader{1, 2}
    82  )
    83  
    84  type encTest struct {
    85  	val           interface{}
    86  	output, error string
    87  }
    88  
    89  var encTests = []encTest{
    90  	// booleans
    91  	{val: true, output: "01"},
    92  	{val: false, output: "80"},
    93  
    94  	// integers
    95  	{val: uint32(0), output: "80"},
    96  	{val: uint32(127), output: "7F"},
    97  	{val: uint32(128), output: "8180"},
    98  	{val: uint32(256), output: "820100"},
    99  	{val: uint32(1024), output: "820400"},
   100  	{val: uint32(0xFFFFFF), output: "83FFFFFF"},
   101  	{val: uint32(0xFFFFFFFF), output: "84FFFFFFFF"},
   102  	{val: uint64(0xFFFFFFFF), output: "84FFFFFFFF"},
   103  	{val: uint64(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
   104  	{val: uint64(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
   105  	{val: uint64(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
   106  	{val: uint64(0xFFFFFFFFFFFFFFFF), output: "88FFFFFFFFFFFFFFFF"},
   107  
   108  	// big integers (should match uint for small values)
   109  	{val: big.NewInt(0), output: "80"},
   110  	{val: big.NewInt(1), output: "01"},
   111  	{val: big.NewInt(127), output: "7F"},
   112  	{val: big.NewInt(128), output: "8180"},
   113  	{val: big.NewInt(256), output: "820100"},
   114  	{val: big.NewInt(1024), output: "820400"},
   115  	{val: big.NewInt(0xFFFFFF), output: "83FFFFFF"},
   116  	{val: big.NewInt(0xFFFFFFFF), output: "84FFFFFFFF"},
   117  	{val: big.NewInt(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
   118  	{val: big.NewInt(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
   119  	{val: big.NewInt(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
   120  	{
   121  		val:    big.NewInt(0).SetBytes(unhex("102030405060708090A0B0C0D0E0F2")),
   122  		output: "8F102030405060708090A0B0C0D0E0F2",
   123  	},
   124  	{
   125  		val:    big.NewInt(0).SetBytes(unhex("0100020003000400050006000700080009000A000B000C000D000E01")),
   126  		output: "9C0100020003000400050006000700080009000A000B000C000D000E01",
   127  	},
   128  	{
   129  		val:    big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
   130  		output: "A1010000000000000000000000000000000000000000000000000000000000000000",
   131  	},
   132  
   133  	// non-pointer big.Int
   134  	{val: *big.NewInt(0), output: "80"},
   135  	{val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"},
   136  
   137  	// negative ints are not supported
   138  	{val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"},
   139  
   140  	// byte slices, strings
   141  	{val: []byte{}, output: "80"},
   142  	{val: []byte{0x7E}, output: "7E"},
   143  	{val: []byte{0x7F}, output: "7F"},
   144  	{val: []byte{0x80}, output: "8180"},
   145  	{val: []byte{1, 2, 3}, output: "83010203"},
   146  
   147  	{val: []namedByteType{1, 2, 3}, output: "83010203"},
   148  	{val: [...]namedByteType{1, 2, 3}, output: "83010203"},
   149  
   150  	{val: "", output: "80"},
   151  	{val: "\x7E", output: "7E"},
   152  	{val: "\x7F", output: "7F"},
   153  	{val: "\x80", output: "8180"},
   154  	{val: "dog", output: "83646F67"},
   155  	{
   156  		val:    "Lorem ipsum dolor sit amet, consectetur adipisicing eli",
   157  		output: "B74C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C69",
   158  	},
   159  	{
   160  		val:    "Lorem ipsum dolor sit amet, consectetur adipisicing elit",
   161  		output: "B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974",
   162  	},
   163  	{
   164  		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",
   165  		output: "B904004C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742E20437572616269747572206D6175726973206D61676E612C20737573636970697420736564207665686963756C61206E6F6E2C20696163756C697320666175636962757320746F72746F722E2050726F696E20737573636970697420756C74726963696573206D616C6573756164612E204475697320746F72746F7220656C69742C2064696374756D2071756973207472697374697175652065752C20756C7472696365732061742072697375732E204D6F72626920612065737420696D70657264696574206D6920756C6C616D636F7270657220616C6971756574207375736369706974206E6563206C6F72656D2E2041656E65616E2071756973206C656F206D6F6C6C69732C2076756C70757461746520656C6974207661726975732C20636F6E73657175617420656E696D2E204E756C6C6120756C74726963657320747572706973206A7573746F2C20657420706F73756572652075726E6120636F6E7365637465747572206E65632E2050726F696E206E6F6E20636F6E76616C6C6973206D657475732E20446F6E65632074656D706F7220697073756D20696E206D617572697320636F6E67756520736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E646973736520636F6E76616C6C69732073656D2076656C206D617373612066617563696275732C2065676574206C6163696E6961206C616375732074656D706F722E204E756C6C61207175697320756C747269636965732070757275732E2050726F696E20617563746F722072686F6E637573206E69626820636F6E64696D656E74756D206D6F6C6C69732E20416C697175616D20636F6E73657175617420656E696D206174206D65747573206C75637475732C206120656C656966656E6420707572757320656765737461732E20437572616269747572206174206E696268206D657475732E204E616D20626962656E64756D2C206E6571756520617420617563746F72207472697374697175652C206C6F72656D206C696265726F20616C697175657420617263752C206E6F6E20696E74657264756D2074656C6C7573206C65637475732073697420616D65742065726F732E20437261732072686F6E6375732C206D65747573206163206F726E617265206375727375732C20646F6C6F72206A7573746F20756C747269636573206D657475732C20617420756C6C616D636F7270657220766F6C7574706174",
   166  	},
   167  
   168  	// slices
   169  	{val: []uint{}, output: "C0"},
   170  	{val: []uint{1, 2, 3}, output: "C3010203"},
   171  	{
   172  		// [ [], [[]], [ [], [[]] ] ]
   173  		val:    []interface{}{[]interface{}{}, [][]interface{}{{}}, []interface{}{[]interface{}{}, [][]interface{}{{}}}},
   174  		output: "C7C0C1C0C3C0C1C0",
   175  	},
   176  	{
   177  		val:    []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo"},
   178  		output: "F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F",
   179  	},
   180  	{
   181  		val:    []interface{}{uint(1), uint(0xFFFFFF), []interface{}{[]uint{4, 5, 5}}, "abc"},
   182  		output: "CE0183FFFFFFC4C304050583616263",
   183  	},
   184  	{
   185  		val: [][]string{
   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  			{"asdf", "qwer", "zxcv"},
   204  			{"asdf", "qwer", "zxcv"},
   205  			{"asdf", "qwer", "zxcv"},
   206  			{"asdf", "qwer", "zxcv"},
   207  			{"asdf", "qwer", "zxcv"},
   208  			{"asdf", "qwer", "zxcv"},
   209  			{"asdf", "qwer", "zxcv"},
   210  			{"asdf", "qwer", "zxcv"},
   211  			{"asdf", "qwer", "zxcv"},
   212  			{"asdf", "qwer", "zxcv"},
   213  			{"asdf", "qwer", "zxcv"},
   214  			{"asdf", "qwer", "zxcv"},
   215  			{"asdf", "qwer", "zxcv"},
   216  			{"asdf", "qwer", "zxcv"},
   217  			{"asdf", "qwer", "zxcv"},
   218  		},
   219  		output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376",
   220  	},
   221  
   222  	// RawValue
   223  	{val: RawValue(unhex("01")), output: "01"},
   224  	{val: RawValue(unhex("82FFFF")), output: "82FFFF"},
   225  	{val: []RawValue{unhex("01"), unhex("02")}, output: "C20102"},
   226  
   227  	// structs
   228  	{val: simplestruct{}, output: "C28080"},
   229  	{val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"},
   230  	{val: &recstruct{5, nil}, output: "C205C0"},
   231  	{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
   232  	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02"), unhex("03")}}, output: "C3010203"},
   233  	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"},
   234  	{val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"},
   235  	{val: &tailRaw{A: 1, Tail: nil}, output: "C101"},
   236  	{val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"},
   237  	{val: &intField{X: 3}, error: "rlp: type int is not RLP-serializable (struct field rlp.intField.X)"},
   238  
   239  	// nil
   240  	{val: (*uint)(nil), output: "80"},
   241  	{val: (*string)(nil), output: "80"},
   242  	{val: (*[]byte)(nil), output: "80"},
   243  	{val: (*[10]byte)(nil), output: "80"},
   244  	{val: (*big.Int)(nil), output: "80"},
   245  	{val: (*[]string)(nil), output: "C0"},
   246  	{val: (*[10]string)(nil), output: "C0"},
   247  	{val: (*[]interface{})(nil), output: "C0"},
   248  	{val: (*[]struct{ uint })(nil), output: "C0"},
   249  	{val: (*interface{})(nil), output: "C0"},
   250  
   251  	// nil struct fields
   252  	{
   253  		val: struct {
   254  			X *[]byte
   255  		}{},
   256  		output: "C180",
   257  	},
   258  	{
   259  		val: struct {
   260  			X *[2]byte
   261  		}{},
   262  		output: "C180",
   263  	},
   264  	{
   265  		val: struct {
   266  			X *uint64
   267  		}{},
   268  		output: "C180",
   269  	},
   270  	{
   271  		val: struct {
   272  			X *uint64 `rlp:"nilList"`
   273  		}{},
   274  		output: "C1C0",
   275  	},
   276  	{
   277  		val: struct {
   278  			X *[]uint64
   279  		}{},
   280  		output: "C1C0",
   281  	},
   282  	{
   283  		val: struct {
   284  			X *[]uint64 `rlp:"nilString"`
   285  		}{},
   286  		output: "C180",
   287  	},
   288  
   289  	// interfaces
   290  	{val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct
   291  
   292  	// Encoder
   293  	{val: (*testEncoder)(nil), output: "C0"},
   294  	{val: &testEncoder{}, output: "00010001000100010001"},
   295  	{val: &testEncoder{errors.New("test error")}, error: "test error"},
   296  	{val: struct{ E testEncoderValueMethod }{}, output: "C3FAFEF0"},
   297  	{val: struct{ E *testEncoderValueMethod }{}, output: "C1C0"},
   298  
   299  	// Verify that the Encoder interface works for unsupported types like func().
   300  	{val: undecodableEncoder(func() {}), output: "F5F5F5"},
   301  
   302  	// Verify that pointer method testEncoder.EncodeRLP is called for
   303  	// addressable non-pointer values.
   304  	{val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"},
   305  	{val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"},
   306  
   307  	// Verify the error for non-addressable non-pointer Encoder.
   308  	{val: testEncoder{}, error: "rlp: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"},
   309  
   310  	// Verify Encoder takes precedence over []byte.
   311  	{val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"},
   312  }
   313  
   314  func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) {
   315  	for i, test := range encTests {
   316  		output, err := f(test.val)
   317  		if err != nil && test.error == "" {
   318  			t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T",
   319  				i, err, test.val, test.val)
   320  			continue
   321  		}
   322  		if test.error != "" && fmt.Sprint(err) != test.error {
   323  			t.Errorf("test %d: error mismatch\ngot   %v\nwant  %v\nvalue %#v\ntype  %T",
   324  				i, err, test.error, test.val, test.val)
   325  			continue
   326  		}
   327  		if err == nil && !bytes.Equal(output, unhex(test.output)) {
   328  			t.Errorf("test %d: output mismatch:\ngot   %X\nwant  %s\nvalue %#v\ntype  %T",
   329  				i, output, test.output, test.val, test.val)
   330  		}
   331  	}
   332  }
   333  
   334  func TestEncode(t *testing.T) {
   335  	runEncTests(t, func(val interface{}) ([]byte, error) {
   336  		b := new(bytes.Buffer)
   337  		err := Encode(b, val)
   338  		return b.Bytes(), err
   339  	})
   340  }
   341  
   342  func TestEncodeToBytes(t *testing.T) {
   343  	runEncTests(t, EncodeToBytes)
   344  }
   345  
   346  func TestEncodeToReader(t *testing.T) {
   347  	runEncTests(t, func(val interface{}) ([]byte, error) {
   348  		_, r, err := EncodeToReader(val)
   349  		if err != nil {
   350  			return nil, err
   351  		}
   352  		return ioutil.ReadAll(r)
   353  	})
   354  }
   355  
   356  func TestEncodeToReaderPiecewise(t *testing.T) {
   357  	runEncTests(t, func(val interface{}) ([]byte, error) {
   358  		size, r, err := EncodeToReader(val)
   359  		if err != nil {
   360  			return nil, err
   361  		}
   362  
   363  		// read output piecewise
   364  		output := make([]byte, size)
   365  		for start, end := 0, 0; start < size; start = end {
   366  			if remaining := size - start; remaining < 3 {
   367  				end += remaining
   368  			} else {
   369  				end = start + 3
   370  			}
   371  			n, err := r.Read(output[start:end])
   372  			end = start + n
   373  			if err == io.EOF {
   374  				break
   375  			} else if err != nil {
   376  				return nil, err
   377  			}
   378  		}
   379  		return output, nil
   380  	})
   381  }
   382  
   383  // This is a regression test verifying that encReader
   384  // returns its encbuf to the pool only once.
   385  func TestEncodeToReaderReturnToPool(t *testing.T) {
   386  	buf := make([]byte, 50)
   387  	wg := new(sync.WaitGroup)
   388  	for i := 0; i < 5; i++ {
   389  		wg.Add(1)
   390  		go func() {
   391  			for i := 0; i < 1000; i++ {
   392  				_, r, _ := EncodeToReader("foo")
   393  				ioutil.ReadAll(r)
   394  				r.Read(buf)
   395  				r.Read(buf)
   396  				r.Read(buf)
   397  				r.Read(buf)
   398  			}
   399  			wg.Done()
   400  		}()
   401  	}
   402  	wg.Wait()
   403  }