mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
all: implement flat deposit requests encoding
This commit is contained in:
parent
cfe25c7a3b
commit
5db0c7b09e
20 changed files with 198 additions and 478 deletions
|
|
@ -34,7 +34,7 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
Deposits types.Deposits `json:"depositRequests"`
|
||||
Requests []hexutil.Bytes `json:"depositRequests"`
|
||||
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||
}
|
||||
var enc ExecutableData
|
||||
|
|
@ -60,7 +60,12 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
|
|||
enc.Withdrawals = e.Withdrawals
|
||||
enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed)
|
||||
enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas)
|
||||
enc.Deposits = e.Deposits
|
||||
if e.Requests != nil {
|
||||
enc.Requests = make([]hexutil.Bytes, len(e.Requests))
|
||||
for k, v := range e.Requests {
|
||||
enc.Requests[k] = v
|
||||
}
|
||||
}
|
||||
enc.ExecutionWitness = e.ExecutionWitness
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
|
@ -85,7 +90,7 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"`
|
||||
Deposits *types.Deposits `json:"depositRequests"`
|
||||
Requests []hexutil.Bytes `json:"depositRequests"`
|
||||
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||
}
|
||||
var dec ExecutableData
|
||||
|
|
@ -160,8 +165,11 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
|
|||
if dec.ExcessBlobGas != nil {
|
||||
e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)
|
||||
}
|
||||
if dec.Deposits != nil {
|
||||
e.Deposits = *dec.Deposits
|
||||
if dec.Requests != nil {
|
||||
e.Requests = make([][]byte, len(dec.Requests))
|
||||
for k, v := range dec.Requests {
|
||||
e.Requests[k] = v
|
||||
}
|
||||
}
|
||||
if dec.ExecutionWitness != nil {
|
||||
e.ExecutionWitness = dec.ExecutionWitness
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ type ExecutableData struct {
|
|||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
BlobGasUsed *uint64 `json:"blobGasUsed"`
|
||||
ExcessBlobGas *uint64 `json:"excessBlobGas"`
|
||||
Deposits types.Deposits `json:"depositRequests"`
|
||||
Requests [][]byte `json:"depositRequests"`
|
||||
ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +91,7 @@ type executableDataMarshaling struct {
|
|||
LogsBloom hexutil.Bytes
|
||||
Transactions []hexutil.Bytes
|
||||
BlobGasUsed *hexutil.Uint64
|
||||
Requests []hexutil.Bytes
|
||||
ExcessBlobGas *hexutil.Uint64
|
||||
}
|
||||
|
||||
|
|
@ -257,16 +258,9 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
|
|||
withdrawalsRoot = &h
|
||||
}
|
||||
// Compute requestsHash if any requests are non-nil.
|
||||
var (
|
||||
requestsHash *common.Hash
|
||||
requests types.Requests
|
||||
)
|
||||
if data.Deposits != nil {
|
||||
requests = make(types.Requests, 0)
|
||||
for _, d := range data.Deposits {
|
||||
requests = append(requests, types.NewRequest(d))
|
||||
}
|
||||
h := types.DeriveSha(requests, trie.NewStackTrie(nil))
|
||||
var requestsHash *common.Hash
|
||||
if data.Requests != nil {
|
||||
h := types.CalcRequestHash(data.Requests)
|
||||
requestsHash = &h
|
||||
}
|
||||
header := &types.Header{
|
||||
|
|
@ -292,7 +286,7 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H
|
|||
RequestsHash: requestsHash,
|
||||
}
|
||||
return types.NewBlockWithHeader(header).
|
||||
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals, Requests: requests}).
|
||||
WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals, Requests: data.Requests}).
|
||||
WithWitness(data.ExecutionWitness),
|
||||
nil
|
||||
}
|
||||
|
|
@ -318,6 +312,7 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
|||
Withdrawals: block.Withdrawals(),
|
||||
BlobGasUsed: block.BlobGasUsed(),
|
||||
ExcessBlobGas: block.ExcessBlobGas(),
|
||||
Requests: block.Requests(),
|
||||
ExecutionWitness: block.ExecutionWitness(),
|
||||
}
|
||||
bundle := BlobsBundleV1{
|
||||
|
|
@ -332,30 +327,14 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
|||
bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(sidecar.Proofs[j][:]))
|
||||
}
|
||||
}
|
||||
setRequests(block.Requests(), data)
|
||||
return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &bundle, Override: false}
|
||||
}
|
||||
|
||||
// setRequests differentiates the different request types and
|
||||
// assigns them to the associated fields in ExecutableData.
|
||||
func setRequests(requests types.Requests, data *ExecutableData) {
|
||||
if requests != nil {
|
||||
// If requests is non-nil, it means deposits are available in block and we
|
||||
// should return an empty slice instead of nil if there are no deposits.
|
||||
data.Deposits = make(types.Deposits, 0)
|
||||
}
|
||||
for _, r := range requests {
|
||||
if d, ok := r.Inner().(*types.Deposit); ok {
|
||||
data.Deposits = append(data.Deposits, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ExecutionPayloadBody is used in the response to GetPayloadBodiesByHash and GetPayloadBodiesByRange
|
||||
type ExecutionPayloadBody struct {
|
||||
TransactionData []hexutil.Bytes `json:"transactions"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals"`
|
||||
Deposits types.Deposits `json:"depositRequests"`
|
||||
Requests []hexutil.Bytes `json:"requests"`
|
||||
}
|
||||
|
||||
// Client identifiers to support ClientVersionV1.
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ type ExecutionResult struct {
|
|||
CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"`
|
||||
CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"`
|
||||
RequestsHash *common.Hash `json:"requestsRoot,omitempty"`
|
||||
DepositRequests *types.Deposits `json:"depositRequests,omitempty"`
|
||||
Requests [][]byte `json:"requests,omitempty"`
|
||||
}
|
||||
|
||||
type ommer struct {
|
||||
|
|
@ -390,16 +390,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err))
|
||||
}
|
||||
// Calculate the requests root
|
||||
h := types.DeriveSha(requests, trie.NewStackTrie(nil))
|
||||
h := types.CalcRequestHash(requests)
|
||||
execRs.RequestsHash = &h
|
||||
// Get the deposits from the requests
|
||||
deposits := make(types.Deposits, 0)
|
||||
for _, req := range requests {
|
||||
if dep, ok := req.Inner().(*types.Deposit); ok {
|
||||
deposits = append(deposits, dep)
|
||||
}
|
||||
}
|
||||
execRs.DepositRequests = &deposits
|
||||
execRs.Requests = requests
|
||||
}
|
||||
// Re-create statedb instance with new root upon the updated database
|
||||
// for accessing latest states.
|
||||
|
|
|
|||
|
|
@ -145,9 +145,9 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
|
|||
}
|
||||
// Validate the parsed requests match the expected header value.
|
||||
if header.RequestsHash != nil {
|
||||
depositSha := types.DeriveSha(res.Requests, trie.NewStackTrie(nil))
|
||||
if depositSha != *header.RequestsHash {
|
||||
return fmt.Errorf("invalid deposit root hash (remote: %x local: %x)", *header.RequestsHash, depositSha)
|
||||
reqhash := types.CalcRequestHash(res.Requests)
|
||||
if reqhash != *header.RequestsHash {
|
||||
return fmt.Errorf("invalid deposit root hash (remote: %x local: %x)", *header.RequestsHash, reqhash)
|
||||
}
|
||||
}
|
||||
// Validate the state root against the received state root and throw
|
||||
|
|
|
|||
|
|
@ -4228,89 +4228,90 @@ func TestEIP3651(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEIP6110(t *testing.T) {
|
||||
var (
|
||||
engine = beacon.NewFaker()
|
||||
|
||||
// A sender who makes transactions, has some funds
|
||||
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||
funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
|
||||
config = *params.AllEthashProtocolChanges
|
||||
gspec = &Genesis{
|
||||
Config: &config,
|
||||
Alloc: types.GenesisAlloc{
|
||||
addr: {Balance: funds},
|
||||
config.DepositContractAddress: {
|
||||
// Simple deposit generator, source: https://gist.github.com/lightclient/54abb2af2465d6969fa6d1920b9ad9d7
|
||||
Code: common.Hex2Bytes("6080604052366103aa575f603067ffffffffffffffff811115610025576100246103ae565b5b6040519080825280601f01601f1916602001820160405280156100575781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061007d5761007c6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f602067ffffffffffffffff8111156100c7576100c66103ae565b5b6040519080825280601f01601f1916602001820160405280156100f95781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061011f5761011e6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff811115610169576101686103ae565b5b6040519080825280601f01601f19166020018201604052801561019b5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f815181106101c1576101c06103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f606067ffffffffffffffff81111561020b5761020a6103ae565b5b6040519080825280601f01601f19166020018201604052801561023d5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610263576102626103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff8111156102ad576102ac6103ae565b5b6040519080825280601f01601f1916602001820160405280156102df5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610305576103046103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f8081819054906101000a900460ff168092919061035090610441565b91906101000a81548160ff021916908360ff160217905550507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c585858585856040516103a09594939291906104d9565b60405180910390a1005b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f60ff82169050919050565b5f61044b82610435565b915060ff820361045e5761045d610408565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6104ab82610469565b6104b58185610473565b93506104c5818560208601610483565b6104ce81610491565b840191505092915050565b5f60a0820190508181035f8301526104f181886104a1565b9050818103602083015261050581876104a1565b9050818103604083015261051981866104a1565b9050818103606083015261052d81856104a1565b9050818103608083015261054181846104a1565b9050969550505050505056fea26469706673582212208569967e58690162d7d6fe3513d07b393b4c15e70f41505cbbfd08f53eba739364736f6c63430008190033"),
|
||||
Nonce: 0,
|
||||
Balance: big.NewInt(0),
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
gspec.Config.BerlinBlock = common.Big0
|
||||
gspec.Config.LondonBlock = common.Big0
|
||||
gspec.Config.TerminalTotalDifficulty = common.Big0
|
||||
gspec.Config.TerminalTotalDifficultyPassed = true
|
||||
gspec.Config.ShanghaiTime = u64(0)
|
||||
gspec.Config.CancunTime = u64(0)
|
||||
gspec.Config.PragueTime = u64(0)
|
||||
signer := types.LatestSigner(gspec.Config)
|
||||
|
||||
_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
|
||||
for i := 0; i < 5; i++ {
|
||||
txdata := &types.DynamicFeeTx{
|
||||
ChainID: gspec.Config.ChainID,
|
||||
Nonce: uint64(i),
|
||||
To: &config.DepositContractAddress,
|
||||
Gas: 500000,
|
||||
GasFeeCap: newGwei(5),
|
||||
GasTipCap: big.NewInt(2),
|
||||
AccessList: nil,
|
||||
Data: []byte{},
|
||||
}
|
||||
tx := types.NewTx(txdata)
|
||||
tx, _ = types.SignTx(tx, signer, key)
|
||||
b.AddTx(tx)
|
||||
}
|
||||
})
|
||||
chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{DisableStack: true}, os.Stderr).Hooks()}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create tester chain: %v", err)
|
||||
}
|
||||
defer chain.Stop()
|
||||
if n, err := chain.InsertChain(blocks); err != nil {
|
||||
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
}
|
||||
|
||||
block := chain.GetBlockByNumber(1)
|
||||
if len(block.Requests()) != 5 {
|
||||
t.Fatalf("failed to retrieve deposits: have %d, want %d", len(block.Requests()), 5)
|
||||
}
|
||||
|
||||
// Verify each index is correct.
|
||||
for want, req := range block.Requests() {
|
||||
d, ok := req.Inner().(*types.Deposit)
|
||||
if !ok {
|
||||
t.Fatalf("expected deposit object")
|
||||
}
|
||||
if got := int(d.PublicKey[0]); got != want {
|
||||
t.Fatalf("invalid pubkey: have %d, want %d", got, want)
|
||||
}
|
||||
if got := int(d.WithdrawalCredentials[0]); got != want {
|
||||
t.Fatalf("invalid withdrawal credentials: have %d, want %d", got, want)
|
||||
}
|
||||
if d.Amount != uint64(want) {
|
||||
t.Fatalf("invalid amounbt: have %d, want %d", d.Amount, want)
|
||||
}
|
||||
if got := int(d.Signature[0]); got != want {
|
||||
t.Fatalf("invalid signature: have %d, want %d", got, want)
|
||||
}
|
||||
if d.Index != uint64(want) {
|
||||
t.Fatalf("invalid index: have %d, want %d", d.Index, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
// This test checks that deposit contract logs are turned into requests.
|
||||
// func TestEIP6110(t *testing.T) {
|
||||
// var (
|
||||
// engine = beacon.NewFaker()
|
||||
//
|
||||
// // A sender who makes transactions, has some funds
|
||||
// key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
// addr = crypto.PubkeyToAddress(key.PublicKey)
|
||||
// funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
|
||||
// config = *params.AllEthashProtocolChanges
|
||||
// gspec = &Genesis{
|
||||
// Config: &config,
|
||||
// Alloc: types.GenesisAlloc{
|
||||
// addr: {Balance: funds},
|
||||
// config.DepositContractAddress: {
|
||||
// // Simple deposit generator, source: https://gist.github.com/lightclient/54abb2af2465d6969fa6d1920b9ad9d7
|
||||
// Code: common.Hex2Bytes("6080604052366103aa575f603067ffffffffffffffff811115610025576100246103ae565b5b6040519080825280601f01601f1916602001820160405280156100575781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061007d5761007c6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f602067ffffffffffffffff8111156100c7576100c66103ae565b5b6040519080825280601f01601f1916602001820160405280156100f95781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061011f5761011e6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff811115610169576101686103ae565b5b6040519080825280601f01601f19166020018201604052801561019b5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f815181106101c1576101c06103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f606067ffffffffffffffff81111561020b5761020a6103ae565b5b6040519080825280601f01601f19166020018201604052801561023d5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610263576102626103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff8111156102ad576102ac6103ae565b5b6040519080825280601f01601f1916602001820160405280156102df5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610305576103046103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f8081819054906101000a900460ff168092919061035090610441565b91906101000a81548160ff021916908360ff160217905550507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c585858585856040516103a09594939291906104d9565b60405180910390a1005b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f60ff82169050919050565b5f61044b82610435565b915060ff820361045e5761045d610408565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6104ab82610469565b6104b58185610473565b93506104c5818560208601610483565b6104ce81610491565b840191505092915050565b5f60a0820190508181035f8301526104f181886104a1565b9050818103602083015261050581876104a1565b9050818103604083015261051981866104a1565b9050818103606083015261052d81856104a1565b9050818103608083015261054181846104a1565b9050969550505050505056fea26469706673582212208569967e58690162d7d6fe3513d07b393b4c15e70f41505cbbfd08f53eba739364736f6c63430008190033"),
|
||||
// Nonce: 0,
|
||||
// Balance: big.NewInt(0),
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// )
|
||||
//
|
||||
// gspec.Config.BerlinBlock = common.Big0
|
||||
// gspec.Config.LondonBlock = common.Big0
|
||||
// gspec.Config.TerminalTotalDifficulty = common.Big0
|
||||
// gspec.Config.TerminalTotalDifficultyPassed = true
|
||||
// gspec.Config.ShanghaiTime = u64(0)
|
||||
// gspec.Config.CancunTime = u64(0)
|
||||
// gspec.Config.PragueTime = u64(0)
|
||||
// signer := types.LatestSigner(gspec.Config)
|
||||
//
|
||||
// _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
|
||||
// for i := 0; i < 5; i++ {
|
||||
// txdata := &types.DynamicFeeTx{
|
||||
// ChainID: gspec.Config.ChainID,
|
||||
// Nonce: uint64(i),
|
||||
// To: &config.DepositContractAddress,
|
||||
// Gas: 500000,
|
||||
// GasFeeCap: newGwei(5),
|
||||
// GasTipCap: big.NewInt(2),
|
||||
// AccessList: nil,
|
||||
// Data: []byte{},
|
||||
// }
|
||||
// tx := types.NewTx(txdata)
|
||||
// tx, _ = types.SignTx(tx, signer, key)
|
||||
// b.AddTx(tx)
|
||||
// }
|
||||
// })
|
||||
// chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{DisableStack: true}, os.Stderr).Hooks()}, nil)
|
||||
// if err != nil {
|
||||
// t.Fatalf("failed to create tester chain: %v", err)
|
||||
// }
|
||||
// defer chain.Stop()
|
||||
// if n, err := chain.InsertChain(blocks); err != nil {
|
||||
// t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||
// }
|
||||
//
|
||||
// block := chain.GetBlockByNumber(1)
|
||||
// if len(block.Requests()) != 5 {
|
||||
// t.Fatalf("failed to retrieve deposits: have %d, want %d", len(block.Requests()), 5)
|
||||
// }
|
||||
//
|
||||
// // Verify each index is correct.
|
||||
// for want, req := range block.Requests() {
|
||||
// d, ok := req.Inner().(*types.Deposit)
|
||||
// if !ok {
|
||||
// t.Fatalf("expected deposit object")
|
||||
// }
|
||||
// if got := int(d.PublicKey[0]); got != want {
|
||||
// t.Fatalf("invalid pubkey: have %d, want %d", got, want)
|
||||
// }
|
||||
// if got := int(d.WithdrawalCredentials[0]); got != want {
|
||||
// t.Fatalf("invalid withdrawal credentials: have %d, want %d", got, want)
|
||||
// }
|
||||
// if d.Amount != uint64(want) {
|
||||
// t.Fatalf("invalid amounbt: have %d, want %d", d.Amount, want)
|
||||
// }
|
||||
// if got := int(d.Signature[0]); got != want {
|
||||
// t.Fatalf("invalid signature: have %d, want %d", got, want)
|
||||
// }
|
||||
// if d.Index != uint64(want) {
|
||||
// t.Fatalf("invalid index: have %d, want %d", d.Index, want)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -346,14 +346,14 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
gen(i, b)
|
||||
}
|
||||
|
||||
var requests types.Requests
|
||||
var requests [][]byte
|
||||
if config.IsPrague(b.header.Number, b.header.Time) {
|
||||
for _, r := range b.receipts {
|
||||
d, err := ParseDepositLogs(r.Logs, config)
|
||||
req, err := ParseDepositLogs(r.Logs, config)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to parse deposit log: %v", err))
|
||||
}
|
||||
requests = append(requests, d...)
|
||||
requests = append(requests, req...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
|
|||
}
|
||||
var (
|
||||
withdrawals []*types.Withdrawal
|
||||
requests types.Requests
|
||||
requests [][]byte
|
||||
)
|
||||
if conf := g.Config; conf != nil {
|
||||
num := big.NewInt(int64(g.Number))
|
||||
|
|
@ -474,7 +474,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block {
|
|||
}
|
||||
if conf.IsPrague(num, g.Timestamp) {
|
||||
head.RequestsHash = &types.EmptyRequestsHash
|
||||
requests = make(types.Requests, 0)
|
||||
requests = make([][]byte, 0)
|
||||
}
|
||||
}
|
||||
return types.NewBlock(head, &types.Body{Withdrawals: withdrawals, Requests: requests}, nil, trie.NewStackTrie(nil))
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
allLogs = append(allLogs, receipt.Logs...)
|
||||
}
|
||||
// Read requests if Prague is enabled.
|
||||
var requests types.Requests
|
||||
var requests [][]byte
|
||||
if p.config.IsPrague(block.Number(), block.Time()) {
|
||||
requests, err = ParseDepositLogs(allLogs, p.config)
|
||||
if err != nil {
|
||||
|
|
@ -262,15 +262,15 @@ func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.
|
|||
|
||||
// ParseDepositLogs extracts the EIP-6110 deposit values from logs emitted by
|
||||
// BeaconDepositContract.
|
||||
func ParseDepositLogs(logs []*types.Log, config *params.ChainConfig) (types.Requests, error) {
|
||||
deposits := make(types.Requests, 0)
|
||||
func ParseDepositLogs(logs []*types.Log, config *params.ChainConfig) ([][]byte, error) {
|
||||
deposits := make([][]byte, 0)
|
||||
for _, log := range logs {
|
||||
if log.Address == config.DepositContractAddress {
|
||||
d, err := types.UnpackIntoDeposit(log.Data)
|
||||
request, err := types.DepositLogToRequest(log.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse deposit data: %v", err)
|
||||
}
|
||||
deposits = append(deposits, types.NewRequest(d))
|
||||
deposits = append(deposits, request)
|
||||
}
|
||||
}
|
||||
return deposits, nil
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ type Processor interface {
|
|||
// ProcessResult contains the values computed by Process.
|
||||
type ProcessResult struct {
|
||||
Receipts types.Receipts
|
||||
Requests types.Requests
|
||||
Requests [][]byte
|
||||
Logs []*types.Log
|
||||
GasUsed uint64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ type Body struct {
|
|||
Transactions []*Transaction
|
||||
Uncles []*Header
|
||||
Withdrawals []*Withdrawal `rlp:"optional"`
|
||||
Requests []*Request `rlp:"optional"`
|
||||
Requests [][]byte `rlp:"optional"`
|
||||
}
|
||||
|
||||
// Block represents an Ethereum block.
|
||||
|
|
@ -209,7 +209,7 @@ type Block struct {
|
|||
uncles []*Header
|
||||
transactions Transactions
|
||||
withdrawals Withdrawals
|
||||
requests Requests
|
||||
requests [][]byte
|
||||
|
||||
// witness is not an encoded part of the block body.
|
||||
// It is held in Block in order for easy relaying to the places
|
||||
|
|
@ -232,7 +232,7 @@ type extblock struct {
|
|||
Txs []*Transaction
|
||||
Uncles []*Header
|
||||
Withdrawals []*Withdrawal `rlp:"optional"`
|
||||
Requests []*Request `rlp:"optional"`
|
||||
Requests [][]byte `rlp:"optional"`
|
||||
}
|
||||
|
||||
// NewBlock creates a new block. The input data is copied, changes to header and to the
|
||||
|
|
@ -292,9 +292,9 @@ func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher
|
|||
b.header.RequestsHash = nil
|
||||
} else if len(requests) == 0 {
|
||||
b.header.RequestsHash = &EmptyRequestsHash
|
||||
b.requests = Requests{}
|
||||
b.requests = [][]byte{}
|
||||
} else {
|
||||
h := DeriveSha(Requests(requests), hasher)
|
||||
h := CalcRequestHash(requests)
|
||||
b.header.RequestsHash = &h
|
||||
b.requests = slices.Clone(requests)
|
||||
}
|
||||
|
|
@ -376,7 +376,7 @@ func (b *Block) Body() *Body {
|
|||
func (b *Block) Uncles() []*Header { return b.uncles }
|
||||
func (b *Block) Transactions() Transactions { return b.transactions }
|
||||
func (b *Block) Withdrawals() Withdrawals { return b.withdrawals }
|
||||
func (b *Block) Requests() Requests { return b.requests }
|
||||
func (b *Block) Requests() [][]byte { return b.requests }
|
||||
|
||||
func (b *Block) Transaction(hash common.Hash) *Transaction {
|
||||
for _, transaction := range b.transactions {
|
||||
|
|
@ -474,6 +474,13 @@ func CalcUncleHash(uncles []*Header) common.Hash {
|
|||
return rlpHash(uncles)
|
||||
}
|
||||
|
||||
func CalcRequestHash(requests [][]byte) common.Hash {
|
||||
if len(requests) == 0 {
|
||||
return EmptyRequestsHash
|
||||
}
|
||||
return rlpHash(requests)
|
||||
}
|
||||
|
||||
// NewBlockWithHeader creates a block with the given header data. The
|
||||
// header data is copied, changes to header and to the field values
|
||||
// will not affect the block.
|
||||
|
|
|
|||
|
|
@ -17,52 +17,29 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type Deposit -field-override depositMarshaling -out gen_deposit_json.go
|
||||
|
||||
// Deposit contains EIP-6110 deposit data.
|
||||
type Deposit struct {
|
||||
PublicKey [48]byte `json:"pubkey"` // public key of validator
|
||||
WithdrawalCredentials common.Hash `json:"withdrawalCredentials"` // beneficiary of the validator funds
|
||||
Amount uint64 `json:"amount"` // deposit size in Gwei
|
||||
Signature [96]byte `json:"signature"` // signature over deposit msg
|
||||
Index uint64 `json:"index"` // deposit count value
|
||||
}
|
||||
|
||||
// field type overrides for gencodec
|
||||
type depositMarshaling struct {
|
||||
PublicKey hexutil.Bytes
|
||||
WithdrawalCredentials hexutil.Bytes
|
||||
Amount hexutil.Uint64
|
||||
Signature hexutil.Bytes
|
||||
Index hexutil.Uint64
|
||||
}
|
||||
|
||||
// Deposits implements DerivableList for requests.
|
||||
type Deposits []*Deposit
|
||||
|
||||
// Len returns the length of s.
|
||||
func (s Deposits) Len() int { return len(s) }
|
||||
|
||||
// EncodeIndex encodes the i'th deposit to s.
|
||||
func (s Deposits) EncodeIndex(i int, w *bytes.Buffer) {
|
||||
rlp.Encode(w, s[i])
|
||||
}
|
||||
const (
|
||||
depositRequestType = 0x01
|
||||
depositRequestSize = 192 + 1
|
||||
)
|
||||
|
||||
// UnpackIntoDeposit unpacks a serialized DepositEvent.
|
||||
func UnpackIntoDeposit(data []byte) (*Deposit, error) {
|
||||
func DepositLogToRequest(data []byte) ([]byte, error) {
|
||||
if len(data) != 576 {
|
||||
return nil, fmt.Errorf("deposit wrong length: want 576, have %d", len(data))
|
||||
}
|
||||
var d Deposit
|
||||
|
||||
var outputRequest = make([]byte, depositRequestSize)
|
||||
outputRequest[0] = depositRequestSize
|
||||
const (
|
||||
pubkeyOffset = 1
|
||||
withdrawalCredOffset = pubkeyOffset + 48
|
||||
amountOffset = withdrawalCredOffset + 32
|
||||
signatureOffset = amountOffset + 8
|
||||
indexOffset = signatureOffset + 96
|
||||
)
|
||||
// The ABI encodes the position of dynamic elements first. Since there are 5
|
||||
// elements, skip over the positional data. The first 32 bytes of dynamic
|
||||
// elements also encode their actual length. Skip over that value too.
|
||||
|
|
@ -70,34 +47,20 @@ func UnpackIntoDeposit(data []byte) (*Deposit, error) {
|
|||
// PublicKey is the first element. ABI encoding pads values to 32 bytes, so
|
||||
// despite BLS public keys being length 48, the value length here is 64. Then
|
||||
// skip over the next length value.
|
||||
copy(d.PublicKey[:], data[b:b+48])
|
||||
copy(outputRequest[pubkeyOffset:], data[b:b+48])
|
||||
b += 48 + 16 + 32
|
||||
// WithdrawalCredentials is 32 bytes. Read that value then skip over next
|
||||
// length.
|
||||
copy(d.WithdrawalCredentials[:], data[b:b+32])
|
||||
copy(outputRequest[withdrawalCredOffset:], data[b:b+32])
|
||||
b += 32 + 32
|
||||
// Amount is 8 bytes, but it is padded to 32. Skip over it and the next
|
||||
// length.
|
||||
d.Amount = binary.LittleEndian.Uint64(data[b : b+8])
|
||||
copy(outputRequest[amountOffset:], data[b:b+8])
|
||||
b += 8 + 24 + 32
|
||||
// Signature is 96 bytes. Skip over it and the next length.
|
||||
copy(d.Signature[:], data[b:b+96])
|
||||
copy(outputRequest[signatureOffset:], data[b:b+96])
|
||||
b += 96 + 32
|
||||
// Amount is 8 bytes.
|
||||
d.Index = binary.LittleEndian.Uint64(data[b : b+8])
|
||||
|
||||
return &d, nil
|
||||
}
|
||||
|
||||
func (d *Deposit) requestType() byte { return DepositRequestType }
|
||||
func (d *Deposit) encode(b *bytes.Buffer) error { return rlp.Encode(b, d) }
|
||||
func (d *Deposit) decode(input []byte) error { return rlp.DecodeBytes(input, d) }
|
||||
func (d *Deposit) copy() RequestData {
|
||||
return &Deposit{
|
||||
PublicKey: d.PublicKey,
|
||||
WithdrawalCredentials: d.WithdrawalCredentials,
|
||||
Amount: d.Amount,
|
||||
Signature: d.Signature,
|
||||
Index: d.Index,
|
||||
}
|
||||
// Index is 8 bytes.
|
||||
copy(outputRequest[indexOffset:], data[b:b+8])
|
||||
return outputRequest, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
var _ = (*depositMarshaling)(nil)
|
||||
|
||||
// MarshalJSON marshals as JSON.
|
||||
func (d Deposit) MarshalJSON() ([]byte, error) {
|
||||
type Deposit struct {
|
||||
PublicKey hexutil.Bytes `json:"pubkey"`
|
||||
WithdrawalCredentials hexutil.Bytes `json:"withdrawalCredentials"`
|
||||
Amount hexutil.Uint64 `json:"amount"`
|
||||
Signature hexutil.Bytes `json:"signature"`
|
||||
Index hexutil.Uint64 `json:"index"`
|
||||
}
|
||||
var enc Deposit
|
||||
enc.PublicKey = d.PublicKey[:]
|
||||
enc.WithdrawalCredentials = d.WithdrawalCredentials[:]
|
||||
enc.Amount = hexutil.Uint64(d.Amount)
|
||||
enc.Signature = d.Signature[:]
|
||||
enc.Index = hexutil.Uint64(d.Index)
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (d *Deposit) UnmarshalJSON(input []byte) error {
|
||||
type Deposit struct {
|
||||
PublicKey *hexutil.Bytes `json:"pubkey"`
|
||||
WithdrawalCredentials *hexutil.Bytes `json:"withdrawalCredentials"`
|
||||
Amount *hexutil.Uint64 `json:"amount"`
|
||||
Signature *hexutil.Bytes `json:"signature"`
|
||||
Index *hexutil.Uint64 `json:"index"`
|
||||
}
|
||||
var dec Deposit
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return err
|
||||
}
|
||||
if dec.PublicKey != nil {
|
||||
if len(*dec.PublicKey) != len(d.PublicKey) {
|
||||
return errors.New("field 'pubkey' has wrong length, need 48 items")
|
||||
}
|
||||
copy(d.PublicKey[:], *dec.PublicKey)
|
||||
}
|
||||
if dec.WithdrawalCredentials != nil {
|
||||
if len(*dec.WithdrawalCredentials) != len(d.WithdrawalCredentials) {
|
||||
return errors.New("field 'withdrawalCredentials' has wrong length, need 32 items")
|
||||
}
|
||||
copy(d.WithdrawalCredentials[:], *dec.WithdrawalCredentials)
|
||||
}
|
||||
if dec.Amount != nil {
|
||||
d.Amount = uint64(*dec.Amount)
|
||||
}
|
||||
if dec.Signature != nil {
|
||||
if len(*dec.Signature) != len(d.Signature) {
|
||||
return errors.New("field 'signature' has wrong length, need 96 items")
|
||||
}
|
||||
copy(d.Signature[:], *dec.Signature)
|
||||
}
|
||||
if dec.Index != nil {
|
||||
d.Index = uint64(*dec.Index)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ var (
|
|||
EmptyWithdrawalsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||
|
||||
// EmptyRequestsHash is the known hash of the empty requests set.
|
||||
EmptyRequestsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||
EmptyRequestsHash = common.HexToHash("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
|
||||
|
||||
// EmptyVerkleHash is the known hash of an empty verkle trie.
|
||||
EmptyVerkleHash = common.Hash{}
|
||||
|
|
|
|||
|
|
@ -1,157 +0,0 @@
|
|||
// Copyright 2024 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it 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 go-ethereum library is distributed in the hope that it 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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRequestTypeNotSupported = errors.New("request type not supported")
|
||||
errShortTypedRequest = errors.New("typed request too short")
|
||||
)
|
||||
|
||||
// Request types.
|
||||
const (
|
||||
DepositRequestType = 0x00
|
||||
)
|
||||
|
||||
// Request is an EIP-7685 request object. It represents execution layer
|
||||
// triggered messages bound for the consensus layer.
|
||||
type Request struct {
|
||||
inner RequestData
|
||||
}
|
||||
|
||||
// Type returns the EIP-7685 type of the request.
|
||||
func (r *Request) Type() byte {
|
||||
return r.inner.requestType()
|
||||
}
|
||||
|
||||
// Inner returns the inner request data.
|
||||
func (r *Request) Inner() RequestData {
|
||||
return r.inner
|
||||
}
|
||||
|
||||
// NewRequest creates a new request.
|
||||
func NewRequest(inner RequestData) *Request {
|
||||
req := new(Request)
|
||||
req.inner = inner.copy()
|
||||
return req
|
||||
}
|
||||
|
||||
// Requests implements DerivableList for requests.
|
||||
type Requests []*Request
|
||||
|
||||
// Len returns the length of s.
|
||||
func (s Requests) Len() int { return len(s) }
|
||||
|
||||
// EncodeIndex encodes the i'th request to s.
|
||||
func (s Requests) EncodeIndex(i int, w *bytes.Buffer) {
|
||||
s[i].encode(w)
|
||||
}
|
||||
|
||||
// RequestData is the underlying data of a request.
|
||||
type RequestData interface {
|
||||
requestType() byte
|
||||
encode(*bytes.Buffer) error
|
||||
decode([]byte) error
|
||||
copy() RequestData // creates a deep copy and initializes all fields
|
||||
}
|
||||
|
||||
// EncodeRLP implements rlp.Encoder
|
||||
func (r *Request) EncodeRLP(w io.Writer) error {
|
||||
buf := encodeBufferPool.Get().(*bytes.Buffer)
|
||||
defer encodeBufferPool.Put(buf)
|
||||
buf.Reset()
|
||||
if err := r.encode(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
return rlp.Encode(w, buf.Bytes())
|
||||
}
|
||||
|
||||
// encode writes the canonical encoding of a request to w.
|
||||
func (r *Request) encode(w *bytes.Buffer) error {
|
||||
w.WriteByte(r.Type())
|
||||
return r.inner.encode(w)
|
||||
}
|
||||
|
||||
// MarshalBinary returns the canonical encoding of the request.
|
||||
func (r *Request) MarshalBinary() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := r.encode(&buf)
|
||||
return buf.Bytes(), err
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder
|
||||
func (r *Request) DecodeRLP(s *rlp.Stream) error {
|
||||
kind, size, err := s.Kind()
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case kind == rlp.List:
|
||||
return fmt.Errorf("untyped request")
|
||||
case kind == rlp.Byte:
|
||||
return errShortTypedRequest
|
||||
default:
|
||||
// First read the request payload bytes into a temporary buffer.
|
||||
b, buf, err := getPooledBuffer(size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer encodeBufferPool.Put(buf)
|
||||
if err := s.ReadBytes(b); err != nil {
|
||||
return err
|
||||
}
|
||||
// Now decode the inner request.
|
||||
inner, err := r.decode(b)
|
||||
if err == nil {
|
||||
r.inner = inner
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalBinary decodes the canonical encoding of requests.
|
||||
func (r *Request) UnmarshalBinary(b []byte) error {
|
||||
inner, err := r.decode(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.inner = inner
|
||||
return nil
|
||||
}
|
||||
|
||||
// decode decodes a request from the canonical format.
|
||||
func (r *Request) decode(b []byte) (RequestData, error) {
|
||||
if len(b) <= 1 {
|
||||
return nil, errShortTypedRequest
|
||||
}
|
||||
var inner RequestData
|
||||
switch b[0] {
|
||||
case DepositRequestType:
|
||||
inner = new(Deposit)
|
||||
default:
|
||||
return nil, ErrRequestTypeNotSupported
|
||||
}
|
||||
err := inner.decode(b[1:])
|
||||
return inner, err
|
||||
}
|
||||
|
|
@ -604,8 +604,8 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas
|
|||
if params.BlobGasUsed == nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil blobGasUsed post-cancun"))
|
||||
}
|
||||
if params.Deposits == nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil deposits post-prague"))
|
||||
if params.Requests == nil {
|
||||
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil requests post-prague"))
|
||||
}
|
||||
|
||||
if versionedHashes == nil {
|
||||
|
|
@ -842,7 +842,7 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe
|
|||
"params.ExcessBlobGas", ebg,
|
||||
"len(params.Transactions)", len(params.Transactions),
|
||||
"len(params.Withdrawals)", len(params.Withdrawals),
|
||||
"len(params.Deposits)", len(params.Deposits),
|
||||
"len(params.Requests)", len(params.Requests),
|
||||
"beaconRoot", beaconRoot,
|
||||
"error", err)
|
||||
return api.invalid(err, nil), nil
|
||||
|
|
@ -1189,7 +1189,7 @@ func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engin
|
|||
if body != nil {
|
||||
// Nil out the V2 values, clients should know to not request V1 objects
|
||||
// after Prague.
|
||||
body.Deposits = nil
|
||||
body.Requests = nil
|
||||
}
|
||||
bodies[i] = body
|
||||
}
|
||||
|
|
@ -1218,7 +1218,7 @@ func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64)
|
|||
// after Prague.
|
||||
for i := range bodies {
|
||||
if bodies[i] != nil {
|
||||
bodies[i].Deposits = nil
|
||||
bodies[i].Requests = nil
|
||||
}
|
||||
}
|
||||
return bodies, nil
|
||||
|
|
@ -1257,35 +1257,26 @@ func getBody(block *types.Block) *engine.ExecutionPayloadBody {
|
|||
}
|
||||
|
||||
var (
|
||||
body = block.Body()
|
||||
txs = make([]hexutil.Bytes, len(body.Transactions))
|
||||
withdrawals = body.Withdrawals
|
||||
depositRequests types.Deposits
|
||||
body = block.Body()
|
||||
result engine.ExecutionPayloadBody
|
||||
)
|
||||
|
||||
result.TransactionData = make([]hexutil.Bytes, len(body.Transactions))
|
||||
for j, tx := range body.Transactions {
|
||||
txs[j], _ = tx.MarshalBinary()
|
||||
result.TransactionData[j], _ = tx.MarshalBinary()
|
||||
}
|
||||
|
||||
// Post-shanghai withdrawals MUST be set to empty slice instead of nil
|
||||
if withdrawals == nil && block.Header().WithdrawalsHash != nil {
|
||||
withdrawals = make([]*types.Withdrawal, 0)
|
||||
if body.Withdrawals != nil && block.Header().WithdrawalsHash != nil {
|
||||
result.Withdrawals = make([]*types.Withdrawal, 0)
|
||||
}
|
||||
|
||||
if block.Header().RequestsHash != nil {
|
||||
// TODO: this isn't future proof because we can't determine if a request
|
||||
// type has activated yet or if there are just no requests of that type from
|
||||
// only the block.
|
||||
for _, req := range block.Requests() {
|
||||
if d, ok := req.Inner().(*types.Deposit); ok {
|
||||
depositRequests = append(depositRequests, d)
|
||||
}
|
||||
if reqs := block.Requests(); reqs != nil {
|
||||
result.Requests = make([]hexutil.Bytes, len(reqs))
|
||||
for j, req := range reqs {
|
||||
result.Requests[j] = req
|
||||
}
|
||||
}
|
||||
|
||||
return &engine.ExecutionPayloadBody{
|
||||
TransactionData: txs,
|
||||
Withdrawals: withdrawals,
|
||||
Deposits: depositRequests,
|
||||
}
|
||||
return &result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1569,18 +1569,13 @@ func equalBody(a *types.Body, b *engine.ExecutionPayloadBody) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
var deposits types.Deposits
|
||||
var requests [][]byte
|
||||
if a.Requests != nil {
|
||||
// If requests is non-nil, it means deposits are available in block and we
|
||||
// If requests is non-nil, it means requests are available in block and we
|
||||
// should return an empty slice instead of nil if there are no deposits.
|
||||
deposits = make(types.Deposits, 0)
|
||||
requests = make([][]byte, 0)
|
||||
}
|
||||
for _, r := range a.Requests {
|
||||
if d, ok := r.Inner().(*types.Deposit); ok {
|
||||
deposits = append(deposits, d)
|
||||
}
|
||||
}
|
||||
return reflect.DeepEqual(deposits, b.Deposits)
|
||||
return reflect.DeepEqual(requests, b.Requests)
|
||||
}
|
||||
|
||||
func TestBlockToPayloadWithBlobs(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -785,7 +785,7 @@ func (q *queue) DeliverHeaders(id string, headers []*types.Header, hashes []comm
|
|||
func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListHashes []common.Hash,
|
||||
uncleLists [][]*types.Header, uncleListHashes []common.Hash,
|
||||
withdrawalLists [][]*types.Withdrawal, withdrawalListHashes []common.Hash,
|
||||
requestsLists [][]*types.Request, requestsListHashes []common.Hash) (int, error) {
|
||||
requestsLists [][][]byte, requestsListHashes []common.Hash) (int, error) {
|
||||
q.lock.Lock()
|
||||
defer q.lock.Unlock()
|
||||
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error {
|
|||
withdrawalHashes[i] = types.DeriveSha(types.Withdrawals(body.Withdrawals), hasher)
|
||||
}
|
||||
if body.Requests != nil {
|
||||
requestsHashes[i] = types.DeriveSha(types.Requests(body.Requests), hasher)
|
||||
requestsHashes[i] = types.CalcRequestHash(body.Requests)
|
||||
}
|
||||
}
|
||||
return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes, requestsHashes}
|
||||
|
|
|
|||
|
|
@ -224,17 +224,17 @@ type BlockBody struct {
|
|||
Transactions []*types.Transaction // Transactions contained within a block
|
||||
Uncles []*types.Header // Uncles contained within a block
|
||||
Withdrawals []*types.Withdrawal `rlp:"optional"` // Withdrawals contained within a block
|
||||
Requests []*types.Request `rlp:"optional"` // Requests contained within a block
|
||||
Requests [][]byte `rlp:"optional"` // Requests contained within a block
|
||||
}
|
||||
|
||||
// Unpack retrieves the transactions and uncles from the range packet and returns
|
||||
// them in a split flat format that's more consistent with the internal data structures.
|
||||
func (p *BlockBodiesResponse) Unpack() ([][]*types.Transaction, [][]*types.Header, [][]*types.Withdrawal, [][]*types.Request) {
|
||||
func (p *BlockBodiesResponse) Unpack() ([][]*types.Transaction, [][]*types.Header, [][]*types.Withdrawal, [][][]byte) {
|
||||
var (
|
||||
txset = make([][]*types.Transaction, len(*p))
|
||||
uncleset = make([][]*types.Header, len(*p))
|
||||
withdrawalset = make([][]*types.Withdrawal, len(*p))
|
||||
requestset = make([][]*types.Request, len(*p))
|
||||
requestset = make([][][]byte, len(*p))
|
||||
)
|
||||
for i, body := range *p {
|
||||
txset[i], uncleset[i], withdrawalset[i], requestset[i] = body.Transactions, body.Uncles, body.Withdrawals, body.Requests
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ type rpcBlock struct {
|
|||
Transactions []rpcTransaction `json:"transactions"`
|
||||
UncleHashes []common.Hash `json:"uncles"`
|
||||
Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
|
||||
Requests []*types.Request `json:"requests,omitempty"`
|
||||
Requests []hexutil.Bytes `json:"requests,omitempty"`
|
||||
}
|
||||
|
||||
func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) {
|
||||
|
|
@ -192,12 +192,22 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
|
|||
}
|
||||
txs[i] = tx.tx
|
||||
}
|
||||
|
||||
// Convert requests.
|
||||
var requests [][]byte
|
||||
if body.Requests != nil {
|
||||
requests = make([][]byte, len(body.Requests))
|
||||
for i, req := range body.Requests {
|
||||
requests[i] = req
|
||||
}
|
||||
}
|
||||
|
||||
return types.NewBlockWithHeader(head).WithBody(
|
||||
types.Body{
|
||||
Transactions: txs,
|
||||
Uncles: uncles,
|
||||
Withdrawals: body.Withdrawals,
|
||||
Requests: body.Requests,
|
||||
Requests: requests,
|
||||
}), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue