From f15f9d2abca3f8718966d6ded53a3ab9c77dcfdc Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Mon, 6 Jul 2020 13:30:10 +0200 Subject: [PATCH 1/9] vm -> tangerineWhistle: added HF and alias to VM and tests, adopted test:state:selectedForks CI script --- packages/vm/lib/index.ts | 1 + packages/vm/package.json | 2 +- packages/vm/tests/config.js | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 537926b93a..4500104625 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -110,6 +110,7 @@ export default class VM extends AsyncEventEmitter { const chain = opts.chain ? opts.chain : 'mainnet' const hardfork = opts.hardfork ? opts.hardfork : 'petersburg' const supportedHardforks = [ + 'tangerineWhistle', 'spuriousDragon', 'byzantium', 'constantinople', diff --git a/packages/vm/package.json b/packages/vm/package.json index 544c148bcd..a1f181392e 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -15,7 +15,7 @@ "docs:build": "typedoc --options typedoc.js", "test:state": "ts-node ./tests/tester --state", "test:state:allForks": "npm run test:state -- --fork=SpuriousDragon && npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", - "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=SpuriousDragon", + "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=TangerineWhistle", "test:state:slow": "npm run test:state -- --runSkipped=slow", "test:buildIntegrity": "npm run test:state -- --test='stackOverflow'", "test:blockchain": "node -r ts-node/register --stack-size=1500 ./tests/tester --blockchain", diff --git a/packages/vm/tests/config.js b/packages/vm/tests/config.js index 78cdc89427..c752750a0e 100644 --- a/packages/vm/tests/config.js +++ b/packages/vm/tests/config.js @@ -119,6 +119,11 @@ const SKIP_VM = [ * @returns {String} Either an alias of the forkConfig param, or the forkConfig param itself */ function getRequiredForkConfigAlias(forkConfig) { + // TangerineWhistle is named EIP150 (attention: misleading name) + // in the client-independent consensus test suite + if (String(forkConfig).match(/^tangerineWhistle$/i)) { + return 'EIP150' + } // SpuriousDragon is named EIP158 (attention: misleading name) // in the client-independent consensus test suite if (String(forkConfig).match(/^spuriousDragon$/i)) { From a2a2354155335ed9e70e66c0819e8739e7afc2ed Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Mon, 6 Jul 2020 13:45:50 +0200 Subject: [PATCH 2/9] vm -> tangerineWhistle: added spuriousDragon HF separation switch for account creation and CREATE nonce increment (EIP-161) --- packages/vm/lib/evm/evm.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 88acdae009..52df32be56 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -221,7 +221,10 @@ export default class EVM { await this._vm._emit('newContract', newContractEvent) toAccount = await this._state.getAccount(message.to) - toAccount.nonce = new BN(toAccount.nonce).addn(1).toArrayLike(Buffer) + // EIP-161 on account creation and CREATE execution + if (this._vm._common.gteHardfork('spuriousDragon')) { + toAccount.nonce = new BN(toAccount.nonce).addn(1).toArrayLike(Buffer) + } // Add tx value to the `to` account let errorMessage From 2f9ed3c6b064465057a47a6e1fed341ff51354a1 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Tue, 7 Jul 2020 10:26:02 +0200 Subject: [PATCH 3/9] vm -> tangerineWhistle: only delete touched accounts on spuriousDragon or later (EIP-161) --- packages/vm/lib/state/stateManager.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/vm/lib/state/stateManager.ts b/packages/vm/lib/state/stateManager.ts index b9b7fd6588..c7e08bda9f 100644 --- a/packages/vm/lib/state/stateManager.ts +++ b/packages/vm/lib/state/stateManager.ts @@ -482,12 +482,14 @@ export default class DefaultStateManager implements StateManager { * as defined in EIP-161 (https://eips.ethereum.org/EIPS/eip-161). */ async cleanupTouchedAccounts(): Promise { - const touchedArray = Array.from(this._touched) - for (const addressHex of touchedArray) { - const address = Buffer.from(addressHex, 'hex') - const empty = await this.accountIsEmpty(address) - if (empty) { - this._cache.del(address) + if (this._common.gteHardfork('spuriousDragon')) { + const touchedArray = Array.from(this._touched) + for (const addressHex of touchedArray) { + const address = Buffer.from(addressHex, 'hex') + const empty = await this.accountIsEmpty(address) + if (empty) { + this._cache.del(address) + } } } this._touched.clear() From 6bb93d86fb3477eb8c9e15c14118f403c643b5c2 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Wed, 8 Jul 2020 13:40:57 +0200 Subject: [PATCH 4/9] vm -> tangerineWhistle: added separation on EIP-161 SELFDESTRUCT gas costs, new accountExists StateManager function --- packages/vm/lib/evm/eei.ts | 2 +- packages/vm/lib/evm/opFns.ts | 26 +++++++++++++---- packages/vm/lib/state/cache.ts | 20 ++++++++----- packages/vm/lib/state/interface.ts | 1 + packages/vm/lib/state/stateManager.ts | 15 ++++++++-- packages/vm/tests/api/state/stateManager.js | 31 +++++++++++++++++++++ 6 files changed, 80 insertions(+), 15 deletions(-) diff --git a/packages/vm/lib/evm/eei.ts b/packages/vm/lib/evm/eei.ts index 7f22d09a6a..83201cd53e 100644 --- a/packages/vm/lib/evm/eei.ts +++ b/packages/vm/lib/evm/eei.ts @@ -576,7 +576,7 @@ export default class EEI { } /** - * Returns true if account is empty (according to EIP-161). + * Returns true if account is empty or non-existent (according to EIP-161). * @param address - Address of account */ async isAccountEmpty(address: Buffer): Promise { diff --git a/packages/vm/lib/evm/opFns.ts b/packages/vm/lib/evm/opFns.ts index 53e4f3a962..ba78a3176b 100644 --- a/packages/vm/lib/evm/opFns.ts +++ b/packages/vm/lib/evm/opFns.ts @@ -789,13 +789,29 @@ export const handlers: { [k: string]: OpHandler } = { } const selfdestructToAddressBuf = addressToBuffer(selfdestructToAddress) - const balance = await runState.eei.getExternalBalance(runState.eei.getAddress()) - if (balance.gtn(0)) { - const empty = await runState.eei.isAccountEmpty(selfdestructToAddressBuf) - if (empty) { - runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) + let deductGas = false + if (runState._common.gteHardfork('spuriousDragon')) { + // EIP-161: State Trie Clearing + const balance = await runState.eei.getExternalBalance(runState.eei.getAddress()) + if (balance.gtn(0)) { + // This technically checks if account is empty or non-existent + // TODO: improve on the API here (EEI and StateManager) + const empty = await runState.eei.isAccountEmpty(selfdestructToAddressBuf) + if (empty) { + const account = await runState.stateManager.getAccount(selfdestructToAddressBuf) + deductGas = true + } + } + } else { + // Pre EIP-161 (Spurious Dragon) gas semantics + const exists = await runState.stateManager.accountExists(selfdestructToAddressBuf) + if (!exists) { + deductGas = true } } + if (deductGas) { + runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) + } return runState.eei.selfDestruct(selfdestructToAddressBuf) }, diff --git a/packages/vm/lib/state/cache.ts b/packages/vm/lib/state/cache.ts index e126b453c5..e278e2b2da 100644 --- a/packages/vm/lib/state/cache.ts +++ b/packages/vm/lib/state/cache.ts @@ -54,24 +54,30 @@ export default class Cache { /** * Looks up address in underlying trie. * @param address - Address of account + * @param create - Create emtpy account if non-existent */ - async _lookupAccount(address: Buffer): Promise { + async _lookupAccount(address: Buffer, create: boolean = true): Promise { const raw = await this._trie.get(address) - const account = new Account(raw) - return account + if (raw || create) { + const account = new Account(raw) + return account + } } /** * Looks up address in cache, if not found, looks it up * in the underlying trie. * @param key - Address of account + * @param create - Create emtpy account if non-existent */ - async getOrLoad(key: Buffer): Promise { + async getOrLoad(key: Buffer, create: boolean = true): Promise { let account = this.lookup(key) if (!account) { - account = await this._lookupAccount(key) - this._update(key, account, false, false) + account = await this._lookupAccount(key, create) + if (account) { + this._update(key, account as Account, false, false) + } } return account @@ -87,7 +93,7 @@ export default class Cache { if (addressHex) { const address = Buffer.from(addressHex, 'hex') const account = await this._lookupAccount(address) - this._update(address, account, false, false) + this._update(address, account as Account, false, false) } } } diff --git a/packages/vm/lib/state/interface.ts b/packages/vm/lib/state/interface.ts index b6bf384ba8..00bc5d21d1 100644 --- a/packages/vm/lib/state/interface.ts +++ b/packages/vm/lib/state/interface.ts @@ -28,5 +28,6 @@ export interface StateManager { generateCanonicalGenesis(): Promise generateGenesis(initState: any): Promise accountIsEmpty(address: Buffer): Promise + accountExists(address: Buffer): Promise cleanupTouchedAccounts(): Promise } diff --git a/packages/vm/lib/state/stateManager.ts b/packages/vm/lib/state/stateManager.ts index c7e08bda9f..0c057b0236 100644 --- a/packages/vm/lib/state/stateManager.ts +++ b/packages/vm/lib/state/stateManager.ts @@ -71,7 +71,7 @@ export default class DefaultStateManager implements StateManager { * @param address - Address of the `account` to get */ async getAccount(address: Buffer): Promise { - const account = await this._cache.getOrLoad(address) + const account = (await this._cache.getOrLoad(address)) as Account return account } @@ -468,7 +468,8 @@ export default class DefaultStateManager implements StateManager { } /** - * Checks if the `account` corresponding to `address` is empty as defined in + * 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 */ @@ -477,6 +478,16 @@ export default class DefaultStateManager implements StateManager { return account.isEmpty() } + /** + * Checks if the `account` corresponding to `address` + * exists + * @param address - Address of the `account` to check + */ + async accountExists(address: Buffer): Promise { + const account = await this._cache.getOrLoad(address, false) + return account ? true : false + } + /** * Removes accounts form the state trie that have been touched, * as defined in EIP-161 (https://eips.ethereum.org/EIPS/eip-161). diff --git a/packages/vm/tests/api/state/stateManager.js b/packages/vm/tests/api/state/stateManager.js index dbf0c7c746..90280102f5 100644 --- a/packages/vm/tests/api/state/stateManager.js +++ b/packages/vm/tests/api/state/stateManager.js @@ -113,6 +113,37 @@ tape('StateManager', (t) => { }, ) + t.test( + 'should return false for a non-existent account', + async (st) => { + const stateManager = new DefaultStateManager() + const address = Buffer.from('a94f5374fce5edbc8e2a8697c15331677e6ebf0b', 'hex') + + let res = await stateManager.accountExists(address) + + st.notOk(res) + + st.end() + }, + ) + + t.test( + 'should return true for an existent account', + async (st) => { + const stateManager = new DefaultStateManager() + const account = createAccount('0x1', '0x1') + const address = Buffer.from('a94f5374fce5edbc8e2a8697c15331677e6ebf0b', 'hex') + + await stateManager.putAccount(address, account) + + let res = await stateManager.accountExists(address) + + st.ok(res) + + st.end() + }, + ) + t.test( 'should call the callback with a false boolean representing non-emptiness when the account is not empty', async (st) => { From f09a36b93527efaa516146ff5deeda1a0c6f3934 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Thu, 9 Jul 2020 20:40:09 +0200 Subject: [PATCH 5/9] [VM] TangerineWhistle: fix some SELFDESTRUCT tests --- packages/vm/lib/evm/opFns.ts | 11 ++++++++--- packages/vm/lib/runTx.ts | 2 +- packages/vm/lib/state/interface.ts | 3 ++- packages/vm/lib/state/stateManager.ts | 9 +++++++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/vm/lib/evm/opFns.ts b/packages/vm/lib/evm/opFns.ts index ba78a3176b..39e918eb2d 100644 --- a/packages/vm/lib/evm/opFns.ts +++ b/packages/vm/lib/evm/opFns.ts @@ -663,19 +663,24 @@ export const handlers: { [k: string]: OpHandler } = { subMemUsage(runState, inOffset, inLength) subMemUsage(runState, outOffset, outLength) - if (!value.isZero()) { + + if (!value.isZero()){ runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callValueTransfer'))) } gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft()) - + let data = Buffer.alloc(0) if (!inLength.isZero()) { data = runState.memory.read(inOffset.toNumber(), inLength.toNumber()) } const empty = await runState.eei.isAccountEmpty(toAddressBuf) + const forkGteSpuriousDragon = runState._common.gteHardfork('spuriousDragon') + if (empty) { - if (!value.isZero()) { + if (!forkGteSpuriousDragon) { + runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) + } else if (!value.isZero()) { runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) } } diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index cad65cce15..f8a80e2cae 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -184,7 +184,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { if (results.execResult.selfdestruct) { const keys = Object.keys(results.execResult.selfdestruct) for (const k of keys) { - await state.putAccount(Buffer.from(k, 'hex'), new Account()) + await state.deleteAccount(Buffer.from(k, 'hex')) } } await state.cleanupTouchedAccounts() diff --git a/packages/vm/lib/state/interface.ts b/packages/vm/lib/state/interface.ts index 00bc5d21d1..87026b61bc 100644 --- a/packages/vm/lib/state/interface.ts +++ b/packages/vm/lib/state/interface.ts @@ -10,7 +10,8 @@ export interface StorageDump { export interface StateManager { copy(): StateManager getAccount(address: Buffer): Promise - putAccount(address: Buffer, account: Account): Promise + putAccount(address: Buffer, account: Account | null): Promise + deleteAccount(address: Buffer): Promise touchAccount(address: Buffer): void putContractCode(address: Buffer, value: Buffer): Promise getContractCode(address: Buffer): Promise diff --git a/packages/vm/lib/state/stateManager.ts b/packages/vm/lib/state/stateManager.ts index 0c057b0236..7330e4d588 100644 --- a/packages/vm/lib/state/stateManager.ts +++ b/packages/vm/lib/state/stateManager.ts @@ -87,7 +87,11 @@ export default class DefaultStateManager implements StateManager { // if they have money or a non-zero nonce or code, then write to tree this._cache.put(address, account) this.touchAccount(address) - // this._trie.put(addressHex, account.serialize(), cb) + } + + async deleteAccount(address: Buffer) { + this._cache.del(address) + this.touchAccount(address) } /** @@ -475,6 +479,7 @@ export default class DefaultStateManager implements StateManager { */ async accountIsEmpty(address: Buffer): Promise { const account = await this.getAccount(address) + console.log(account.isEmpty()) return account.isEmpty() } @@ -484,7 +489,7 @@ export default class DefaultStateManager implements StateManager { * @param address - Address of the `account` to check */ async accountExists(address: Buffer): Promise { - const account = await this._cache.getOrLoad(address, false) + const account = await this._trie.get(address) return account ? true : false } From e2f5371f1cfbed398608b4c94b1e45b871b5f413 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Fri, 10 Jul 2020 16:36:52 +0200 Subject: [PATCH 6/9] [VM] fix call new account gas for pre-Spurious Dragon --- packages/vm/lib/evm/opFns.ts | 17 ++++++++++------- packages/vm/lib/state/stateManager.ts | 13 +++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/vm/lib/evm/opFns.ts b/packages/vm/lib/evm/opFns.ts index 39e918eb2d..5bf1b246e9 100644 --- a/packages/vm/lib/evm/opFns.ts +++ b/packages/vm/lib/evm/opFns.ts @@ -660,7 +660,6 @@ export const handlers: { [k: string]: OpHandler } = { if (runState.eei.isStatic() && !value.isZero()) { trap(ERROR.STATIC_STATE_CHANGE) } - subMemUsage(runState, inOffset, inLength) subMemUsage(runState, outOffset, outLength) @@ -674,13 +673,17 @@ export const handlers: { [k: string]: OpHandler } = { data = runState.memory.read(inOffset.toNumber(), inLength.toNumber()) } - const empty = await runState.eei.isAccountEmpty(toAddressBuf) - const forkGteSpuriousDragon = runState._common.gteHardfork('spuriousDragon') - - if (empty) { - if (!forkGteSpuriousDragon) { + if (runState._common.gteHardfork('spuriousDragon')) { + // We are at or after Spurious Dragon + // Call new account gas: account is DEAD and we transfer nonzero value + if (runState.stateManager.accountIsEmpty(toAddressBuf) && !value.isZero()) { runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) - } else if (!value.isZero()) { + } + } else if ( !(await runState.stateManager.accountExists(toAddressBuf))){ + // We are before Spurious Dragon + // Call new account gas: account does not exist (it is not in the state trie, not even as an "empty" account) + const accountDoesNotExist = !(await runState.stateManager.accountExists(toAddressBuf)) + if (accountDoesNotExist) { runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) } } diff --git a/packages/vm/lib/state/stateManager.ts b/packages/vm/lib/state/stateManager.ts index 7330e4d588..a5ba3c72a7 100644 --- a/packages/vm/lib/state/stateManager.ts +++ b/packages/vm/lib/state/stateManager.ts @@ -115,7 +115,7 @@ export default class DefaultStateManager implements StateManager { const codeHash = keccak256(value) if (codeHash.equals(KECCAK256_NULL)) { - return + //return } const account = await this.getAccount(address) @@ -479,7 +479,6 @@ export default class DefaultStateManager implements StateManager { */ async accountIsEmpty(address: Buffer): Promise { const account = await this.getAccount(address) - console.log(account.isEmpty()) return account.isEmpty() } @@ -489,8 +488,14 @@ export default class DefaultStateManager implements StateManager { * @param address - Address of the `account` to check */ async accountExists(address: Buffer): Promise { - const account = await this._trie.get(address) - return account ? true : false + const account = await this._cache.lookup(address) + if (account) { + return true; + } + if (await this._cache._trie.get(address)) { + return true; + } + return false } /** From 46d9cd6ab36514af30177eba10a296c8bacbaaf3 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Mon, 13 Jul 2020 19:48:07 +0200 Subject: [PATCH 7/9] [VM] fix case where miner account gets 0 gas fees --- packages/vm/lib/runTx.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index f8a80e2cae..9f24fc1c13 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -174,9 +174,12 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { const minerAccount = await state.getAccount(block.header.coinbase) // add the amount spent on gas to the miner's account minerAccount.balance = toBuffer(new BN(minerAccount.balance).add(results.amountSpent)) - if (!new BN(minerAccount.balance).isZero()) { - await state.putAccount(block.header.coinbase, minerAccount) - } + + // Put the miner account into the state. If the balance of the miner account remains zero, note that + // the state.putAccount function puts this into the "touched" accounts. This will thus be removed when + // we clean the touched accounts below in case we are in a fork >= SpuriousDragon + await state.putAccount(block.header.coinbase, minerAccount) + /* * Cleanup accounts From 04eaff3834f9800b62e1da8ea9469fd80e1d98c4 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Mon, 13 Jul 2020 20:08:37 +0200 Subject: [PATCH 8/9] [VM] fix SpuriousDragon and lint --- packages/vm/lib/evm/opFns.ts | 10 +++++----- packages/vm/lib/runTx.ts | 1 - packages/vm/lib/state/stateManager.ts | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/vm/lib/evm/opFns.ts b/packages/vm/lib/evm/opFns.ts index 5bf1b246e9..31f911fe90 100644 --- a/packages/vm/lib/evm/opFns.ts +++ b/packages/vm/lib/evm/opFns.ts @@ -662,12 +662,12 @@ export const handlers: { [k: string]: OpHandler } = { } subMemUsage(runState, inOffset, inLength) subMemUsage(runState, outOffset, outLength) - - if (!value.isZero()){ + + if (!value.isZero()) { runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callValueTransfer'))) } gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft()) - + let data = Buffer.alloc(0) if (!inLength.isZero()) { data = runState.memory.read(inOffset.toNumber(), inLength.toNumber()) @@ -676,10 +676,10 @@ export const handlers: { [k: string]: OpHandler } = { if (runState._common.gteHardfork('spuriousDragon')) { // We are at or after Spurious Dragon // Call new account gas: account is DEAD and we transfer nonzero value - if (runState.stateManager.accountIsEmpty(toAddressBuf) && !value.isZero()) { + if ((await runState.stateManager.accountIsEmpty(toAddressBuf)) && !value.isZero()) { runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount'))) } - } else if ( !(await runState.stateManager.accountExists(toAddressBuf))){ + } else if (!(await runState.stateManager.accountExists(toAddressBuf))) { // We are before Spurious Dragon // Call new account gas: account does not exist (it is not in the state trie, not even as an "empty" account) const accountDoesNotExist = !(await runState.stateManager.accountExists(toAddressBuf)) diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 9f24fc1c13..8b2822f211 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -179,7 +179,6 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // the state.putAccount function puts this into the "touched" accounts. This will thus be removed when // we clean the touched accounts below in case we are in a fork >= SpuriousDragon await state.putAccount(block.header.coinbase, minerAccount) - /* * Cleanup accounts diff --git a/packages/vm/lib/state/stateManager.ts b/packages/vm/lib/state/stateManager.ts index a5ba3c72a7..933479214f 100644 --- a/packages/vm/lib/state/stateManager.ts +++ b/packages/vm/lib/state/stateManager.ts @@ -88,7 +88,7 @@ export default class DefaultStateManager implements StateManager { this._cache.put(address, account) this.touchAccount(address) } - + async deleteAccount(address: Buffer) { this._cache.del(address) this.touchAccount(address) @@ -490,10 +490,10 @@ export default class DefaultStateManager implements StateManager { async accountExists(address: Buffer): Promise { const account = await this._cache.lookup(address) if (account) { - return true; + return true } if (await this._cache._trie.get(address)) { - return true; + return true } return false } From a0bd87b1ceabee7c35bf99ffd316612e0af020c3 Mon Sep 17 00:00:00 2001 From: Jochem Brouwer Date: Mon, 13 Jul 2020 20:08:55 +0200 Subject: [PATCH 9/9] [VM] add tangerineWhistle to state all forks test --- packages/vm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vm/package.json b/packages/vm/package.json index a1f181392e..84db915333 100644 --- a/packages/vm/package.json +++ b/packages/vm/package.json @@ -14,7 +14,7 @@ "coverage:test": "npm run build && tape './tests/api/**/*.js' ./tests/tester.js --state --dist", "docs:build": "typedoc --options typedoc.js", "test:state": "ts-node ./tests/tester --state", - "test:state:allForks": "npm run test:state -- --fork=SpuriousDragon && npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", + "test:state:allForks": "npm run test:state -- --fork=TangerineWhistle && npm run test:state -- --fork=SpuriousDragon && npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=TangerineWhistle", "test:state:slow": "npm run test:state -- --runSkipped=slow", "test:buildIntegrity": "npm run test:state -- --test='stackOverflow'",