Yes, this was exactly my point, since indeed monotonically increasing does not mean that it +1s for each withdrawal, it can increase with any number (integer). And you are right, it should also specify that it should start at 0.
Given that withdrawals_root and the Withdrawal structure are new additions, I’m wondering if it would be possible to use a consistent tree style across the two specs.
This would enable the EL block header to be derived from the CL ExecutionPayloadHeader, enabling light clients that are subscribed to the CL light clients gossip to follow the chain without requiring any additional network requests. Network requests would only be needed when encountering a block of interest via logs_bloom, or when requesting a state or transaction inclusion proof.
I have explored three other approaches to solve this inconsistency across EL and CL root formats for light clients.
Including hexary transactions_root and withdrawals_root into the ExecutionPayload
This would require extensions to the BeaconBlock and BeaconState, hence is more invasive than it should be, just to make life easier for light clients.
May interfere with future changes to the trie format (statelessness / verkle tries).
Have the CL implementation re-compute hexary transactions_root and withdrawals_root from the beacon block data when providing light client data.
This would require CL implementations to add software for hexary trie computation. Given that SSZ tends to be seen as more modern than hexary tries, it would be a step into the wrong direction.
May interfere with split block storage designs, because the CL would no longer have the raw transactions and withdrawals that are needed to compute the hexary trie root hashes. The CL may need to fetch that info via eth_getBlockByRoot(..., includeTransactions: false), and that call may compete with resources needed for ongoing validator duties or fork choice processing.
Only provide the other ExecutionPayloadHeader fields to the light client, omitting the hexary transactions_root and withdrawals_root.
This would require light clients to issue a second network request to obtain those hexary trie roots, which are needed to validate inclusion of transactions. It would be great if light clients could follow the chain without additional network requests to individual peers, just by following gossip on light client topics (or the event stream from REST).
May introduce complexity by having not only full blocks and block headers, but also a partial block headers concept.
Hence, the request here, whether withdrawals_root and Withdrawals could be modernized with a change to SSZ. SSZ libraries should already be available for all programming languages used by major EL implementations. Going forward, new roots should become consistent across both the EL and CL.
Note that transactions_root is the other blocker currently preventing to convert ExecutionPayloadHeader to an EL block header. The situation is different, though, because the individual transactions are also RLP encoded in the CL. So, only the hexary transactions_root would need to be converted to a SSZ root, but not the individual transactions. If that is not feasible given the long-term existence of this field, the ExecutionPayload could be extended with the hexary transactions_root as a one-time exception.
As I understand the eth 1 address at 2) is for both 3) and 5)
can only be a Externally Owned Address not a Contract Address (as no EVM). It this correct?
no, the execution layer address can be any valid address, so either an EOA or a smart contract. the mechanism of EIP-4895 only increments the balance so one caveat is that if you are expecting any kind of execution from the smart contract, that simply won’t happen (so no logs, or ability to update internal smart contract state)
is 4) supported now
Is that true for both 3) and 5)
what happens with the 32 ETH from 2) in deposit_contract.sol
nothing. the ETH in this contract should be considered to be ‘burnt’ and/or taken out of supply. there is no way to access them any more
Since we are handling a large number of validators, we are thinking about having multiple validators using the same withdrawal address, for speed and cost reasons of the further handling of funds. However that introduces a potential accounting traceability problem.
Will it be possible to somehow enumerate through all the
execution_payload.withdrawals ... List of [index, validator_index, address, amount]
specified in EIP-4895 performed on the execution layer, to trace the specific transactions per validator ?
Hey @ralexstokes! Are validator gas tips included in the automatic reward push on top of the 32 ETH or are they withdrawn in a different way? Also, can rewards and principal be withdrawn simultaneously? Thanks!
Question (maybe naive).
With the recipient address on the Withdrawal object being any ETH valid address (including smart contracts), could this affect applications on the EVM assuming that the contract should never have an ETH balance?
Maybe it is just that because of SELFDESTRUCT this should simply not be assumed, but to me looks like something pretty important and new, if working like that.