Skip to content

Commit

Permalink
Update EIP-7002: change request to flat encoding (#8855)
Browse files Browse the repository at this point in the history
* EIP-7002: change request to flat encoding

I am proposing to change the encoding of withdrawal requests to be exactly equal to how
they are returned by the contract. The extra layer of RLP encoding is not necessary, and
by removing it, we can avoid defining the structure of these requests in the execution
layer client implementation.

* EIP-7002: make note of endianness of amount for input and output

* 7002: clarify endianness in pseudocode

* 7002: update bytecode

---------

Co-authored-by: lightclient <[email protected]>
  • Loading branch information
fjl and lightclient committed Sep 26, 2024
1 parent 4392dec commit a23be81
Showing 1 changed file with 87 additions and 20 deletions.
107 changes: 87 additions & 20 deletions EIPS/eip-7002.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,22 @@ with type `0x01` and consists of the following fields:
2. `validator_pubkey`: `Bytes48`
3. `amount:` `uint64`

The [EIP-7685](./eip-7685) encoding of a withdrawal request **MUST** be computed as the follows:
The [EIP-7685](./eip-7685) encoding of a withdrawal request is computed as follows.
Note that `amount` is returned by the contract little-endian, and must be encoded as such.

```python
encoded = WITHDRAWAL_REQUEST_TYPE ++ rlp([source_address, validator_pubkey, amount])
request_type = WITHDRAWAL_REQUEST_TYPE
request_data = source_address ++ validator_pubkey ++ amount
```

The size of encoded withdrawal `request_data` is 76 bytes.

#### Withdrawal Request Contract

The contract has three different code paths, which can be summarized at a high level as follows:

1. Add withdrawal request - requires a `56` byte input, the validator's public
key concatenated with `uint64` amount value.
key concatenated with a big-endian `uint64` amount value.
2. Excess withdrawal requests getter - if the input length is zero, return the current excess withdrawal requests count.
3. System process - if called by system address, pop off the withdrawal requests for the current block from the queue.

Expand Down Expand Up @@ -111,7 +115,7 @@ def add_withdrawal_request(Bytes48: validator_pubkey, uint64: amount):
queue_storage_slot = WITHDRAWAL_REQUEST_QUEUE_STORAGE_OFFSET + queue_tail_index * 3
sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot, msg.sender)
sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 1, validator_pubkey[0:32])
sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2, validator_pubkey[32:48] ++ amount)
sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2, validator_pubkey[32:48] ++ uint64_to_little_endian(amount))
sstore(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, WITHDRAWAL_REQUEST_QUEUE_TAIL_STORAGE_SLOT, queue_tail_index + 1)
```

Expand Down Expand Up @@ -174,6 +178,12 @@ def read_withdrawal_requests():
# Helpers #
###########

def little_endian_to_uint64(data: bytes) -> uint64:
return uint64(int.from_bytes(data, 'little'))

def uint64_to_little_endian(num: uint64) -> bytes:
return num.to_bytes(8, 'little')

class ValidatorWithdrawalRequest(object):
source_address: Bytes20
validator_pubkey: Bytes48
Expand All @@ -192,7 +202,7 @@ def dequeue_withdrawal_requests():
validator_pubkey = (
sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 1)[0:32] + sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[0:16]
)
amount = sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[16:24]
amount = little_endian_to_uint64(sload(WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, queue_storage_slot + 2)[16:24])
req = ValidatorWithdrawalRequest(
source_address=Bytes20(source_address),
validator_pubkey=Bytes48(validator_pubkey),
Expand Down Expand Up @@ -254,7 +264,7 @@ calldatasize
push1 0x38
eq
iszero
push2 0x013f
push2 0x01ab
jumpi
push1 0x11
Expand Down Expand Up @@ -300,7 +310,7 @@ swap1
div
callvalue
lt
push2 0x013f
push2 0x01ab
jumpi
push1 0x01
Expand Down Expand Up @@ -373,7 +383,7 @@ jumpdest
dup2
dup2
eq
push1 0xed
push2 0x0158
jumpi
dup1
Expand Down Expand Up @@ -406,10 +416,68 @@ dup3
push1 0x14
add
mstore
swap1
dup1
push32 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000
and
dup3
push1 0x34
add
mstore
push1 0x40
shr
swap1
push1 0x44
add
dup2
push1 0x38
shr
dup2
push1 0x07
add
mstore8
dup2
push1 0x30
shr
dup2
push1 0x06
add
mstore8
dup2
push1 0x28
shr
dup2
push1 0x05
add
mstore8
dup2
push1 0x20
shr
dup2
push1 0x04
add
mstore8
dup2
push1 0x18
shr
dup2
push1 0x03
add
mstore8
dup2
push1 0x10
shr
dup2
push1 0x02
add
mstore8
dup2
push1 0x08
shr
dup2
push1 0x01
add
mstore8
mstore8
push1 0x01
add
push1 0xb6
Expand All @@ -421,13 +489,13 @@ add
dup1
swap3
eq
push1 0xfe
push2 0x016a
jumpi
swap1
push1 0x02
sstore
push2 0x0109
push2 0x0175
jump
jumpdest
Expand All @@ -447,7 +515,7 @@ dup1
push2 0x049d
eq
iszero
push2 0x0118
push2 0x0184
jumpi
pop
Expand All @@ -461,13 +529,13 @@ dup3
dup3
add
gt
push2 0x012d
push2 0x0199
jumpi
pop
pop
push0
push2 0x0133
push2 0x019f
jump
jumpdest
Expand All @@ -491,7 +559,6 @@ jumpdest
push0
push0
revert
```

