From a63325e71579f9eee3643a77e4585526bd9f74eb Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Mon, 23 Sep 2024 23:15:27 +0200 Subject: [PATCH] Update EIP-6404: Add support for SetCode transactions --- beacon_chain/el/engine_api_conversions.nim | 96 +++++++++++++++++-- beacon_chain/spec/datatypes/stable.nim | 36 +++++-- .../eth2_apis/eth2_rest_serialization.nim | 4 +- vendor/nim-web3 | 2 +- 4 files changed, 123 insertions(+), 15 deletions(-) diff --git a/beacon_chain/el/engine_api_conversions.nim b/beacon_chain/el/engine_api_conversions.nim index 5d593761c..65b24df8e 100644 --- a/beacon_chain/el/engine_api_conversions.nim +++ b/beacon_chain/el/engine_api_conversions.nim @@ -161,9 +161,9 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): Opt.none(uint8), chain_id: if tt.payload.chainId.isSome: - Opt.some(tt.payload.chainId.get.uint64) + Opt.some(tt.payload.chainId.get) else: - Opt.none(uint64), + Opt.none(UInt256), nonce: if tt.payload.nonce.isSome: Opt.some(tt.payload.nonce.get.uint64) @@ -240,8 +240,51 @@ func asConsensusType*(rpcExecutionPayload: ExecutionPayloadV4): stable.VersionedHash(it)))) else: Opt.none( - List[stable.VersionedHash, - Limit MAX_BLOB_COMMITMENTS_PER_BLOCK])), + List[stable.VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]), + authorization_list: + if tt.payload.authorizationList.isSome: + Opt.some( + List[Eip6404Authorization, Limit MAX_AUTHORIZATION_LIST_SIZE] + .init(tt.payload.authorizationList.get.mapIt( + Eip6404Authorization( + payload: Eip6404AuthorizationPayload( + magic: + if it.payload.magic.isSome: + Opt.some(distinctBase(it.payload.magic.get).uint8) + else: + Opt.none(TransactionType), + chainId: + if it.payload.chainId.isSome: + Opt.some(it.payload.chainId.get) + else: + Opt.none(ChainId), + address: + if it.payload.address.isSome: + Opt.some(ExecutionAddress( + data: distinctBase(it.payload.address.get))) + else: + Opt.none(ExecutionAddress), + nonce: + if it.payload.nonce.isSome: + Opt.some(distinctBase(it.payload.nonce.get)) + else: + Opt.none(uint64)), + authority: Eip6404ExecutionSignature( + address: + if it.authority.address.isSome: + Opt.some(ExecutionAddress( + data: distinctBase(it.authority.address.get))) + else: + Opt.none(ExecutionAddress), + secp256k1_signature: + if it.authority.secp256k1Signature.isSome: + Opt.some(array[65, byte]( + it.authority.secp256k1Signature.get)) + else: + Opt.none(array[65, byte])))))) + else: + Opt.none( + List[Eip6404Authorization, Limit MAX_AUTHORIZATION_LIST_SIZE])), `from`: Eip6404ExecutionSignature( address: if tt.`from`.address.isSome: @@ -417,9 +460,9 @@ func asEngineExecutionPayload*(blockBody: electra.BeaconBlockBody): Opt.none(Quantity), chainId: if tt.payload.chain_id.isSome: - Opt.some(tt.payload.chain_id.get.Quantity) + Opt.some(tt.payload.chain_id.get) else: - Opt.none(Quantity), + Opt.none(UInt256), nonce: if tt.payload.nonce.isSome: Opt.some(tt.payload.nonce.get.Quantity) @@ -491,7 +534,46 @@ func asEngineExecutionPayload*(blockBody: electra.BeaconBlockBody): Opt.some(distinctBase(tt.payload.blob_versioned_hashes.get) .mapIt(FixedBytes[32](it))) else: - Opt.none(seq[FixedBytes[32]])), + Opt.none(seq[FixedBytes[32]]), + authorizationList: + if tt.payload.authorization_list.isSome: + Opt.some(distinctBase(tt.payload.authorization_list.get).mapIt( + AuthorizationV1( + payload: AuthorizationPayloadV1( + magic: + if it.payload.magic.isSome: + Opt.some(it.payload.magic.get.Quantity) + else: + Opt.none(Quantity), + chainId: + if it.payload.chain_id.isSome: + Opt.some(it.payload.chain_id.get) + else: + Opt.none(UInt256), + address: + if it.payload.address.isSome: + Opt.some(Address(it.payload.address.get.data)) + else: + Opt.none(Address), + nonce: + if it.payload.nonce.isSome: + Opt.some(it.payload.nonce.get.Quantity) + else: + Opt.none(Quantity)), + authority: engine_api_types.ExecutionSignature( + address: + if it.authority.address.isSome: + Opt.some(Address(it.authority.address.get.data)) + else: + Opt.none(Address), + secp256k1Signature: + if it.authority.secp256k1_signature.isSome: + Opt.some(FixedBytes[65]( + it.authority.secp256k1_signature.get)) + else: + Opt.none(FixedBytes[65]))))) + else: + Opt.none(seq[AuthorizationV1])), `from`: engine_api_types.ExecutionSignature( address: if tt.`from`.address.isSome: diff --git a/beacon_chain/spec/datatypes/stable.nim b/beacon_chain/spec/datatypes/stable.nim index e6a17416e..82e960d16 100644 --- a/beacon_chain/spec/datatypes/stable.nim +++ b/beacon_chain/spec/datatypes/stable.nim @@ -23,9 +23,15 @@ const MAX_BEACON_STATE_FIELDS* = 128 # https://eips.ethereum.org/EIPS/eip-6404 + SECP256K1_SIGNATURE_SIZE* = 65 + MAX_EXECUTION_SIGNATURE_FIELDS* = 16 + MAX_FEES_PER_GAS_FIELDS* = 16 MAX_CALLDATA_SIZE* = 16_777_216 MAX_ACCESS_LIST_STORAGE_KEYS* = 524_288 MAX_ACCESS_LIST_SIZE* = 524_288 + MAX_AUTHORIZATION_PAYLOAD_FIELDS* = 16 + MAX_AUTHORIZATION_LIST_SIZE* = 65_536 + MAX_TRANSACTION_PAYLOAD_FIELDS* = 32 type # TODO this apparently is suppposed to be SSZ-equivalent to Bytes32, but @@ -36,9 +42,15 @@ type # field manually VersionedHash* = array[32, byte] - ChainId* = uint64 + Eip6404ExecutionSignature* {. + sszStableContainer: MAX_EXECUTION_SIGNATURE_FIELDS.} = object + address*: Opt[ExecutionAddress] + secp256k1_signature*: Opt[array[SECP256K1_SIGNATURE_SIZE, byte]] - Eip6404FeesPerGas* {.sszStableContainer: 16.} = object + TransactionType* = uint8 + ChainId* = UInt256 + + Eip6404FeesPerGas* {.sszStableContainer: MAX_FEES_PER_GAS_FIELDS.} = object regular*: Opt[UInt256] # EIP-4844 @@ -48,7 +60,19 @@ type address*: ExecutionAddress storage_keys*: List[Eth2Digest, Limit MAX_ACCESS_LIST_STORAGE_KEYS] - Eip6404TransactionPayload* {.sszStableContainer: 32.} = object + Eip6404AuthorizationPayload* {. + sszStableContainer: MAX_AUTHORIZATION_PAYLOAD_FIELDS.} = object + magic*: Opt[TransactionType] + chain_id*: Opt[ChainId] + address*: Opt[ExecutionAddress] + nonce*: Opt[uint64] + + Eip6404Authorization* = object + payload*: Eip6404AuthorizationPayload + authority*: Eip6404ExecutionSignature + + Eip6404TransactionPayload* {. + sszStableContainer: MAX_TRANSACTION_PAYLOAD_FIELDS.} = object # EIP-2718 `type`*: Opt[uint8] @@ -72,9 +96,9 @@ type blob_versioned_hashes*: Opt[List[VersionedHash, Limit MAX_BLOB_COMMITMENTS_PER_BLOCK]] - Eip6404ExecutionSignature* {.sszStableContainer: 16.} = object - address*: Opt[ExecutionAddress] - secp256k1_signature*: Opt[array[65, byte]] + # EIP-7702 + authorization_list*: + Opt[List[Eip6404Authorization, Limit MAX_AUTHORIZATION_LIST_SIZE]] Eip6404Transaction* = object payload*: Eip6404TransactionPayload diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index ec5e10d09..1ca9efb73 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -64,10 +64,12 @@ RestJson.useDefaultSerializationFor( DepositTreeSnapshot, DistributedKeystoreInfo, Eip6404AccessTuple, + Eip6404Authorization, + Eip6404AuthorizationPayload, + Eip6404ExecutionSignature, Eip6404FeesPerGas, Eip6404Transaction, Eip6404TransactionPayload, - Eip6404ExecutionSignature, ElectraSignedBlockContents, EmptyBody, Eth1Data, diff --git a/vendor/nim-web3 b/vendor/nim-web3 index d43d509c3..9b8432944 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit d43d509c3e66daa3849de1fd9742c7c9fdd68322 +Subproject commit 9b843294469c07f2b276801dedb7c4a1441ace84