Skip to content

Commit

Permalink
StateManager: _* methods/properties -> protected
Browse files Browse the repository at this point in the history
  • Loading branch information
holgerd77 committed Jul 4, 2023
1 parent 38cf32e commit 0a55c87
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 52 deletions.
74 changes: 39 additions & 35 deletions packages/statemanager/src/ethersStateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ export interface EthersStateManagerOpts {
}

export class EthersStateManager implements EVMStateManagerInterface {
private provider: ethers.JsonRpcProvider
private contractCache: Map<string, Uint8Array>
private storageCache: StorageCache
private blockTag: string
_accountCache: AccountCache
protected _provider: ethers.JsonRpcProvider
protected _contractCache: Map<string, Uint8Array>
protected _storageCache: StorageCache
protected _blockTag: string
protected _accountCache: AccountCache
originalStorageCache: OriginalStorageCache
private _debug: Debugger
private DEBUG: boolean
protected _debug: Debugger
protected DEBUG: boolean
constructor(opts: EthersStateManagerOpts) {
// Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables
// Additional window check is to prevent vite browser bundling (and potentially other) to break
Expand All @@ -35,29 +35,29 @@ export class EthersStateManager implements EVMStateManagerInterface {

this._debug = createDebugLogger('statemanager:ethersStateManager')
if (typeof opts.provider === 'string') {
this.provider = new ethers.JsonRpcProvider(opts.provider)
this._provider = new ethers.JsonRpcProvider(opts.provider)
} else if (opts.provider instanceof ethers.JsonRpcProvider) {
this.provider = opts.provider
this._provider = opts.provider
} else {
throw new Error(`valid JsonRpcProvider or url required; got ${opts.provider}`)
}

this.blockTag = opts.blockTag === 'earliest' ? opts.blockTag : bigIntToHex(opts.blockTag)
this._blockTag = opts.blockTag === 'earliest' ? opts.blockTag : bigIntToHex(opts.blockTag)

this.contractCache = new Map()
this.storageCache = new StorageCache({ size: 100000, type: CacheType.ORDERED_MAP })
this._contractCache = new Map()
this._storageCache = new StorageCache({ size: 100000, type: CacheType.ORDERED_MAP })
this._accountCache = new AccountCache({ size: 100000, type: CacheType.ORDERED_MAP })

this.originalStorageCache = new OriginalStorageCache(this.getContractStorage.bind(this))
}

shallowCopy(): EthersStateManager {
const newState = new EthersStateManager({
provider: this.provider,
blockTag: BigInt(this.blockTag),
provider: this._provider,
blockTag: BigInt(this._blockTag),
})
newState.contractCache = new Map(this.contractCache)
newState.storageCache = new StorageCache({
newState._contractCache = new Map(this._contractCache)
newState._storageCache = new StorageCache({
size: 100000,
type: CacheType.ORDERED_MAP,
})
Expand All @@ -74,18 +74,18 @@ export class EthersStateManager implements EVMStateManagerInterface {
* @param blockTag - the new block tag to use when querying the provider
*/
setBlockTag(blockTag: bigint | 'earliest'): void {
this.blockTag = blockTag === 'earliest' ? blockTag : bigIntToHex(blockTag)
this._blockTag = blockTag === 'earliest' ? blockTag : bigIntToHex(blockTag)
this.clearCaches()
if (this.DEBUG) this._debug(`setting block tag to ${this.blockTag}`)
if (this.DEBUG) this._debug(`setting block tag to ${this._blockTag}`)
}

/**
* Clears the internal cache so all accounts, contract code, and storage slots will
* initially be retrieved from the provider
*/
clearCaches(): void {
this.contractCache.clear()
this.storageCache.clear()
this._contractCache.clear()
this._storageCache.clear()
this._accountCache.clear()
}

Expand All @@ -96,11 +96,11 @@ export class EthersStateManager implements EVMStateManagerInterface {
* Returns an empty `Uint8Array` if the account has no associated code.
*/
async getContractCode(address: Address): Promise<Uint8Array> {
let codeBytes = this.contractCache.get(address.toString())
let codeBytes = this._contractCache.get(address.toString())
if (codeBytes !== undefined) return codeBytes
const code = await this.provider.getCode(address.toString(), this.blockTag)
const code = await this._provider.getCode(address.toString(), this._blockTag)
codeBytes = toBytes(code)
this.contractCache.set(address.toString(), codeBytes)
this._contractCache.set(address.toString(), codeBytes)
return codeBytes
}

Expand All @@ -112,7 +112,7 @@ export class EthersStateManager implements EVMStateManagerInterface {
*/
async putContractCode(address: Address, value: Uint8Array): Promise<void> {
// Store contract code in the cache
this.contractCache.set(address.toString(), value)
this._contractCache.set(address.toString(), value)
}

/**
Expand All @@ -130,16 +130,16 @@ export class EthersStateManager implements EVMStateManagerInterface {
throw new Error('Storage key must be 32 bytes long')
}

let value = this.storageCache!.get(address, key)
let value = this._storageCache!.get(address, key)
if (value !== undefined) {
return value
}

// Retrieve storage slot from provider if not found in cache
const storage = await this.provider.getStorage(
const storage = await this._provider.getStorage(
address.toString(),
bytesToBigInt(key),
this.blockTag
this._blockTag
)
value = toBytes(storage)

Expand All @@ -157,15 +157,15 @@ export class EthersStateManager implements EVMStateManagerInterface {
* If it is empty or filled with zeros, deletes the value.
*/
async putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise<void> {
this.storageCache.put(address, key, value)
this._storageCache.put(address, key, value)
}

/**
* Clears all storage entries for the account corresponding to `address`.
* @param address - Address to clear the storage of
*/
async clearContractStorage(address: Address): Promise<void> {
this.storageCache.clearContractStorage(address)
this._storageCache.clearContractStorage(address)
}

/**
Expand All @@ -176,7 +176,7 @@ export class EthersStateManager implements EVMStateManagerInterface {
* Both are represented as `0x` prefixed hex strings.
*/
dumpStorage(address: Address): Promise<StorageDump> {
const storageMap = this.storageCache._lruCache?.get(address.toString())
const storageMap = this._storageCache._lruCache?.get(address.toString())
const dump: StorageDump = {}
if (storageMap !== undefined) {
for (const slot of storageMap) {
Expand All @@ -196,7 +196,11 @@ export class EthersStateManager implements EVMStateManagerInterface {
const localAccount = this._accountCache.get(address)
if (localAccount !== undefined) return true
// Get merkle proof for `address` from provider
const proof = await this.provider.send('eth_getProof', [address.toString(), [], this.blockTag])
const proof = await this._provider.send('eth_getProof', [
address.toString(),
[],
this._blockTag,
])

const proofBuf = proof.accountProof.map((proofNode: string) => toBytes(proofNode))

Expand Down Expand Up @@ -233,10 +237,10 @@ export class EthersStateManager implements EVMStateManagerInterface {
*/
async getAccountFromProvider(address: Address): Promise<Account> {
if (this.DEBUG) this._debug(`retrieving account data from ${address.toString()} from provider`)
const accountData = await this.provider.send('eth_getProof', [
const accountData = await this._provider.send('eth_getProof', [
address.toString(),
[],
this.blockTag,
this._blockTag,
])
const account = Account.fromAccountData({
balance: BigInt(accountData.balance),
Expand Down Expand Up @@ -310,10 +314,10 @@ export class EthersStateManager implements EVMStateManagerInterface {
*/
async getProof(address: Address, storageSlots: Uint8Array[] = []): Promise<Proof> {
if (this.DEBUG) this._debug(`retrieving proof from provider for ${address.toString()}`)
const proof = await this.provider.send('eth_getProof', [
const proof = await this._provider.send('eth_getProof', [
address.toString(),
[storageSlots.map((slot) => bytesToHex(slot))],
this.blockTag,
this._blockTag,
])

return proof
Expand Down
18 changes: 9 additions & 9 deletions packages/statemanager/src/stateManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,15 @@ export interface DefaultStateManagerOpts {
* `@ethereumjs/trie` trie as a data backend.
*/
export class DefaultStateManager implements EVMStateManagerInterface {
_debug: Debugger
_accountCache?: AccountCache
_storageCache?: StorageCache
protected _debug: Debugger
protected _accountCache?: AccountCache
protected _storageCache?: StorageCache

originalStorageCache: OriginalStorageCache

_trie: Trie
_storageTries: { [key: string]: Trie }
_codeCache: { [key: string]: Uint8Array }
protected _trie: Trie
protected _storageTries: { [key: string]: Trie }
protected _codeCache: { [key: string]: Uint8Array }

protected readonly _prefixCodeHashes: boolean
protected readonly _accountCacheSettings: CacheSettings
Expand Down Expand Up @@ -367,7 +367,7 @@ export class DefaultStateManager implements EVMStateManagerInterface {
* cache or does a lookup.
* @private
*/
private async _getStorageTrie(address: Address, account: Account): Promise<Trie> {
protected async _getStorageTrie(address: Address, account: Account): Promise<Trie> {
// from storage cache
const addressHex = bytesToUnprefixedHex(address.bytes)
const storageTrie = this._storageTries[addressHex]
Expand Down Expand Up @@ -421,7 +421,7 @@ export class DefaultStateManager implements EVMStateManagerInterface {
* @param address - Address of the account whose storage is to be modified
* @param modifyTrie - Function to modify the storage trie of the account
*/
private async _modifyContractStorage(
protected async _modifyContractStorage(
address: Address,
account: Account,
modifyTrie: (storageTrie: Trie, done: Function) => void
Expand All @@ -443,7 +443,7 @@ export class DefaultStateManager implements EVMStateManagerInterface {
})
}

private async _writeContractStorage(
protected async _writeContractStorage(
address: Address,
account: Account,
key: Uint8Array,
Expand Down
21 changes: 13 additions & 8 deletions packages/statemanager/test/ethersStateManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,15 @@ describe('Ethers State Manager initialization tests', () => {
state instanceof EthersStateManager,
'was able to instantiate state manager with JsonRpcProvider subclass'
)
assert.equal((state as any).blockTag, '0x1', 'State manager starts with default block tag of 1')
assert.equal(
(state as any)._blockTag,
'0x1',
'State manager starts with default block tag of 1'
)

state = new EthersStateManager({ provider, blockTag: 1n })
assert.equal(
(state as any).blockTag,
(state as any)._blockTag,
'0x1',
'State Manager instantiated with predefined blocktag'
)
Expand Down Expand Up @@ -96,7 +100,8 @@ describe('Ethers State Manager API tests', () => {

await state.putContractCode(UNIerc20ContractAddress, UNIContractCode)
assert.ok(
typeof (state as any).contractCache.get(UNIerc20ContractAddress.toString()) !== 'undefined',
typeof (state as any)._contractCache.get(UNIerc20ContractAddress.toString()) !==
'undefined',
'UNI ERC20 contract code was found in cache'
)

Expand Down Expand Up @@ -183,21 +188,21 @@ describe('Ethers State Manager API tests', () => {

assert.equal(
undefined,
(state as any).contractCache.get(UNIerc20ContractAddress),
(state as any)._contractCache.get(UNIerc20ContractAddress),
'should not have any code for contract after cache is cleared'
)

assert.notEqual(
undefined,
(newState as any).contractCache.get(UNIerc20ContractAddress.toString()),
(newState as any)._contractCache.get(UNIerc20ContractAddress.toString()),
'state manager copy should have code for contract after cache is cleared on original state manager'
)

assert.equal((state as any).blockTag, '0x1', 'blockTag defaults to 1')
assert.equal((state as any)._blockTag, '0x1', 'blockTag defaults to 1')
state.setBlockTag(5n)
assert.equal((state as any).blockTag, '0x5', 'blockTag set to 0x5')
assert.equal((state as any)._blockTag, '0x5', 'blockTag set to 0x5')
state.setBlockTag('earliest')
assert.equal((state as any).blockTag, 'earliest', 'blockTag set to earliest')
assert.equal((state as any)._blockTag, 'earliest', 'blockTag set to earliest')
}
})
})
Expand Down

0 comments on commit 0a55c87

Please sign in to comment.