nimbus-eth1/fluffy/tools/portal_bridge/state_bridge/offers_builder.nim

107 lines
3.7 KiB
Nim

# Fluffy
# Copyright (c) 2024 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.
{.push raises: [].}
import
std/[sequtils, sugar],
eth/common,
../../../network/state/[state_content, state_utils, state_gossip],
./world_state
type OffersBuilder* = object
worldState: WorldStateRef
blockHash: BlockHash
accountTrieOffers: seq[AccountTrieOfferWithKey]
contractTrieOffers: seq[ContractTrieOfferWithKey]
contractCodeOffers: seq[ContractCodeOfferWithKey]
proc init*(T: type OffersBuilder, worldState: WorldStateRef, blockHash: BlockHash): T =
T(worldState: worldState, blockHash: blockHash)
proc toTrieProof(proof: seq[seq[byte]]): TrieProof =
TrieProof.init(proof.map((node) => TrieNode.init(node)))
proc buildAccountTrieNodeOffer(
builder: var OffersBuilder, addressHash: content_keys.AddressHash, proof: TrieProof
) =
try:
let
path = removeLeafKeyEndNibbles(
Nibbles.init(addressHash.data, isEven = true), proof[^1]
)
offerKey = AccountTrieNodeKey.init(path, keccakHash(proof[^1].asSeq()))
offerValue = AccountTrieNodeOffer.init(proof, builder.blockHash)
builder.accountTrieOffers.add(offerValue.withKey(offerKey))
except RlpError as e:
raiseAssert(e.msg) # Should never happen
proc buildContractTrieNodeOffer(
builder: var OffersBuilder,
addressHash: content_keys.AddressHash,
slotHash: SlotKeyHash,
storageProof: TrieProof,
accountProof: TrieProof,
) =
try:
let
path = removeLeafKeyEndNibbles(
Nibbles.init(slotHash.data, isEven = true), storageProof[^1]
)
offerKey = ContractTrieNodeKey.init(
addressHash, path, keccakHash(storageProof[^1].asSeq())
)
offerValue =
ContractTrieNodeOffer.init(storageProof, accountProof, builder.blockHash)
builder.contractTrieOffers.add(offerValue.withKey(offerKey))
except RlpError as e:
raiseAssert(e.msg) # Should never happen
proc buildContractCodeOffer(
builder: var OffersBuilder,
addressHash: content_keys.AddressHash,
code: seq[byte],
accountProof: TrieProof,
) =
let
#bytecode = Bytelist.init(code) # This fails to compile for some reason
bytecode = Bytecode(code)
offerKey = ContractCodeKey.init(addressHash, keccakHash(code))
offerValue = ContractCodeOffer.init(bytecode, accountProof, builder.blockHash)
builder.contractCodeOffers.add(offerValue.withKey(offerKey))
proc buildBlockOffers*(builder: var OffersBuilder) =
for addressHash, proof in builder.worldState.updatedAccountProofs():
let accountProof = toTrieProof(proof)
builder.buildAccountTrieNodeOffer(addressHash, accountProof)
for slotHash, sProof in builder.worldState.updatedStorageProofs(addressHash):
let storageProof = toTrieProof(sProof)
builder.buildContractTrieNodeOffer(
addressHash, slotHash, storageProof, accountProof
)
let code = builder.worldState.getUpdatedBytecode(addressHash)
if code.len() > 0:
builder.buildContractCodeOffer(addressHash, code, accountProof)
proc getAccountTrieOffers*(builder: OffersBuilder): lent seq[AccountTrieOfferWithKey] =
builder.accountTrieOffers
proc getContractTrieOffers*(
builder: OffersBuilder
): lent seq[ContractTrieOfferWithKey] =
builder.contractTrieOffers
proc getContractCodeOffers*(
builder: OffersBuilder
): lent seq[ContractCodeOfferWithKey] =
builder.contractCodeOffers