Skip to content

Commit

Permalink
Merge branch 'reconstruct-capella-block' into capella
Browse files Browse the repository at this point in the history
  • Loading branch information
rkapka committed Dec 6, 2022
2 parents 57bdb90 + c1f29ea commit b060158
Show file tree
Hide file tree
Showing 17 changed files with 499 additions and 116 deletions.
12 changes: 6 additions & 6 deletions beacon-chain/blockchain/execution_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,14 @@ func Test_NotifyNewPayload(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &mockExecution.EngineClient{ErrNewPayload: tt.newPayloadErr, BlockByHashMap: map[[32]byte]*v1.ExecutionBlock{}}
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlock{
e := &mockExecution.EngineClient{ErrNewPayload: tt.newPayloadErr, BlockByHashMap: map[[32]byte]*v1.ExecutionBlockBellatrix{}}
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.BytesToHash([]byte("b")),
},
TotalDifficulty: "0x2",
}
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlock{
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.BytesToHash([]byte("3")),
},
Expand Down Expand Up @@ -759,14 +759,14 @@ func Test_NotifyNewPayload_SetOptimisticToValid(t *testing.T) {
require.NoError(t, err)
service, err := NewService(ctx, opts...)
require.NoError(t, err)
e := &mockExecution.EngineClient{BlockByHashMap: map[[32]byte]*v1.ExecutionBlock{}}
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlock{
e := &mockExecution.EngineClient{BlockByHashMap: map[[32]byte]*v1.ExecutionBlockBellatrix{}}
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.BytesToHash([]byte("b")),
},
TotalDifficulty: "0x2",
}
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlock{
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.BytesToHash([]byte("3")),
},
Expand Down
14 changes: 7 additions & 7 deletions beacon-chain/blockchain/pow_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,18 @@ func Test_validateMergeBlock(t *testing.T) {
service, err := NewService(ctx, opts...)
require.NoError(t, err)

engine := &mocks.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
engine := &mocks.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlockBellatrix{}}
service.cfg.ExecutionEngineCaller = engine
a := [32]byte{'a'}
b := [32]byte{'b'}
mergeBlockParentHash := [32]byte{'3'}
engine.BlockByHashMap[a] = &enginev1.ExecutionBlock{
engine.BlockByHashMap[a] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: b,
},
TotalDifficulty: "0x2",
}
engine.BlockByHashMap[b] = &enginev1.ExecutionBlock{
engine.BlockByHashMap[b] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: mergeBlockParentHash,
},
Expand Down Expand Up @@ -168,12 +168,12 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
service, err := NewService(ctx, opts...)
require.NoError(t, err)

engine := &mocks.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
engine := &mocks.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlockBellatrix{}}
service.cfg.ExecutionEngineCaller = engine
h := [32]byte{'a'}
p := [32]byte{'b'}
td := "0x1"
engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
engine.BlockByHashMap[h] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: p,
},
Expand All @@ -191,7 +191,7 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
_, _, err = service.getBlkParentHashAndTD(ctx, h[:])
require.ErrorContains(t, "pow block is nil", err)

engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
engine.BlockByHashMap[h] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: p,
},
Expand All @@ -200,7 +200,7 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
_, _, err = service.getBlkParentHashAndTD(ctx, h[:])
require.ErrorContains(t, "could not decode merge block total difficulty: hex string without 0x prefix", err)

engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
engine.BlockByHashMap[h] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: p,
},
Expand Down
6 changes: 3 additions & 3 deletions beacon-chain/blockchain/process_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1285,14 +1285,14 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &mockExecution.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
e.BlockByHashMap[aHash] = &enginev1.ExecutionBlock{
e := &mockExecution.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlockBellatrix{}}
e.BlockByHashMap[aHash] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: bHash,
},
TotalDifficulty: "0x2",
}
e.BlockByHashMap[bHash] = &enginev1.ExecutionBlock{
e.BlockByHashMap[bHash] = &enginev1.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.BytesToHash([]byte("3")),
},
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/execution/check_transition_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func TestService_logTtdStatus(t *testing.T) {
require.NoError(t, r.Body.Close())
}()

