forked from ethereum/go-ethereum
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat:
types.HeaderHooks
for RLP overrides (#89)
## Why this should be merged The `types.Header` fields of both [`coreth`](https://pkg.go.dev/github.com/ava-labs/coreth/core/types#Header) and [`subnet-evm`](https://pkg.go.dev/github.com/ava-labs/subnet-evm/core/types#Header) have been modified such that their RLP encodings (i.e. block hashes) aren't compatible with vanilla `geth` nor each other. This PR adds support for arbitrary RLP encoding coupled with type-safe extra payloads. ## How this works Equivalent to #1 (`params`) and #44 (`types.StateAccount`) registration of pseudo-generic payloads. The only major difference is the guarantee of a non-nil payload pointer, which means that the payload hooks are never called on nil pointers as this would make it difficult to decode RLP into them. ## How this was tested Round-trip RLP {en,de}coding via a registered stub hook. --------- Signed-off-by: Arran Schlosberg <[email protected]> Co-authored-by: Quentin McGaw <[email protected]>
- Loading branch information
Showing
11 changed files
with
294 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright 2024 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 types_test | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
. "github.com/ava-labs/libevm/core/types" | ||
"github.com/ava-labs/libevm/crypto" | ||
"github.com/ava-labs/libevm/libevm/ethtest" | ||
"github.com/ava-labs/libevm/rlp" | ||
) | ||
|
||
type stubHeaderHooks struct { | ||
rlpSuffix []byte | ||
gotRawRLPToDecode []byte | ||
setHeaderToOnDecode Header | ||
|
||
errEncode, errDecode error | ||
} | ||
|
||
func fakeHeaderRLP(h *Header, suffix []byte) []byte { | ||
return append(crypto.Keccak256(h.ParentHash[:]), suffix...) | ||
} | ||
|
||
func (hh *stubHeaderHooks) EncodeRLP(h *Header, w io.Writer) error { | ||
if _, err := w.Write(fakeHeaderRLP(h, hh.rlpSuffix)); err != nil { | ||
return err | ||
} | ||
return hh.errEncode | ||
} | ||
|
||
func (hh *stubHeaderHooks) DecodeRLP(h *Header, s *rlp.Stream) error { | ||
r, err := s.Raw() | ||
if err != nil { | ||
return err | ||
} | ||
hh.gotRawRLPToDecode = r | ||
*h = hh.setHeaderToOnDecode | ||
return hh.errDecode | ||
} | ||
|
||
func TestHeaderHooks(t *testing.T) { | ||
TestOnlyClearRegisteredExtras() | ||
defer TestOnlyClearRegisteredExtras() | ||
|
||
extras := RegisterExtras[stubHeaderHooks, *stubHeaderHooks, struct{}]() | ||
rng := ethtest.NewPseudoRand(13579) | ||
|
||
t.Run("EncodeRLP", func(t *testing.T) { | ||
suffix := rng.Bytes(8) | ||
|
||
hdr := &Header{ | ||
ParentHash: rng.Hash(), | ||
} | ||
extras.Header.Get(hdr).rlpSuffix = append([]byte{}, suffix...) | ||
|
||
got, err := rlp.EncodeToBytes(hdr) | ||
require.NoError(t, err, "rlp.EncodeToBytes(%T)", hdr) | ||
assert.Equal(t, fakeHeaderRLP(hdr, suffix), got) | ||
}) | ||
|
||
t.Run("DecodeRLP", func(t *testing.T) { | ||
input, err := rlp.EncodeToBytes(rng.Bytes(8)) | ||
require.NoError(t, err) | ||
|
||
hdr := new(Header) | ||
stub := &stubHeaderHooks{ | ||
setHeaderToOnDecode: Header{ | ||
Extra: []byte("arr4n was here"), | ||
}, | ||
} | ||
extras.Header.Set(hdr, stub) | ||
err = rlp.DecodeBytes(input, hdr) | ||
require.NoErrorf(t, err, "rlp.DecodeBytes(%#x)", input) | ||
|
||
assert.Equal(t, input, stub.gotRawRLPToDecode, "raw RLP received by hooks") | ||
assert.Equalf(t, &stub.setHeaderToOnDecode, hdr, "%T after RLP decoding with hook", hdr) | ||
}) | ||
|
||
t.Run("error_propagation", func(t *testing.T) { | ||
errEncode := errors.New("uh oh") | ||
errDecode := errors.New("something bad happened") | ||
|
||
hdr := new(Header) | ||
extras.Header.Set(hdr, &stubHeaderHooks{ | ||
errEncode: errEncode, | ||
errDecode: errDecode, | ||
}) | ||
|
||
assert.Equal(t, errEncode, rlp.Encode(io.Discard, hdr), "via rlp.Encode()") | ||
assert.Equal(t, errDecode, rlp.DecodeBytes([]byte{0}, hdr), "via rlp.DecodeBytes()") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.