mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-09 11:55:57 +00:00
0a8986bc77
Saving both memory and processing, we can move entries from one savepoint to another, specially when the target is empty as it often is during transaction processing
93 lines
2.7 KiB
Nim
93 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,
|
|
../utils/mergeutils
|
|
|
|
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 mergeAndReset*(ac, other: var AccessList) =
|
|
# move values in `other` to `ac`
|
|
ac.slots.mergeAndReset(other.slots)
|
|
|
|
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
|