Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding consolidation requests to json serialization #14229

Merged
merged 5 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 24 additions & 19 deletions beacon-chain/execution/engine_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,27 +612,32 @@ func fullPayloadFromPayloadBody(
if err != nil {
return nil, err
}
cr, err := pb.JsonConsolidationRequestsToProto(body.ConsolidationRequests)
if err != nil {
return nil, err
}
return blocks.WrappedExecutionPayloadElectra(
&pb.ExecutionPayloadElectra{
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: header.BlockHash(),
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
Withdrawals: body.Withdrawals,
ExcessBlobGas: ebg,
BlobGasUsed: bgu,
DepositRequests: dr,
WithdrawalRequests: wr,
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: header.BlockHash(),
Transactions: pb.RecastHexutilByteSlice(body.Transactions),
Withdrawals: body.Withdrawals,
ExcessBlobGas: ebg,
BlobGasUsed: bgu,
DepositRequests: dr,
WithdrawalRequests: wr,
ConsolidationRequests: cr,
}) // We can't get the block value and don't care about the block value for this instance
default:
return nil, fmt.Errorf("unknown execution block version for payload %d", bVersion)
Expand Down
57 changes: 38 additions & 19 deletions beacon-chain/execution/engine_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,20 @@ func fixturesStruct() *payloadFixtures {
Index: &idx,
}
}
consolidationRequests := make([]pb.ConsolidationRequestV1, 1)
for i := range consolidationRequests {
address := &common.Address{}
address.SetBytes([]byte{0, 0, byte(i)})
sPubkey := pb.BlsPubkey{}
copy(sPubkey[:], []byte{0, byte(i)})
tPubkey := pb.BlsPubkey{}
copy(tPubkey[:], []byte{0, byte(i)})
consolidationRequests[i] = pb.ConsolidationRequestV1{
SourceAddress: address,
SourcePubkey: &sPubkey,
TargetPubkey: &tPubkey,
}
}
dr, err := pb.JsonDepositRequestsToProto(depositRequests)
if err != nil {
panic(err)
Expand All @@ -1541,26 +1555,31 @@ func fixturesStruct() *payloadFixtures {
if err != nil {
panic(err)
}
cr, err := pb.JsonConsolidationRequestsToProto(consolidationRequests)
if err != nil {
panic(err)
}
executionPayloadFixtureElectra := &pb.ExecutionPayloadElectra{
ParentHash: foo[:],
FeeRecipient: bar,
StateRoot: foo[:],
ReceiptsRoot: foo[:],
LogsBloom: baz,
PrevRandao: foo[:],
BlockNumber: 1,
GasLimit: 1,
GasUsed: 1,
Timestamp: 1,
ExtraData: foo[:],
BaseFeePerGas: bytesutil.PadTo(baseFeePerGas.Bytes(), fieldparams.RootLength),
BlockHash: foo[:],
Transactions: [][]byte{foo[:]},
Withdrawals: []*pb.Withdrawal{},
BlobGasUsed: 2,
ExcessBlobGas: 3,
DepositRequests: dr,
WithdrawalRequests: wr,
ParentHash: foo[:],
FeeRecipient: bar,
StateRoot: foo[:],
ReceiptsRoot: foo[:],
LogsBloom: baz,
PrevRandao: foo[:],
BlockNumber: 1,
GasLimit: 1,
GasUsed: 1,
Timestamp: 1,
ExtraData: foo[:],
BaseFeePerGas: bytesutil.PadTo(baseFeePerGas.Bytes(), fieldparams.RootLength),
BlockHash: foo[:],
Transactions: [][]byte{foo[:]},
Withdrawals: []*pb.Withdrawal{},
BlobGasUsed: 2,
ExcessBlobGas: 3,
DepositRequests: dr,
WithdrawalRequests: wr,
ConsolidationRequests: cr,
}
hexUint := hexutil.Uint64(1)
executionPayloadWithValueFixtureCapella := &pb.GetPayloadV2ResponseJson{
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/execution/payload_body_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func payloadToBody(t *testing.T, ed interfaces.ExecutionData) *pb.ExecutionPaylo
if isElectra {
body.DepositRequests = pb.ProtoDepositRequestsToJson(eed.DepositRequests())
body.WithdrawalRequests = pb.ProtoWithdrawalRequestsToJson(eed.WithdrawalRequests())
body.ConsolidationRequests = pb.ProtoConsolidationRequestsToJson(eed.ConsolidationRequests())
}
return body
}
Expand Down
151 changes: 109 additions & 42 deletions proto/engine/v1/json_marshal_unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,33 +306,35 @@ type GetPayloadV4ResponseJson struct {

// ExecutionPayloadElectraJSON represents the engine API ExecutionPayloadV4 type.
type ExecutionPayloadElectraJSON struct {
ParentHash *common.Hash `json:"parentHash"`
FeeRecipient *common.Address `json:"feeRecipient"`
StateRoot *common.Hash `json:"stateRoot"`
ReceiptsRoot *common.Hash `json:"receiptsRoot"`
LogsBloom *hexutil.Bytes `json:"logsBloom"`
PrevRandao *common.Hash `json:"prevRandao"`
BlockNumber *hexutil.Uint64 `json:"blockNumber"`
GasLimit *hexutil.Uint64 `json:"gasLimit"`
GasUsed *hexutil.Uint64 `json:"gasUsed"`
Timestamp *hexutil.Uint64 `json:"timestamp"`
ExtraData hexutil.Bytes `json:"extraData"`
BaseFeePerGas string `json:"baseFeePerGas"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
BlockHash *common.Hash `json:"blockHash"`
Transactions []hexutil.Bytes `json:"transactions"`
Withdrawals []*Withdrawal `json:"withdrawals"`
WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"`
DepositRequests []DepositRequestV1 `json:"depositRequests"`
ParentHash *common.Hash `json:"parentHash"`
FeeRecipient *common.Address `json:"feeRecipient"`
StateRoot *common.Hash `json:"stateRoot"`
ReceiptsRoot *common.Hash `json:"receiptsRoot"`
LogsBloom *hexutil.Bytes `json:"logsBloom"`
PrevRandao *common.Hash `json:"prevRandao"`
BlockNumber *hexutil.Uint64 `json:"blockNumber"`
GasLimit *hexutil.Uint64 `json:"gasLimit"`
GasUsed *hexutil.Uint64 `json:"gasUsed"`
Timestamp *hexutil.Uint64 `json:"timestamp"`
ExtraData hexutil.Bytes `json:"extraData"`
BaseFeePerGas string `json:"baseFeePerGas"`
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
BlockHash *common.Hash `json:"blockHash"`
Transactions []hexutil.Bytes `json:"transactions"`
Withdrawals []*Withdrawal `json:"withdrawals"`
WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"`
DepositRequests []DepositRequestV1 `json:"depositRequests"`
ConsolidationRequests []ConsolidationRequestV1 `json:"consolidationRequests"`
}

// ExecutionPayloadBody represents the engine API ExecutionPayloadV1 or ExecutionPayloadV2 type.
type ExecutionPayloadBody struct {
Transactions []hexutil.Bytes `json:"transactions"`
Withdrawals []*Withdrawal `json:"withdrawals"`
WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"`
DepositRequests []DepositRequestV1 `json:"depositRequests"`
Transactions []hexutil.Bytes `json:"transactions"`
Withdrawals []*Withdrawal `json:"withdrawals"`
WithdrawalRequests []WithdrawalRequestV1 `json:"withdrawalRequests"`
DepositRequests []DepositRequestV1 `json:"depositRequests"`
ConsolidationRequests []ConsolidationRequestV1 `json:"consolidationRequests"`
}

// Validate returns an error if key fields in GetPayloadV4ResponseJson are nil or invalid.
Expand Down Expand Up @@ -468,6 +470,30 @@ func (r DepositRequestV1) Validate() error {
return nil
}

// ConsolidationRequestV1 represents an execution engine ConsolidationRequestV1 value
// https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#consolidationrequestv1
type ConsolidationRequestV1 struct {
// sourceAddress: DATA, 20 Bytes
SourceAddress *common.Address `json:"sourceAddress"`
// sourcePubkey: DATA, 48 Bytes
SourcePubkey *BlsPubkey `json:"sourcePubkey"`
// targetPubkey: DATA, 48 Bytes
TargetPubkey *BlsPubkey `json:"targetPubkey"`
}

func (r ConsolidationRequestV1) Validate() error {
if r.SourceAddress == nil {
return errors.Wrap(errJsonNilField, "missing required field 'sourceAddress' for ConsolidationRequestV1")
}
if r.SourcePubkey == nil {
return errors.Wrap(errJsonNilField, "missing required field 'sourcePubkey' for ConsolidationRequestV1")
}
if r.TargetPubkey == nil {
return errors.Wrap(errJsonNilField, "missing required field 'targetPubkey' for ConsolidationRequestV1")
}
return nil
}

// MarshalJSON --
func (e *ExecutionPayload) MarshalJSON() ([]byte, error) {
transactions := make([]hexutil.Bytes, len(e.Transactions))
Expand Down Expand Up @@ -1065,6 +1091,42 @@ func ProtoWithdrawalRequestsToJson(reqs []*WithdrawalRequest) []WithdrawalReques
return j
}

func JsonConsolidationRequestsToProto(j []ConsolidationRequestV1) ([]*ConsolidationRequest, error) {
reqs := make([]*ConsolidationRequest, len(j))

for i := range j {
req := j[i]
if err := req.Validate(); err != nil {
return nil, err
}
reqs[i] = &ConsolidationRequest{
SourceAddress: req.SourceAddress.Bytes(),
SourcePubkey: req.SourcePubkey.Bytes(),
TargetPubkey: req.TargetPubkey.Bytes(),
}
}

return reqs, nil
}

func ProtoConsolidationRequestsToJson(reqs []*ConsolidationRequest) []ConsolidationRequestV1 {
j := make([]ConsolidationRequestV1, len(reqs))
for i := range reqs {
r := reqs[i]
spk := BlsPubkey{}
copy(spk[:], r.SourcePubkey)
tpk := BlsPubkey{}
copy(tpk[:], r.TargetPubkey)
address := common.BytesToAddress(r.SourceAddress)
j[i] = ConsolidationRequestV1{
SourceAddress: &address,
SourcePubkey: &spk,
TargetPubkey: &tpk,
}
}
return j
}

func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra, error) {
baseFeeBigEnd, err := hexutil.DecodeBig(j.BaseFeePerGas)
if err != nil {
Expand All @@ -1087,26 +1149,31 @@ func (j *ExecutionPayloadElectraJSON) ElectraPayload() (*ExecutionPayloadElectra
if err != nil {
return nil, err
}
cr, err := JsonConsolidationRequestsToProto(j.ConsolidationRequests)
if err != nil {
return nil, err
}
return &ExecutionPayloadElectra{
ParentHash: j.ParentHash.Bytes(),
FeeRecipient: j.FeeRecipient.Bytes(),
StateRoot: j.StateRoot.Bytes(),
ReceiptsRoot: j.ReceiptsRoot.Bytes(),
LogsBloom: *j.LogsBloom,
PrevRandao: j.PrevRandao.Bytes(),
BlockNumber: uint64(*j.BlockNumber),
GasLimit: uint64(*j.GasLimit),
GasUsed: uint64(*j.GasUsed),
Timestamp: uint64(*j.Timestamp),
ExtraData: j.ExtraData,
BaseFeePerGas: baseFee,
BlockHash: j.BlockHash.Bytes(),
Transactions: transactions,
Withdrawals: j.Withdrawals,
BlobGasUsed: uint64(*j.BlobGasUsed),
ExcessBlobGas: uint64(*j.ExcessBlobGas),
DepositRequests: dr,
WithdrawalRequests: wr,
ParentHash: j.ParentHash.Bytes(),
FeeRecipient: j.FeeRecipient.Bytes(),
StateRoot: j.StateRoot.Bytes(),
ReceiptsRoot: j.ReceiptsRoot.Bytes(),
LogsBloom: *j.LogsBloom,
PrevRandao: j.PrevRandao.Bytes(),
BlockNumber: uint64(*j.BlockNumber),
GasLimit: uint64(*j.GasLimit),
GasUsed: uint64(*j.GasUsed),
Timestamp: uint64(*j.Timestamp),
ExtraData: j.ExtraData,
BaseFeePerGas: baseFee,
BlockHash: j.BlockHash.Bytes(),
Transactions: transactions,
Withdrawals: j.Withdrawals,
BlobGasUsed: uint64(*j.BlobGasUsed),
ExcessBlobGas: uint64(*j.ExcessBlobGas),
DepositRequests: dr,
WithdrawalRequests: wr,
ConsolidationRequests: cr,
}, nil
}

Expand Down
21 changes: 17 additions & 4 deletions proto/engine/v1/json_marshal_unmarshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
},
}

consolidationReq := []*enginev1.ConsolidationRequest{
{
SourceAddress: bytesutil.PadTo([]byte("sourceAddress-1"), 20),
SourcePubkey: bytesutil.PadTo([]byte("s-pubKey-1"), 48),
TargetPubkey: bytesutil.PadTo([]byte("t-pubKey-1"), 48),
},
}

resp := &enginev1.GetPayloadV4ResponseJson{
BlobsBundle: &enginev1.BlobBundleJSON{
Commitments: []hexutil.Bytes{{'a'}, {'b'}, {'c'}, {'d'}},
Expand Down Expand Up @@ -358,10 +366,11 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
Address: bytesutil.PadTo([]byte("address"), 20),
Amount: 1,
}},
BlobGasUsed: &bgu,
ExcessBlobGas: &ebg,
WithdrawalRequests: enginev1.ProtoWithdrawalRequestsToJson(withdrawalReq),
DepositRequests: enginev1.ProtoDepositRequestsToJson(depositReq),
BlobGasUsed: &bgu,
ExcessBlobGas: &ebg,
WithdrawalRequests: enginev1.ProtoWithdrawalRequestsToJson(withdrawalReq),
DepositRequests: enginev1.ProtoDepositRequestsToJson(depositReq),
ConsolidationRequests: enginev1.ProtoConsolidationRequestsToJson(consolidationReq),
},
}
enc, err := json.Marshal(resp)
Expand Down Expand Up @@ -414,6 +423,10 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
for i := range pb.Payload.DepositRequests {
require.DeepEqual(t, pb.Payload.DepositRequests[i], depositReq[i])
}
require.Equal(t, len(pb.Payload.ConsolidationRequests), len(consolidationReq))
for i := range pb.Payload.ConsolidationRequests {
require.DeepEqual(t, pb.Payload.ConsolidationRequests[i], consolidationReq[i])
}
})
t.Run("execution block", func(t *testing.T) {
baseFeePerGas := big.NewInt(1770307273)
Expand Down
7 changes: 7 additions & 0 deletions testing/util/electra.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ func GenerateTestElectraBlockWithSidecar(t *testing.T, parent [32]byte, slot pri
ExcessBlobGas: 0,
DepositRequests: generateTestDepositRequests(uint64(g.slot), 4),
WithdrawalRequests: generateTestWithdrawalRequests(uint64(g.slot), 4),
ConsolidationRequests: []*enginev1.ConsolidationRequest{
{
SourceAddress: make([]byte, 20),
SourcePubkey: make([]byte, 48),
TargetPubkey: make([]byte, 48),
},
},
}
}

Expand Down
Loading