| 
17 | 17 | package types_test  | 
18 | 18 | 
 
  | 
19 | 19 | import (  | 
 | 20 | +	"bytes"  | 
20 | 21 | 	"encoding/hex"  | 
21 | 22 | 	"testing"  | 
22 | 23 | 
 
  | 
 | 24 | +	"github.com/google/go-cmp/cmp"  | 
23 | 25 | 	"github.com/stretchr/testify/assert"  | 
24 | 26 | 	"github.com/stretchr/testify/require"  | 
25 | 27 | 
 
  | 
@@ -133,40 +135,71 @@ func TestBodyRLPBackwardsCompatibility(t *testing.T) {  | 
133 | 135 | 	tests := []struct {  | 
134 | 136 | 		name        string  | 
135 | 137 | 		withdrawals []*Withdrawal  | 
136 |  | -		// WARNING: changing these hex values might break backwards  | 
137 |  | -		// compatibility of RLP encoding!  | 
138 |  | -		wantHex string  | 
139 | 138 | 	}{  | 
140 | 139 | 		{  | 
141 |  | -			name:    "without_Withdrawals",  | 
142 |  | -			wantHex: `f903f6d2d1884d98b91b8d3568708080808080808080f903e0f901eda093449fc540c83e70fa443a4b915449e55e28b904f20f13961ab2ce35f5de9f7da00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f901eda0a019122ed4ee6f666f32c82157681f98da4dab6e0d7180ad29a037b080c402e2a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000`,  | 
 | 140 | +			name: "with_nil_Withdrawals",  | 
 | 141 | +		},  | 
 | 142 | +		{  | 
 | 143 | +			name: "with_empty_Withdrawals",  | 
 | 144 | +			// As the struct field has an `rlp:"optional"` tag, we need to  | 
 | 145 | +			// differentiate between nil (nothing added to RLP) and an empty  | 
 | 146 | +			// slice (empty list added to RLP).  | 
 | 147 | +			withdrawals: []*Withdrawal{},  | 
143 | 148 | 		},  | 
144 | 149 | 		{  | 
145 | 150 | 			name:        "with_Withdrawals",  | 
146 | 151 | 			withdrawals: withdrawals,  | 
147 |  | -			wantHex:     `f90418d2d1884d98b91b8d3568708080808080808080f903e0f901eda093449fc540c83e70fa443a4b915449e55e28b904f20f13961ab2ce35f5de9f7da00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000f901eda0a019122ed4ee6f666f32c82157681f98da4dab6e0d7180ad29a037b080c402e2a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000e1e0880756befb39c6b8aa8094000000000000000000000000000000000000000080`,  | 
148 | 152 | 		},  | 
149 | 153 | 	}  | 
150 | 154 | 
 
  | 
151 | 155 | 	for _, tt := range tests {  | 
152 | 156 | 		t.Run(tt.name, func(t *testing.T) {  | 
153 | 157 | 			body.Withdrawals = tt.withdrawals  | 
154 | 158 | 
 
  | 
155 |  | -			wantRLP, err := hex.DecodeString(tt.wantHex)  | 
156 |  | -			require.NoError(t, err, "hex.DecodeString()")  | 
 | 159 | +			// The originaly [Body] doesn't implement [rlp.Encoder] nor  | 
 | 160 | +			// [rlp.Decoder] so we can use a methodless equivalent as gold  | 
 | 161 | +			// standard.  | 
 | 162 | +			type withoutMethods Body  | 
 | 163 | +			wantRLP, err := rlp.EncodeToBytes((*withoutMethods)(body))  | 
 | 164 | +			require.NoErrorf(t, err, "rlp.EncodeToBytes([%T with methods stripped])", body)  | 
157 | 165 | 
 
  | 
158 | 166 | 			t.Run("Encode", func(t *testing.T) {  | 
159 | 167 | 				got, err := rlp.EncodeToBytes(body)  | 
160 | 168 | 				require.NoErrorf(t, err, "rlp.EncodeToBytes(%T)", body)  | 
161 |  | -				t.Logf("got RLP: %#x", got)  | 
162 | 169 | 				assert.Equalf(t, wantRLP, got, "rlp.EncodeToBytes(%T)", body)  | 
163 | 170 | 			})  | 
164 | 171 | 
 
  | 
165 | 172 | 			t.Run("Decode", func(t *testing.T) {  | 
166 | 173 | 				got := new(Body)  | 
167 | 174 | 				err := rlp.DecodeBytes(wantRLP, got)  | 
168 | 175 | 				require.NoErrorf(t, err, "rlp.DecodeBytes(..., %T)", got)  | 
 | 176 | + | 
 | 177 | +				opts := cmp.Options{  | 
 | 178 | +					cmp.Comparer(func(a, b *Header) bool {  | 
 | 179 | +						return a.Hash() == b.Hash()  | 
 | 180 | +					}),  | 
 | 181 | +					cmp.Comparer(txComparer(t)),  | 
 | 182 | +				}  | 
 | 183 | +				if diff := cmp.Diff(body, got, opts); diff != "" {  | 
 | 184 | +					t.Errorf("rlp.DecodeBytes(rlp.EncodeToBytes(%T)) diff (-want +got):\n%s", body, diff)  | 
 | 185 | +				}  | 
169 | 186 | 			})  | 
170 | 187 | 		})  | 
171 | 188 | 	}  | 
172 | 189 | }  | 
 | 190 | + | 
 | 191 | +func txComparer(tb testing.TB) func(_, _ *Transaction) bool {  | 
 | 192 | +	return func(a, b *Transaction) bool {  | 
 | 193 | +		if a == nil && b == nil {  | 
 | 194 | +			return true  | 
 | 195 | +		}  | 
 | 196 | +		if a == nil || b == nil {  | 
 | 197 | +			return false  | 
 | 198 | +		}  | 
 | 199 | +		aBuf, err := a.MarshalBinary()  | 
 | 200 | +		require.NoErrorf(tb, err, "%T.MarshalBinary()", a)  | 
 | 201 | +		bBuf, err := b.MarshalBinary()  | 
 | 202 | +		require.NoErrorf(tb, err, "%T.MarshalBinary()", b)  | 
 | 203 | +		return bytes.Equal(aBuf, bBuf)  | 
 | 204 | +	}  | 
 | 205 | +}  | 
0 commit comments