resp := &pb.ExecutionBlock{
resp := &pb.ExecutionBlockBellatrix{
Header: gethtypes.Header{
ParentHash: common.Hash{},
UncleHash: common.Hash{},
Expand Down Expand Up @@ -219,7 +219,7 @@ func TestService_logTtdStatus_NotSyncedClient(t *testing.T) {
require.NoError(t, r.Body.Close())
}()

resp := (*pb.ExecutionBlock)(nil) // Nil response when a client is not synced
resp := (*pb.ExecutionBlockBellatrix)(nil) // Nil response when a client is not synced
respJSON := map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
Expand Down
85 changes: 63 additions & 22 deletions beacon-chain/execution/engine_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type ForkchoiceUpdatedResponse struct {
// block with an execution payload from a signed beacon block and a connection
// to an execution client's engine API.
type ExecutionPayloadReconstructor interface {
ReconstructFullBellatrixBlock(
ReconstructFullBlock(
ctx context.Context, blindedBlock interfaces.SignedBeaconBlock,
) (interfaces.SignedBeaconBlock, error)
ReconstructFullBellatrixBlockBatch(
Expand All @@ -82,7 +82,7 @@ type EngineCaller interface {
ExchangeTransitionConfiguration(
ctx context.Context, cfg *pb.TransitionConfiguration,
) error
ExecutionBlockByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlock, error)
ExecutionBlockByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlockBellatrix, error)
GetTerminalBlockHash(ctx context.Context, transitionTime uint64) ([]byte, bool, error)
}

Expand Down Expand Up @@ -346,11 +346,11 @@ func (s *Service) GetTerminalBlockHash(ctx context.Context, transitionTime uint6

// LatestExecutionBlock fetches the latest execution engine block by calling
// eth_blockByNumber via JSON-RPC.
func (s *Service) LatestExecutionBlock(ctx context.Context) (*pb.ExecutionBlock, error) {
func (s *Service) LatestExecutionBlock(ctx context.Context) (*pb.ExecutionBlockBellatrix, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.LatestExecutionBlock")
defer span.End()

result := &pb.ExecutionBlock{}
result := &pb.ExecutionBlockBellatrix{}
err := s.rpcClient.CallContext(
ctx,
result,
Expand All @@ -363,28 +363,38 @@ func (s *Service) LatestExecutionBlock(ctx context.Context) (*pb.ExecutionBlock,

// ExecutionBlockByHash fetches an execution engine block by hash by calling
// eth_blockByHash via JSON-RPC.
func (s *Service) ExecutionBlockByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlock, error) {
func (s *Service) ExecutionBlockByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlockBellatrix, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExecutionBlockByHash")
defer span.End()
result := &pb.ExecutionBlock{}
result := &pb.ExecutionBlockBellatrix{}
err := s.rpcClient.CallContext(ctx, result, ExecutionBlockByHashMethod, hash, withTxs)
return result, handleRPCError(err)
}

// ExecutionBlockCapellaByHash fetches an execution engine block by hash by calling
// eth_blockByHash via JSON-RPC.
func (s *Service) ExecutionBlockCapellaByHash(ctx context.Context, hash common.Hash, withTxs bool) (*pb.ExecutionBlockCapella, error) {
ctx, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExecutionBlockCapellaByHash")
defer span.End()
result := &pb.ExecutionBlockCapella{}
err := s.rpcClient.CallContext(ctx, result, ExecutionBlockByHashMethod, hash, withTxs)
return result, handleRPCError(err)
}

// ExecutionBlocksByHashes fetches a batch of execution engine blocks by hash by calling
// eth_blockByHash via JSON-RPC.
func (s *Service) ExecutionBlocksByHashes(ctx context.Context, hashes []common.Hash, withTxs bool) ([]*pb.ExecutionBlock, error) {
func (s *Service) ExecutionBlocksByHashes(ctx context.Context, hashes []common.Hash, withTxs bool) ([]*pb.ExecutionBlockBellatrix, error) {
_, span := trace.StartSpan(ctx, "powchain.engine-api-client.ExecutionBlocksByHashes")
defer span.End()
numOfHashes := len(hashes)
elems := make([]gethRPC.BatchElem, 0, numOfHashes)
execBlks := make([]*pb.ExecutionBlock, 0, numOfHashes)
execBlks := make([]*pb.ExecutionBlockBellatrix, 0, numOfHashes)
errs := make([]error, 0, numOfHashes)
if numOfHashes == 0 {
return execBlks, nil
}
for _, h := range hashes {
blk := &pb.ExecutionBlock{}
blk := &pb.ExecutionBlockBellatrix{}
err := error(nil)
newH := h
elems = append(elems, gethRPC.BatchElem{
Expand Down Expand Up @@ -428,9 +438,9 @@ func (s *Service) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H
return hdr, err
}

// ReconstructFullBellatrixBlock takes in a blinded beacon block and reconstructs
// ReconstructFullBlock takes in a blinded beacon block and reconstructs
// a beacon block with a full execution payload via the engine API.
func (s *Service) ReconstructFullBellatrixBlock(
func (s *Service) ReconstructFullBlock(
ctx context.Context, blindedBlock interfaces.SignedBeaconBlock,
) (interfaces.SignedBeaconBlock, error) {
if err := blocks.BeaconBlockIsNil(blindedBlock); err != nil {
Expand All @@ -455,7 +465,12 @@ func (s *Service) ReconstructFullBellatrixBlock(
}

executionBlockHash := common.BytesToHash(header.BlockHash())
executionBlock, err := s.ExecutionBlockByHash(ctx, executionBlockHash, true /* with txs */)
var executionBlock pb.ExecutionBlock
if blindedBlock.Version() == version.Bellatrix {
executionBlock, err = s.ExecutionBlockByHash(ctx, executionBlockHash, true /* with txs */)
} else {
executionBlock, err = s.ExecutionBlockCapellaByHash(ctx, executionBlockHash, true /* with txs */)
}
if err != nil {
return nil, fmt.Errorf("could not fetch execution block with txs by hash %#x: %v", executionBlockHash, err)
}
Expand All @@ -466,7 +481,7 @@ func (s *Service) ReconstructFullBellatrixBlock(
if err != nil {
return nil, err
}
fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload)
fullBlock, err := blocks.BuildSignedBeaconBlockFromExecutionPayload(blindedBlock, payload.Proto())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -550,27 +565,52 @@ func (s *Service) ReconstructFullBellatrixBlockBatch(
}

func fullPayloadFromExecutionBlock(
header interfaces.ExecutionData, block *pb.ExecutionBlock,
) (*pb.ExecutionPayload, error) {
header interfaces.ExecutionData, block pb.ExecutionBlock,
) (interfaces.ExecutionData, error) {
if header.IsNil() || block == nil {
return nil, errors.New("execution block and header cannot be nil")
}
if !bytes.Equal(header.BlockHash(), block.Hash[:]) {
blockHash := block.GetHash()
if !bytes.Equal(header.BlockHash(), blockHash[:]) {
return nil, fmt.Errorf(
"block hash field in execution header %#x does not match execution block hash %#x",
header.BlockHash(),
block.Hash,
blockHash,
)
}
txs := make([][]byte, len(block.Transactions))
for i, tx := range block.Transactions {
blockTransactions := block.GetTransactions()
txs := make([][]byte, len(blockTransactions))
for i, tx := range blockTransactions {
txBin, err := tx.MarshalBinary()
if err != nil {
return nil, err
}
txs[i] = txBin
}
return &pb.ExecutionPayload{

if block.Version() == version.Bellatrix {
return blocks.WrappedExecutionPayload(&pb.ExecutionPayload{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
StateRoot: header.StateRoot(),
ReceiptsRoot: header.ReceiptsRoot(),
LogsBloom: header.LogsBloom(),
PrevRandao: header.PrevRandao(),
BlockNumber: header.BlockNumber(),
GasLimit: header.GasLimit(),
GasUsed: header.GasUsed(),
Timestamp: header.Timestamp(),
ExtraData: header.ExtraData(),
BaseFeePerGas: header.BaseFeePerGas(),
BlockHash: blockHash[:],
Transactions: txs,
})
}
withdrawals, err := block.GetWithdrawals()
if err != nil {
return nil, err
}
return blocks.WrappedExecutionPayloadCapella(&pb.ExecutionPayloadCapella{
ParentHash: header.ParentHash(),
FeeRecipient: header.FeeRecipient(),
StateRoot: header.StateRoot(),
Expand All @@ -583,9 +623,10 @@ func fullPayloadFromExecutionBlock(
Timestamp: header.Timestamp(),
ExtraData: header.ExtraData(),
BaseFeePerGas: header.BaseFeePerGas(),
BlockHash: block.Hash[:],
BlockHash: blockHash[:],
Transactions: txs,
}, nil
Withdrawals: withdrawals,
})
}

// Handles errors received from the RPC server according to the specification.
Expand Down
12 changes: 6 additions & 6 deletions beacon-chain/execution/engine_client_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func FuzzExecutionBlock(f *testing.F) {
S: big.NewInt(math.MaxInt),
}
tx := types.NewTx(innerData)
execBlock := &pb.ExecutionBlock{
execBlock := &pb.ExecutionBlockBellatrix{
Header: types.Header{
ParentHash: common.Hash([32]byte{0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01}),
Root: common.Hash([32]byte{0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01}),
Expand All @@ -203,7 +203,7 @@ func FuzzExecutionBlock(f *testing.F) {

f.Fuzz(func(t *testing.T, jsonBlob []byte) {
gethResp := make(map[string]interface{})
prysmResp := &pb.ExecutionBlock{}
prysmResp := &pb.ExecutionBlockBellatrix{}
gethErr := json.Unmarshal(jsonBlob, &gethResp)
prysmErr := json.Unmarshal(jsonBlob, prysmResp)
// Nothing to marshal if we have an error.
Expand Down Expand Up @@ -237,7 +237,7 @@ func FuzzExecutionBlock(f *testing.F) {
})
}

func isBogusTransactionHash(blk *pb.ExecutionBlock, jsonMap map[string]interface{}) bool {
func isBogusTransactionHash(blk *pb.ExecutionBlockBellatrix, jsonMap map[string]interface{}) bool {
if blk.Transactions == nil {
return false
}
Expand All @@ -260,7 +260,7 @@ func isBogusTransactionHash(blk *pb.ExecutionBlock, jsonMap map[string]interface

func compareHeaders(t *testing.T, jsonBlob []byte) {
gethResp := &types.Header{}
prysmResp := &pb.ExecutionBlock{}
prysmResp := &pb.ExecutionBlockBellatrix{}
gethErr := json.Unmarshal(jsonBlob, gethResp)
prysmErr := json.Unmarshal(jsonBlob, prysmResp)
assert.Equal(t, gethErr != nil, prysmErr != nil, fmt.Sprintf("geth and prysm unmarshaller return inconsistent errors. %v and %v", gethErr, prysmErr))
Expand All @@ -282,7 +282,7 @@ func compareHeaders(t *testing.T, jsonBlob []byte) {
assert.DeepEqual(t, newGethResp, newGethResp2)
}

func validateBlockConsistency(execBlock *pb.ExecutionBlock, jsonMap map[string]interface{}) error {
func validateBlockConsistency(execBlock *pb.ExecutionBlockBellatrix, jsonMap map[string]interface{}) error {
blockVal := reflect.ValueOf(execBlock).Elem()
bType := reflect.TypeOf(execBlock).Elem()

Expand Down Expand Up @@ -316,7 +316,7 @@ func validateBlockConsistency(execBlock *pb.ExecutionBlock, jsonMap map[string]i
return nil
}

func jsonFieldsAreValid(execBlock *pb.ExecutionBlock, jsonMap map[string]interface{}) (bool, error) {
func jsonFieldsAreValid(execBlock *pb.ExecutionBlockBellatrix, jsonMap map[string]interface{}) (bool, error) {
bType := reflect.TypeOf(execBlock).Elem()

fieldnum := bType.NumField()
Expand Down
Loading

0 comments on commit b060158

Please sign in to comment.