1717package types_test
1818
1919import (
20- "bytes"
2120 "encoding/hex"
2221 "fmt"
2322 "testing"
@@ -26,7 +25,9 @@ import (
2625 "github.com/stretchr/testify/assert"
2726 "github.com/stretchr/testify/require"
2827
28+ "github.com/ava-labs/libevm/common"
2929 . "github.com/ava-labs/libevm/core/types"
30+ "github.com/ava-labs/libevm/libevm/cmpeth"
3031 "github.com/ava-labs/libevm/libevm/ethtest"
3132 "github.com/ava-labs/libevm/rlp"
3233)
@@ -193,10 +194,8 @@ func testBodyRLPBackwardsCompatibility(t *testing.T, seed uint64) {
193194 require .NoErrorf (t , err , "rlp.DecodeBytes(..., %T)" , got )
194195
195196 opts := cmp.Options {
196- cmp .Comparer (func (a , b * Header ) bool {
197- return a .Hash () == b .Hash ()
198- }),
199- cmp .Comparer (txComparer (t )),
197+ cmpeth .CompareHeadersByHash (),
198+ cmpeth .CompareTransactionsByBinary (t ),
200199 }
201200 if diff := cmp .Diff (body , got , opts ); diff != "" {
202201 t .Errorf ("rlp.DecodeBytes(rlp.EncodeToBytes(%T)) diff (-want +got):\n %s" , body , diff )
@@ -206,23 +205,116 @@ func testBodyRLPBackwardsCompatibility(t *testing.T, seed uint64) {
206205 }
207206}
208207
209- // txComparer returns an equality checker for use with [cmp.Comparer].
210- func txComparer (tb testing.TB ) func (_ , _ * Transaction ) bool {
211- tb .Helper ()
212- return func (a , b * Transaction ) bool {
213- tb .Helper ()
214-
215- if a == nil && b == nil {
216- return true
217- }
218- if a == nil || b == nil {
219- return false
220- }
221-
222- aBuf , err := a .MarshalBinary ()
223- require .NoErrorf (tb , err , "%T.MarshalBinary()" , a )
224- bBuf , err := b .MarshalBinary ()
225- require .NoErrorf (tb , err , "%T.MarshalBinary()" , b )
226- return bytes .Equal (aBuf , bBuf )
208+ // cChainBodyExtras carries the same additional fields as the ava-labs/coreth
209+ // [Body] and implements [BodyHooks] to achieve equivalent RLP {en,de}coding.
210+ type cChainBodyExtras struct {
211+ Version uint32
212+ ExtData * []byte
213+ }
214+
215+ var _ BodyHooks = (* cChainBodyExtras )(nil )
216+
217+ func (e * cChainBodyExtras ) AppendRLPFields (b rlp.EncoderBuffer , _ bool ) error {
218+ b .WriteUint64 (uint64 (e .Version ))
219+ if e .ExtData != nil {
220+ b .WriteString (string (* e .ExtData ))
221+ } else {
222+ b .WriteString ("" )
223+ }
224+ return nil
225+ }
226+
227+ func (e * cChainBodyExtras ) DecodeExtraRLPFields (s * rlp.Stream ) error {
228+ if err := s .Decode (& e .Version ); err != nil {
229+ return err
230+ }
231+
232+ buf , err := s .Bytes ()
233+ if err != nil {
234+ return err
235+ }
236+ if len (buf ) > 0 {
237+ e .ExtData = & buf
238+ } else {
239+ // Respect the `rlp:"nil"` field tag.
240+ e .ExtData = nil
241+ }
242+
243+ return nil
244+ }
245+
246+ func TestBodyRLPCChainCompat (t * testing.T ) {
247+ // The inputs to this test were used to generate the expected RLP with
248+ // ava-labs/coreth. This serves as both an example of how to use [BodyHooks]
249+ // and a test of compatibility.
250+
251+ t .Cleanup (func () {
252+ TestOnlyRegisterBodyHooks (NOOPBodyHooks {})
253+ })
254+
255+ to := common .HexToAddress (`decafc0ffeebad` )
256+ body := & Body {
257+ Transactions : []* Transaction {
258+ NewTx (& LegacyTx {
259+ Nonce : 42 ,
260+ To : & to ,
261+ }),
262+ },
263+ Uncles : []* Header { /* RLP encoding differs in ava-labs/coreth */ },
264+ }
265+
266+ const version = 314159
267+ tests := []struct {
268+ name string
269+ extra * cChainBodyExtras
270+ // WARNING: changing these values might break backwards compatibility of
271+ // RLP encoding!
272+ wantRLPHex string
273+ }{
274+ {
275+ extra : & cChainBodyExtras {
276+ Version : version ,
277+ },
278+ wantRLPHex : `e5dedd2a80809400000000000000000000000000decafc0ffeebad8080808080c08304cb2f80` ,
279+ },
280+ {
281+ extra : & cChainBodyExtras {
282+ Version : version ,
283+ ExtData : & []byte {1 , 4 , 2 , 8 , 5 , 7 },
284+ },
285+ wantRLPHex : `ebdedd2a80809400000000000000000000000000decafc0ffeebad8080808080c08304cb2f86010402080507` ,
286+ },
287+ }
288+
289+ for _ , tt := range tests {
290+ t .Run (tt .name , func (t * testing.T ) {
291+ wantRLP , err := hex .DecodeString (tt .wantRLPHex )
292+ require .NoError (t , err )
293+
294+ t .Run ("Encode" , func (t * testing.T ) {
295+ TestOnlyRegisterBodyHooks (tt .extra )
296+ got , err := rlp .EncodeToBytes (body )
297+ require .NoError (t , err )
298+ assert .Equal (t , wantRLP , got )
299+ })
300+
301+ t .Run ("Decode" , func (t * testing.T ) {
302+ var extra cChainBodyExtras
303+ TestOnlyRegisterBodyHooks (& extra )
304+
305+ got := new (Body )
306+ err := rlp .DecodeBytes (wantRLP , got )
307+ require .NoError (t , err )
308+ assert .Equal (t , tt .extra , & extra )
309+
310+ opts := cmp.Options {
311+ cmpeth .CompareHeadersByHash (),
312+ cmpeth .CompareTransactionsByBinary (t ),
313+ }
314+ if diff := cmp .Diff (body , got , opts ); diff != "" {
315+ t .Errorf ("%s" , diff )
316+ }
317+ })
318+ })
227319 }
228320}
0 commit comments