mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-15 17:30:44 +00:00
beacon/engine, eth/catalyst: return block access lists in payload bodies v2 (#35347)
This commit is contained in:
parent
e7314c8a13
commit
b34a925e9e
3 changed files with 99 additions and 12 deletions
|
|
@ -415,6 +415,12 @@ type ExecutionPayloadBody struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
}
|
||||
|
||||
// ExecutionPayloadBodyV2 extends ExecutionPayloadBody with the block access list.
|
||||
type ExecutionPayloadBodyV2 struct {
|
||||
ExecutionPayloadBody
|
||||
BlockAccessList *bal.BlockAccessList `json:"blockAccessList"`
|
||||
}
|
||||
|
||||
// Client identifiers to support ClientVersionV1.
|
||||
const (
|
||||
ClientCode = "GE"
|
||||
|
|
|
|||
|
|
@ -1176,13 +1176,13 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin
|
|||
return bodies
|
||||
}
|
||||
|
||||
// GetPayloadBodiesByHashV2 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list
|
||||
// GetPayloadBodiesByHashV2 implements engine_getPayloadBodiesByHashV2 which allows for retrieval of a list
|
||||
// of block bodies by the engine api.
|
||||
func (api *ConsensusAPI) GetPayloadBodiesByHashV2(hashes []common.Hash) []*engine.ExecutionPayloadBody {
|
||||
bodies := make([]*engine.ExecutionPayloadBody, len(hashes))
|
||||
func (api *ConsensusAPI) GetPayloadBodiesByHashV2(hashes []common.Hash) []*engine.ExecutionPayloadBodyV2 {
|
||||
bodies := make([]*engine.ExecutionPayloadBodyV2, len(hashes))
|
||||
for i, hash := range hashes {
|
||||
block := api.eth.BlockChain().GetBlockByHash(hash)
|
||||
bodies[i] = getBody(block)
|
||||
bodies[i] = getBodyV2(block)
|
||||
}
|
||||
return bodies
|
||||
}
|
||||
|
|
@ -1190,16 +1190,16 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV2(hashes []common.Hash) []*engin
|
|||
// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
|
||||
// of block bodies by the engine api.
|
||||
func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) {
|
||||
return api.getBodiesByRange(start, count)
|
||||
return getBodiesByRange(api, start, count, getBody)
|
||||
}
|
||||
|
||||
// GetPayloadBodiesByRangeV2 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
|
||||
// GetPayloadBodiesByRangeV2 implements engine_getPayloadBodiesByRangeV2 which allows for retrieval of a range
|
||||
// of block bodies by the engine api.
|
||||
func (api *ConsensusAPI) GetPayloadBodiesByRangeV2(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) {
|
||||
return api.getBodiesByRange(start, count)
|
||||
func (api *ConsensusAPI) GetPayloadBodiesByRangeV2(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBodyV2, error) {
|
||||
return getBodiesByRange(api, start, count, getBodyV2)
|
||||
}
|
||||
|
||||
func (api *ConsensusAPI) getBodiesByRange(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBody, error) {
|
||||
func getBodiesByRange[T any](api *ConsensusAPI, start, count hexutil.Uint64, getBody func(*types.Block) *T) ([]*T, error) {
|
||||
if start == 0 || count == 0 {
|
||||
return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
|
||||
}
|
||||
|
|
@ -1212,7 +1212,7 @@ func (api *ConsensusAPI) getBodiesByRange(start, count hexutil.Uint64) ([]*engin
|
|||
if last > current {
|
||||
last = current
|
||||
}
|
||||
bodies := make([]*engine.ExecutionPayloadBody, 0, uint64(count))
|
||||
bodies := make([]*T, 0, uint64(count))
|
||||
for i := uint64(start); i <= last; i++ {
|
||||
block := api.eth.BlockChain().GetBlockByNumber(i)
|
||||
bodies = append(bodies, getBody(block))
|
||||
|
|
@ -1241,6 +1241,17 @@ func getBody(block *types.Block) *engine.ExecutionPayloadBody {
|
|||
return &result
|
||||
}
|
||||
|
||||
func getBodyV2(block *types.Block) *engine.ExecutionPayloadBodyV2 {
|
||||
body := getBody(block)
|
||||
if body == nil {
|
||||
return nil
|
||||
}
|
||||
return &engine.ExecutionPayloadBodyV2{
|
||||
ExecutionPayloadBody: *body,
|
||||
BlockAccessList: block.AccessList(),
|
||||
}
|
||||
}
|
||||
|
||||
// convertRequests converts a hex requests slice to plain [][]byte.
|
||||
func convertRequests(hex []hexutil.Bytes) [][]byte {
|
||||
if hex == nil {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/types/bal"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
|
|
@ -1366,7 +1367,7 @@ func TestGetBlockBodiesByHash(t *testing.T) {
|
|||
for k, test := range tests {
|
||||
result := api.GetPayloadBodiesByHashV2(test.hashes)
|
||||
for i, r := range result {
|
||||
if err := checkEqualBody(test.results[i], r); err != nil {
|
||||
if err := checkEqualBodyV2(test.results[i], r); err != nil {
|
||||
t.Fatalf("test %v: invalid response: %v\nexpected %+v\ngot %+v", k, err, test.results[i], r)
|
||||
}
|
||||
}
|
||||
|
|
@ -1444,7 +1445,7 @@ func TestGetBlockBodiesByRange(t *testing.T) {
|
|||
}
|
||||
if len(result) == len(test.results) {
|
||||
for i, r := range result {
|
||||
if err := checkEqualBody(test.results[i], r); err != nil {
|
||||
if err := checkEqualBodyV2(test.results[i], r); err != nil {
|
||||
t.Fatalf("test %d: invalid response: %v\nexpected %+v\ngot %+v", k, err, test.results[i], r)
|
||||
}
|
||||
}
|
||||
|
|
@ -1520,6 +1521,75 @@ func checkEqualBody(a *types.Body, b *engine.ExecutionPayloadBody) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkEqualBodyV2(a *types.Body, b *engine.ExecutionPayloadBodyV2) error {
|
||||
if b == nil {
|
||||
return checkEqualBody(a, nil)
|
||||
}
|
||||
return checkEqualBody(a, &b.ExecutionPayloadBody)
|
||||
}
|
||||
|
||||
func TestGetPayloadBodyV2BlockAccessList(t *testing.T) {
|
||||
empty := bal.BlockAccessList{}
|
||||
emptyHash := empty.Hash()
|
||||
tests := []struct {
|
||||
name string
|
||||
header *types.Header
|
||||
accessList *bal.BlockAccessList
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "retained empty BAL",
|
||||
header: &types.Header{BlockAccessListHash: &emptyHash},
|
||||
accessList: &empty,
|
||||
want: "[]",
|
||||
},
|
||||
{
|
||||
name: "pruned BAL",
|
||||
header: &types.Header{BlockAccessListHash: &emptyHash},
|
||||
want: "null",
|
||||
},
|
||||
{
|
||||
name: "pre-Amsterdam block",
|
||||
header: new(types.Header),
|
||||
want: "null",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
block := types.NewBlockWithHeader(test.header).WithAccessListUnsafe(test.accessList)
|
||||
body := getBodyV2(block)
|
||||
encoded, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var fields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(encoded, &fields); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := string(fields["blockAccessList"]); got != test.want {
|
||||
t.Fatalf("unexpected blockAccessList: got %s, want %s", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPayloadBodyV1OmitsBlockAccessList(t *testing.T) {
|
||||
empty := bal.BlockAccessList{}
|
||||
emptyHash := empty.Hash()
|
||||
block := types.NewBlockWithHeader(&types.Header{BlockAccessListHash: &emptyHash}).WithAccessListUnsafe(&empty)
|
||||
encoded, err := json.Marshal(getBody(block))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var fields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(encoded, &fields); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, ok := fields["blockAccessList"]; ok {
|
||||
t.Fatal("V1 payload body contains blockAccessList")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockToPayloadWithBlobs(t *testing.T) {
|
||||
header := types.Header{}
|
||||
var txs []*types.Transaction
|
||||
|
|
|
|||
Loading…
Reference in a new issue