2022-11-23 16:11:38 +00:00
|
|
|
# nimbus_verified_proxy
|
2024-02-15 13:50:25 +00:00
|
|
|
# Copyright (c) 2022-2024 Status Research & Development GmbH
|
2022-11-23 16:11:38 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
{.push raises: [].}
|
2022-11-24 13:41:00 +00:00
|
|
|
|
2022-11-23 11:46:09 +00:00
|
|
|
import
|
|
|
|
std/typetraits,
|
|
|
|
eth/common/eth_types as etypes,
|
2024-09-29 12:37:09 +00:00
|
|
|
eth/rlp,
|
|
|
|
nimcrypto/hash,
|
2022-11-23 11:46:09 +00:00
|
|
|
stint,
|
2023-08-04 11:10:09 +00:00
|
|
|
web3,
|
2023-12-08 09:35:50 +00:00
|
|
|
web3/engine_api_types,
|
2023-08-04 11:10:09 +00:00
|
|
|
../../nimbus/db/core_db
|
2022-11-23 11:46:09 +00:00
|
|
|
|
2024-09-29 12:37:09 +00:00
|
|
|
type
|
|
|
|
FixedBytes[N: static int] = primitives.FixedBytes[N]
|
|
|
|
Address = primitives.Address
|
|
|
|
|
2024-02-15 13:50:25 +00:00
|
|
|
type ExecutionData* = object
|
|
|
|
parentHash*: BlockHash
|
|
|
|
feeRecipient*: Address
|
|
|
|
stateRoot*: BlockHash
|
|
|
|
receiptsRoot*: BlockHash
|
|
|
|
logsBloom*: FixedBytes[256]
|
|
|
|
prevRandao*: FixedBytes[32]
|
|
|
|
blockNumber*: Quantity
|
|
|
|
gasLimit*: Quantity
|
|
|
|
gasUsed*: Quantity
|
|
|
|
timestamp*: Quantity
|
|
|
|
extraData*: DynamicBytes[0, 32]
|
|
|
|
baseFeePerGas*: UInt256
|
|
|
|
blockHash*: BlockHash
|
|
|
|
transactions*: seq[TypedTransaction]
|
|
|
|
withdrawals*: seq[WithdrawalV1]
|
2022-12-02 15:09:31 +00:00
|
|
|
|
2024-05-15 03:07:59 +00:00
|
|
|
proc asExecutionData*(payload: SomeExecutionPayload): ExecutionData =
|
2022-12-02 15:09:31 +00:00
|
|
|
when payload is ExecutionPayloadV1:
|
|
|
|
return ExecutionData(
|
|
|
|
parentHash: payload.parentHash,
|
|
|
|
feeRecipient: payload.feeRecipient,
|
|
|
|
stateRoot: payload.stateRoot,
|
|
|
|
receiptsRoot: payload.receiptsRoot,
|
|
|
|
logsBloom: payload.logsBloom,
|
|
|
|
prevRandao: payload.prevRandao,
|
|
|
|
blockNumber: payload.blockNumber,
|
|
|
|
gasLimit: payload.gasLimit,
|
|
|
|
gasUsed: payload.gasUsed,
|
|
|
|
timestamp: payload.timestamp,
|
|
|
|
extraData: payload.extraData,
|
|
|
|
baseFeePerGas: payload.baseFeePerGas,
|
|
|
|
blockHash: payload.blockHash,
|
|
|
|
transactions: payload.transactions,
|
2024-02-15 13:50:25 +00:00
|
|
|
withdrawals: @[],
|
2022-12-02 15:09:31 +00:00
|
|
|
)
|
|
|
|
else:
|
2023-01-27 14:57:48 +00:00
|
|
|
# TODO: Deal with different payload types
|
2022-12-02 15:09:31 +00:00
|
|
|
return ExecutionData(
|
|
|
|
parentHash: payload.parentHash,
|
|
|
|
feeRecipient: payload.feeRecipient,
|
|
|
|
stateRoot: payload.stateRoot,
|
|
|
|
receiptsRoot: payload.receiptsRoot,
|
|
|
|
logsBloom: payload.logsBloom,
|
|
|
|
prevRandao: payload.prevRandao,
|
|
|
|
blockNumber: payload.blockNumber,
|
|
|
|
gasLimit: payload.gasLimit,
|
|
|
|
gasUsed: payload.gasUsed,
|
|
|
|
timestamp: payload.timestamp,
|
|
|
|
extraData: payload.extraData,
|
|
|
|
baseFeePerGas: payload.baseFeePerGas,
|
|
|
|
blockHash: payload.blockHash,
|
|
|
|
transactions: payload.transactions,
|
2024-02-15 13:50:25 +00:00
|
|
|
withdrawals: payload.withdrawals,
|
2022-12-02 15:09:31 +00:00
|
|
|
)
|
|
|
|
|
2022-11-23 11:46:09 +00:00
|
|
|
func toFixedBytes(d: MDigest[256]): FixedBytes[32] =
|
|
|
|
FixedBytes[32](d.data)
|
|
|
|
|
2023-03-09 23:40:55 +00:00
|
|
|
template asEthHash(hash: BlockHash): etypes.Hash256 =
|
2024-09-29 12:37:09 +00:00
|
|
|
etypes.Hash256(distinctBase(hash))
|
2022-11-23 11:46:09 +00:00
|
|
|
|
|
|
|
proc calculateTransactionData(
|
2024-02-15 13:50:25 +00:00
|
|
|
items: openArray[TypedTransaction]
|
|
|
|
): (etypes.Hash256, seq[TxOrHash], uint64) =
|
2022-11-23 11:46:09 +00:00
|
|
|
## returns tuple composed of
|
|
|
|
## - root of transactions trie
|
|
|
|
## - list of transactions hashes
|
|
|
|
## - total size of transactions in block
|
2024-07-10 12:19:35 +00:00
|
|
|
var tr = newCoreDbRef(DefaultDbMemory).ctx.getGeneric()
|
2023-12-08 09:35:50 +00:00
|
|
|
var txHashes: seq[TxOrHash]
|
2022-11-23 11:46:09 +00:00
|
|
|
var txSize: uint64
|
|
|
|
for i, t in items:
|
|
|
|
let tx = distinctBase(t)
|
|
|
|
txSize = txSize + uint64(len(tx))
|
2024-10-01 17:40:37 +00:00
|
|
|
tr.merge(rlp.encode(uint64 i), tx).expect "merge data"
|
2024-10-02 16:22:35 +00:00
|
|
|
txHashes.add(txOrHash keccakHash(tx))
|
2024-06-27 09:01:26 +00:00
|
|
|
let rootHash = tr.state(updateOk = true).expect "hash"
|
2024-06-05 20:52:04 +00:00
|
|
|
(rootHash, txHashes, txSize)
|
2022-11-23 11:46:09 +00:00
|
|
|
|
2024-02-15 13:50:25 +00:00
|
|
|
func blockHeaderSize(payload: ExecutionData, txRoot: etypes.Hash256): uint64 =
|
2022-11-23 11:46:09 +00:00
|
|
|
let bh = etypes.BlockHeader(
|
2024-02-15 13:50:25 +00:00
|
|
|
parentHash: payload.parentHash.asEthHash,
|
|
|
|
ommersHash: etypes.EMPTY_UNCLE_HASH,
|
|
|
|
coinbase: etypes.EthAddress payload.feeRecipient,
|
|
|
|
stateRoot: payload.stateRoot.asEthHash,
|
2024-09-29 12:37:09 +00:00
|
|
|
transactionsRoot: txRoot,
|
2024-06-14 07:31:08 +00:00
|
|
|
receiptsRoot: payload.receiptsRoot.asEthHash,
|
2024-09-29 12:37:09 +00:00
|
|
|
logsBloom: distinctBase(payload.logsBloom).to(Bloom),
|
2024-02-15 13:50:25 +00:00
|
|
|
difficulty: default(etypes.DifficultyInt),
|
2024-06-14 07:31:08 +00:00
|
|
|
number: payload.blockNumber.distinctBase,
|
2024-07-07 06:52:11 +00:00
|
|
|
gasLimit: distinctBase(payload.gasLimit),
|
|
|
|
gasUsed: distinctBase(payload.gasUsed),
|
2024-02-15 13:50:25 +00:00
|
|
|
timestamp: payload.timestamp.EthTime,
|
|
|
|
extraData: bytes payload.extraData,
|
2024-10-02 16:22:35 +00:00
|
|
|
mixHash: payload.prevRandao,
|
2024-02-15 13:50:25 +00:00
|
|
|
nonce: default(etypes.BlockNonce),
|
2024-06-14 07:31:08 +00:00
|
|
|
baseFeePerGas: Opt.some payload.baseFeePerGas,
|
2022-11-23 11:46:09 +00:00
|
|
|
)
|
|
|
|
return uint64(len(rlp.encode(bh)))
|
|
|
|
|
2024-02-15 13:50:25 +00:00
|
|
|
proc asBlockObject*(p: ExecutionData): BlockObject {.raises: [ValueError].} =
|
2022-11-24 13:41:00 +00:00
|
|
|
# TODO: currently we always calculate txHashes as BlockObject does not have
|
2022-11-23 11:46:09 +00:00
|
|
|
# option of returning full transactions. It needs fixing at nim-web3 library
|
|
|
|
# level
|
|
|
|
let (txRoot, txHashes, txSize) = calculateTransactionData(p.transactions)
|
|
|
|
let headerSize = blockHeaderSize(p, txRoot)
|
|
|
|
let blockSize = txSize + headerSize
|
|
|
|
BlockObject(
|
2024-03-21 01:05:22 +00:00
|
|
|
number: web3.BlockNumber p.blockNumber,
|
2022-11-23 11:46:09 +00:00
|
|
|
hash: p.blockHash,
|
|
|
|
parentHash: p.parentHash,
|
2024-10-02 16:22:35 +00:00
|
|
|
sha3Uncles: etypes.EMPTY_UNCLE_HASH,
|
2022-11-23 11:46:09 +00:00
|
|
|
logsBloom: p.logsBloom,
|
2024-10-02 16:22:35 +00:00
|
|
|
transactionsRoot: txRoot,
|
2022-11-23 11:46:09 +00:00
|
|
|
stateRoot: p.stateRoot,
|
|
|
|
receiptsRoot: p.receiptsRoot,
|
|
|
|
miner: p.feeRecipient,
|
|
|
|
difficulty: UInt256.zero,
|
2023-06-04 06:00:50 +00:00
|
|
|
extraData: fromHex(DynamicBytes[0, 4096], p.extraData.toHex),
|
2022-11-23 11:46:09 +00:00
|
|
|
gasLimit: p.gasLimit,
|
|
|
|
gasUsed: p.gasUsed,
|
|
|
|
timestamp: p.timestamp,
|
2024-06-14 07:31:08 +00:00
|
|
|
nonce: Opt.some(default(FixedBytes[8])),
|
2022-11-23 11:46:09 +00:00
|
|
|
size: Quantity(blockSize),
|
2022-11-24 13:41:00 +00:00
|
|
|
# TODO: It does not matter what we put here after merge blocks.
|
2022-11-23 11:46:09 +00:00
|
|
|
# Other projects like `helios` return `0`, data providers like alchemy return
|
|
|
|
# transition difficulty. For now retruning `0` as this is a bit easier to do.
|
|
|
|
totalDifficulty: UInt256.zero,
|
|
|
|
transactions: txHashes,
|
|
|
|
uncles: @[],
|
2024-06-14 07:31:08 +00:00
|
|
|
baseFeePerGas: Opt.some(p.baseFeePerGas),
|
2022-11-23 11:46:09 +00:00
|
|
|
)
|