mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-22 14:44:30 +00:00
## Why this should be merged
Allows for modification of `types.Body` payload data + RLP encoding
without placing the entire RLP burden on the `libevm` user as we did
with `types.HeaderHooks`.
## How this works
RLP encoding of a struct is simply a concatenation of RLP encodings of
fields, encompassed by an RLP "list". The
`AppendRLPFields(rlp.EncoderBuffer, ...)` hook exploits this and plugs
in before all `rlp:"optional"`-tagged fields to allow for inclusion of
any new fields. The `EncoderBuffer` SHOULD be used as the `io.Writer`
passed when encoding each field: `rlp.Encode(buffer, fieldValue)`.
`Body` doesn't have `{En,De}codeRLP` methods so they are implemented to
identically replicate original behaviour when a no-op hook is present.
This pattern is sufficient for the `ava-labs/coreth` modifications of
`Body` but can be modified / extended for more complex scenarios, like
`Header`.
> [!NOTE]
> This PR does not include registration of the hooks as that was not the
initial goal and adding them would create too much PR bloat. There is a
placeholder `var todoRegisteredBodyHooks` global variable that can only
be set in tests.
## How this was tested
- Backwards compatibility: the new methods are fuzzed against a `type
withoutMethods Body` passed directly to `rlp.{En,De}code()`
- `coreth` compatibility: unit test of a local implementation of
`BodyHooks` demonstrating reproducibility of RLP encoding.
---------
Signed-off-by: Arran Schlosberg <519948+ARR4N@users.noreply.github.com>
Co-authored-by: Quentin McGaw <quentin.mcgaw@avalabs.org>
56 lines
1.8 KiB
Go
56 lines
1.8 KiB
Go
// Copyright 2025 the libevm authors.
|
|
//
|
|
// The libevm additions to go-ethereum are free software: you can redistribute
|
|
// them and/or modify them under the terms of the GNU Lesser General Public License
|
|
// as published by the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// The libevm additions are distributed in the hope that they will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
package rlp
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestEncodeListToBuffer(t *testing.T) {
|
|
vals := []uint{1, 2, 3, 4, 5}
|
|
|
|
want, err := EncodeToBytes(vals)
|
|
require.NoErrorf(t, err, "EncodeToBytes(%T{%[1]v})", vals)
|
|
|
|
var got bytes.Buffer
|
|
buf := NewEncoderBuffer(&got)
|
|
err = EncodeListToBuffer(buf, vals)
|
|
require.NoErrorf(t, err, "EncodeListToBuffer(..., %T{%[1]v})", vals)
|
|
require.NoErrorf(t, buf.Flush(), "%T.Flush()", buf)
|
|
|
|
assert.Equal(t, want, got.Bytes(), "EncodeListToBuffer(..., %T{%[1]v})", vals)
|
|
}
|
|
|
|
func TestDecodeList(t *testing.T) {
|
|
vals := []uint{0, 1, 42, 314159}
|
|
|
|
rlp, err := EncodeToBytes(vals)
|
|
require.NoErrorf(t, err, "EncodeToBytes(%T{%[1]v})", vals)
|
|
|
|
s := NewStream(bytes.NewReader(rlp), 0)
|
|
got, err := DecodeList[uint](s)
|
|
require.NoErrorf(t, err, "DecodeList[%T]()", vals[0])
|
|
|
|
require.Equal(t, len(vals), len(got), "number of values returned by DecodeList()")
|
|
for i, gotPtr := range got {
|
|
assert.Equalf(t, vals[i], *gotPtr, "DecodeList()[%d]", i)
|
|
}
|
|
}
|