nimbus-eth1/nimbus/db/access_list.nim
Jacek Sieka f6be4bd0ec
avoid initTable (#2328)
`initTable` is obsolete since nim 0.19 and can introduce significant
memory overhead while providing no benefit (since the table will be
grown to the default initial size on first use anyway).

In particular, aristo layers will not necessarily use all tables they
initialize, for exampe when many empty accounts are being created.
2024-06-10 11:05:30 +02:00

95 lines
2.7 KiB
Nim

# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
import
std/[tables, sets],
stint,
eth/common
type
SlotSet = HashSet[UInt256]
AccessList* = object
slots: Table[EthAddress, SlotSet]
# ------------------------------------------------------------------------------
# Private helpers
# ------------------------------------------------------------------------------
func toStorageKeys(slots: SlotSet): seq[StorageKey] =
for slot in slots:
result.add slot.toBytesBE
# ------------------------------------------------------------------------------
# Public constructors
# ------------------------------------------------------------------------------
proc init*(ac: var AccessList) =
ac.slots = Table[EthAddress, SlotSet]()
proc init*(_: type AccessList): AccessList {.inline.} =
result.init()
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
func contains*(ac: AccessList, address: EthAddress): bool {.inline.} =
address in ac.slots
# returnValue: (addressPresent, slotPresent)
func contains*(ac: var AccessList, address: EthAddress, slot: UInt256): bool =
ac.slots.withValue(address, val):
result = slot in val[]
proc merge*(ac: var AccessList, other: AccessList) {.inline.} =
for k, v in other.slots:
ac.slots.withValue(k, val):
val[].incl v
do:
ac.slots[k] = v
proc add*(ac: var AccessList, address: EthAddress) =
if address notin ac.slots:
ac.slots[address] = HashSet[UInt256]()
proc add*(ac: var AccessList, address: EthAddress, slot: UInt256) =
ac.slots.withValue(address, val):
val[].incl slot
do:
ac.slots[address] = toHashSet([slot])
proc clear*(ac: var AccessList) {.inline.} =
ac.slots.clear()
func getAccessList*(ac: AccessList): common.AccessList =
for address, slots in ac.slots:
result.add common.AccessPair(
address : address,
storageKeys: slots.toStorageKeys,
)
func equal*(ac: AccessList, other: var AccessList): bool =
if ac.slots.len != other.slots.len:
return false
for address, slots in ac.slots:
other.slots.withValue(address, otherSlots):
if slots.len != otherSlots[].len:
return false
for slot in slots:
if slot notin otherSlots[]:
return false
do:
return false
true