2022-11-23 16:11:38 +00:00
|
|
|
# nimbus_verified_proxy
|
|
|
|
# Copyright (c) 2022 Status Research & Development GmbH
|
|
|
|
# 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.
|
|
|
|
|
2022-11-23 11:46:09 +00:00
|
|
|
import
|
|
|
|
std/typetraits,
|
|
|
|
eth/common/eth_types as etypes,
|
|
|
|
eth/[trie, rlp, trie/db],
|
|
|
|
stint,
|
|
|
|
web3
|
|
|
|
|
|
|
|
template unsafeQuantityToInt64(q: Quantity): int64 =
|
|
|
|
int64 q
|
|
|
|
|
|
|
|
func toFixedBytes(d: MDigest[256]): FixedBytes[32] =
|
|
|
|
FixedBytes[32](d.data)
|
|
|
|
|
|
|
|
template asEthHash(hash: BlockHash): Hash256 =
|
|
|
|
Hash256(data: distinctBase(hash))
|
|
|
|
|
|
|
|
proc calculateTransactionData(
|
|
|
|
items: openArray[TypedTransaction]): (etypes.Hash256, seq[TxHash], uint64) =
|
|
|
|
## returns tuple composed of
|
|
|
|
## - root of transactions trie
|
|
|
|
## - list of transactions hashes
|
|
|
|
## - total size of transactions in block
|
|
|
|
var tr = initHexaryTrie(newMemoryDB())
|
|
|
|
var txHashes: seq[TxHash]
|
|
|
|
var txSize: uint64
|
|
|
|
for i, t in items:
|
|
|
|
let tx = distinctBase(t)
|
|
|
|
txSize = txSize + uint64(len(tx))
|
|
|
|
tr.put(rlp.encode(i), tx)
|
|
|
|
txHashes.add(toFixedBytes(keccakHash(tx)))
|
|
|
|
return (tr.rootHash(), txHashes, txSize)
|
|
|
|
|
|
|
|
func blockHeaderSize(payload: ExecutionPayloadV1, txRoot: etypes.Hash256): uint64 =
|
|
|
|
let bh = etypes.BlockHeader(
|
|
|
|
parentHash : payload.parentHash.asEthHash,
|
|
|
|
ommersHash : etypes.EMPTY_UNCLE_HASH,
|
|
|
|
coinbase : etypes.EthAddress payload.feeRecipient,
|
|
|
|
stateRoot : payload.stateRoot.asEthHash,
|
|
|
|
txRoot : txRoot,
|
|
|
|
receiptRoot : payload.receiptsRoot.asEthHash,
|
|
|
|
bloom : distinctBase(payload.logsBloom),
|
|
|
|
difficulty : default(etypes.DifficultyInt),
|
|
|
|
blockNumber : payload.blockNumber.distinctBase.u256,
|
|
|
|
gasLimit : payload.gasLimit.unsafeQuantityToInt64,
|
|
|
|
gasUsed : payload.gasUsed.unsafeQuantityToInt64,
|
|
|
|
timestamp : fromUnix payload.timestamp.unsafeQuantityToInt64,
|
|
|
|
extraData : bytes payload.extraData,
|
|
|
|
mixDigest : payload.prevRandao.asEthHash,
|
|
|
|
nonce : default(etypes.BlockNonce),
|
|
|
|
fee : some payload.baseFeePerGas
|
|
|
|
)
|
|
|
|
return uint64(len(rlp.encode(bh)))
|
|
|
|
|
|
|
|
proc asBlockObject*(p: ExecutionPayloadV1): BlockObject =
|
|
|
|
# TODO currently we always calculate txHashes as BlockObject does not have
|
|
|
|
# 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(
|
|
|
|
number: p.blockNumber,
|
|
|
|
hash: p.blockHash,
|
|
|
|
parentHash: p.parentHash,
|
|
|
|
sha3Uncles: FixedBytes(etypes.EMPTY_UNCLE_HASH.data),
|
|
|
|
logsBloom: p.logsBloom,
|
|
|
|
transactionsRoot: toFixedBytes(txRoot),
|
|
|
|
stateRoot: p.stateRoot,
|
|
|
|
receiptsRoot: p.receiptsRoot,
|
|
|
|
miner: p.feeRecipient,
|
|
|
|
difficulty: UInt256.zero,
|
|
|
|
extraData: p.extraData.toHex,
|
|
|
|
gasLimit: p.gasLimit,
|
|
|
|
gasUsed: p.gasUsed,
|
|
|
|
timestamp: p.timestamp,
|
|
|
|
nonce: some(default(FixedBytes[8])),
|
|
|
|
size: Quantity(blockSize),
|
|
|
|
# TODO It does not matter what we put here in after merge blocks.
|
|
|
|
# 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: @[],
|
|
|
|
baseFeePerGas: some(p.baseFeePerGas)
|
|
|
|
)
|
|
|
|
|