@polygon-hermez/vm
Version:
An Ethereum VM implementation
191 lines (190 loc) • 7.9 kB
TypeScript
/// <reference types="node" />
import Common from '@ethereumjs/common';
import { AccessList } from '@ethereumjs/tx';
import { Debugger } from 'debug';
import { Account, Address } from 'ethereumjs-util';
import Cache from './cache';
import { DefaultStateManagerOpts } from './stateManager';
type AddressHex = string;
/**
* Abstract BaseStateManager class for the non-storage-backend
* related functionality parts of a StateManager like keeping
* track of accessed storage (`EIP-2929`) or touched accounts
* (`EIP-158`).
*
* This is not a full StateManager implementation in itself but
* can be used to ease implementing an own StateManager.
*
* Note that the implementation is pretty new (October 2021)
* and we cannot guarantee a stable interface yet.
*/
export declare abstract class BaseStateManager {
_common: Common;
_debug: Debugger;
_cache: Cache;
_touched: Set<AddressHex>;
_touchedStack: Set<AddressHex>[];
_customTouched: Set<AddressHex>;
_originalStorageCache: Map<AddressHex, Map<AddressHex, Buffer>>;
_accessedStorage: Map<string, Set<string>>[];
_accessedStorageReverted: Map<string, Set<string>>[];
_checkpointCount: number;
/**
* StateManager is run in DEBUG mode (default: false)
* Taken from DEBUG environment variable
*
* Safeguards on debug() calls are added for
* performance reasons to avoid string literal evaluation
* @hidden
*/
protected readonly DEBUG: boolean;
/**
* Needs to be called from the subclass constructor
*/
constructor(opts: DefaultStateManagerOpts);
/**
* Gets the account associated with `address`. Returns an empty account if the account does not exist.
* @param address - Address of the `account` to get
*/
getAccount(address: Address): Promise<Account>;
/**
* Saves an account into state under the provided `address`.
* @param address - Address under which to store `account`
* @param account - The account to store
*/
putAccount(address: Address, account: Account): Promise<void>;
/**
* Deletes an account from state under the provided `address`. The account will also be removed from the state trie.
* @param address - Address of the account which should be deleted
*/
deleteAccount(address: Address): Promise<void>;
/**
* Marks an account as touched, according to the definition
* in [EIP-158](https://eips.ethereum.org/EIPS/eip-158).
* This happens when the account is triggered for a state-changing
* event. Touched accounts that are empty will be cleared
* at the end of the tx.
*/
touchAccount(address: Address): void;
abstract putContractCode(address: Address, value: Buffer): Promise<void>;
abstract getContractStorage(address: Address, key: Buffer): Promise<Buffer>;
abstract putContractStorage(address: Address, key: Buffer, value: Buffer): Promise<void>;
/**
* Caches the storage value associated with the provided `address` and `key`
* on first invocation, and returns the cached (original) value from then
* onwards. This is used to get the original value of a storage slot for
* computing gas costs according to EIP-1283.
* @param address - Address of the account to get the storage for
* @param key - Key in the account's storage to get the value for. Must be 32 bytes long.
*/
getOriginalContractStorage(address: Address, key: Buffer): Promise<Buffer>;
/**
* Clears the original storage cache. Refer to {@link StateManager.getOriginalContractStorage}
* for more explanation.
*/
_clearOriginalStorageCache(): void;
/**
* Clears the original storage cache. Refer to {@link StateManager.getOriginalContractStorage}
* for more explanation. Alias of the internal {@link StateManager._clearOriginalStorageCache}
*/
clearOriginalStorageCache(): void;
/**
* Checkpoints the current state of the StateManager instance.
* State changes that follow can then be committed by calling
* `commit` or `reverted` by calling rollback.
*
* Partial implementation, called from the subclass.
*/
checkpoint(): Promise<void>;
/**
* Merges a storage map into the last item of the accessed storage stack
*/
private _accessedStorageMerge;
/**
* Commits the current change-set to the instance since the
* last call to checkpoint.
*
* Partial implementation, called from the subclass.
*/
commit(): Promise<void>;
/**
* Reverts the current change-set to the instance since the
* last call to checkpoint.
*
* Partial implementation , called from the subclass.
*/
revert(): Promise<void>;
abstract hasGenesisState(): Promise<boolean>;
/**
* Generates a canonical genesis state on the instance based on the
* configured chain parameters. Will error if there are uncommitted
* checkpoints on the instance.
*/
generateCanonicalGenesis(): Promise<void>;
/**
* Initializes the provided genesis state into the state trie
* @param initState address -> balance | [balance, code, storage]
*/
generateGenesis(initState: any): Promise<void>;
/**
* Checks if the `account` corresponding to `address`
* is empty or non-existent as defined in
* EIP-161 (https://eips.ethereum.org/EIPS/eip-161).
* @param address - Address to check
*/
accountIsEmpty(address: Address): Promise<boolean>;
/**
* Removes accounts form the state trie that have been touched,
* as defined in EIP-161 (https://eips.ethereum.org/EIPS/eip-161).
*/
cleanupTouchedAccounts(): Promise<void>;
/** EIP-2929 logic
* This should only be called from within the EVM
*/
/**
* Returns true if the address is warm in the current context
* @param address - The address (as a Buffer) to check
*/
isWarmedAddress(address: Buffer): boolean;
/**
* Add a warm address in the current context
* @param address - The address (as a Buffer) to check
*/
addWarmedAddress(address: Buffer): void;
/**
* Returns true if the slot of the address is warm
* @param address - The address (as a Buffer) to check
* @param slot - The slot (as a Buffer) to check
*/
isWarmedStorage(address: Buffer, slot: Buffer): boolean;
/**
* Mark the storage slot in the address as warm in the current context
* @param address - The address (as a Buffer) to check
* @param slot - The slot (as a Buffer) to check
*/
addWarmedStorage(address: Buffer, slot: Buffer): void;
/**
* Clear the warm accounts and storage. To be called after a transaction finished.
* @param boolean - If true, returns an EIP-2930 access list generated
*/
clearWarmedAccounts(): void;
/**
* Generates an EIP-2930 access list
*
* Note: this method is not yet part of the {@link StateManager} interface.
* If not implemented, {@link VM.runTx} is not allowed to be used with the
* `reportAccessList` option and will instead throw.
*
* Note: there is an edge case on accessList generation where an
* internal call might revert without an accessList but pass if the
* accessList is used for a tx run (so the subsequent behavior might change).
* This edge case is not covered by this implementation.
*
* @param addressesRemoved - List of addresses to be removed from the final list
* @param addressesOnlyStorage - List of addresses only to be added in case of present storage slots
*
* @returns - an [@ethereumjs/tx](https://github.com/ethereumjs/ethereumjs-monorepo/packages/tx) `AccessList`
*/
generateAccessList(addressesRemoved?: Address[], addressesOnlyStorage?: Address[]): AccessList;
}
export {};