adding consolidation requests to json serialization (#14229)

* adding consolidation requests to json serialization

* fixing test

* missed file checkin

* fixing unit tests
This commit is contained in:
james-prysm
2024-07-17 08:24:15 -05:00
committed by GitHub
parent 637cbc88e8
commit 2f76ba542f
6 changed files with 196 additions and 84 deletions

View File

@@ -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)

View File

@@ -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)
@@ -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{

View File

@@ -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
}

View File

@@ -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.
@@ -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))
@@ -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 {
@@ -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
}

View File

@@ -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'}},
@@ -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)
@@ -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)

View File

@@ -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),
},
},
}
}