##### Deployment
Expand All @@ -508,17 +575,17 @@ The withdrawal requests contract is deployed like any other smart contract. A sp
"maxPriorityFeePerGas": null,
"maxFeePerGas": null,
"value": "0x0",
"input": "0x61049d5f5561014380600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460a0573615156028575f545f5260205ff35b366038141561013f5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061013f57600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160b4575060105b5f5b81811460ed5780604c02838201600302600401805490600101805490600101549160601b83528260140152906034015260010160b6565b910180921460fe5790600255610109565b90505f6002555f6003555b5f548061049d141561011857505f5b60015460028282011161012d5750505f610133565b01600290035b5f555f600155604c025ff35b5f5ffd",
"input": "0x61049d5f556101af80600f5f395ff33373fffffffffffffffffffffffffffffffffffffffe1460a0573615156028575f545f5260205ff35b36603814156101ab5760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b9093900434106101ab57600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160b4575060105b5f5b8181146101585780604c02838201600302600401805490600101805490600101549160601b83528260140152807fffffffffffffffffffffffffffffffff0000000000000000000000000000000016826034015260401c906044018160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160b6565b910180921461016a5790600255610175565b90505f6002555f6003555b5f548061049d141561018457505f5b6001546002828201116101995750505f61019f565b01600290035b5f555f600155604c025ff35b5f5ffd",
"v": "0x1b",
"r": "0x539",
"s": "0x54ebd8d935ccd710",
"hash": "0x2a81b690e499cd188ec78719659600d2f9bb953692bfd393daaac471e8d89d5b"
"s": "0x48655fec580f6877",
"hash": "0xcf76a9eb8c38b162c697b6e58669dc2546284e84d752d79af9c4e49be6bdcb39"
}
```

```
Sender: 0x38748F0B5Ece4A246d108BB00eD6F17c3062BbD7
Address: 0x05F27129610CB42103b665629CB5c8C00296AaAa
Sender: 0xAC6AfB9d8491e8b397F65331Ce41e338cBfe1048
Address: 0x0511Ce19514e1298Fba96de582652A016E2CAaAa
```

### Consensus layer
Expand Down

0 comments on commit a23be81

Please sign in to comment.