Skip to content

Commit

Permalink
Cache PStateManager's and its promisified functions
Browse files Browse the repository at this point in the history
  • Loading branch information
alcuadrado committed Sep 19, 2019
1 parent 283d0a8 commit 35b4b6c
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 67 deletions.
2 changes: 1 addition & 1 deletion lib/evm/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default class EVM {

constructor(vm: any, txContext: TxContext, block: any) {
this._vm = vm
this._state = new PStateManager(this._vm.stateManager)
this._state = this._vm.pStateManager
this._tx = txContext
this._block = block
}
Expand Down
2 changes: 1 addition & 1 deletion lib/evm/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class Interpreter {

constructor(vm: any, eei: EEI) {
this._vm = vm // TODO: remove when not needed
this._state = new PStateManager(vm.stateManager)
this._state = vm.pStateManager
this._eei = eei
this._runState = {
programCounter: 0,
Expand Down
4 changes: 4 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { default as runBlock, RunBlockOpts, RunBlockResult } from './runBlock'
import { EVMResult, ExecResult } from './evm/evm'
import { OpcodeList, getOpcodesForHF } from './evm/opcodes'
import runBlockchain from './runBlockchain'
import PStateManager from './state/promisified'
const promisify = require('util.promisify')
const AsyncEventEmitter = require('async-eventemitter')
const Trie = require('merkle-patricia-tree/secure.js')
Expand Down Expand Up @@ -73,6 +74,7 @@ export default class VM extends AsyncEventEmitter {
allowUnlimitedContractSize: boolean
_opcodes: OpcodeList
public readonly _emit: (topic: string, data: any) => Promise<void>
public readonly pStateManager: PStateManager

/**
* Instantiates a new [[VM]] Object.
Expand Down Expand Up @@ -118,6 +120,8 @@ export default class VM extends AsyncEventEmitter {
this.stateManager = new StateManager({ trie, common: this._common })
}

this.pStateManager = new PStateManager(this.stateManager)

this.blockchain = opts.blockchain || new Blockchain({ common: this._common })

this.allowUnlimitedContractSize =
Expand Down
4 changes: 2 additions & 2 deletions lib/runBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise<Ru
throw new Error('invalid input, block must be provided')
}

const state = new PStateManager(this.stateManager)
const state = this.pStateManager
const block = opts.block
const generateStateRoot = !!opts.generate

Expand Down Expand Up @@ -240,7 +240,7 @@ async function applyTransactions(this: VM, block: any) {
* the updated balances of their accounts to state.
*/
async function assignBlockRewards(this: VM, block: any): Promise<void> {
const state = new PStateManager(this.stateManager)
const state = this.pStateManager
const minerReward = new BN(this._common.param('pow', 'minerReward'))
const ommers = block.uncleHeaders
// Reward ommers
Expand Down
4 changes: 2 additions & 2 deletions lib/runTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default async function runTx(this: VM, opts: RunTxOpts): Promise<RunTxRes
throw new Error('tx has a higher gas limit than the block')
}

const state = new PStateManager(this.stateManager)
const state = this.pStateManager

await state.checkpoint()

Expand All @@ -89,7 +89,7 @@ export default async function runTx(this: VM, opts: RunTxOpts): Promise<RunTxRes
async function _runTx(this: VM, opts: RunTxOpts): Promise<RunTxResult> {
const block = opts.block
const tx = opts.tx
const state = new PStateManager(this.stateManager)
const state = this.pStateManager

/**
* The `beforeTx` event
Expand Down
106 changes: 47 additions & 59 deletions lib/state/promisified.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,87 +9,75 @@ import { default as StateManager, StorageDump } from './stateManager'
export default class PStateManager {
_wrapped: StateManager

public readonly getAccount: (addr: Buffer) => Promise<Account>
public readonly putAccount: (addr: Buffer, account: Account) => Promise<void>
public readonly putContractCode: (addr: Buffer, code: Buffer) => Promise<void>
public readonly getContractCode: (addr: Buffer) => Promise<Buffer>
public readonly getContractStorage: (addr: Buffer, key: Buffer) => Promise<any>
public readonly getOriginalContractStorage: (addr: Buffer, key: Buffer) => Promise<any>
public readonly putContractStorage: (addr: Buffer, key: Buffer, value: Buffer) => Promise<void>
public readonly clearContractStorage: (addr: Buffer) => Promise<void>
public readonly checkpoint: () => Promise<void>
public readonly commit: () => Promise<void>
public readonly revert: () => Promise<void>
public readonly getStateRoot: () => Promise<Buffer>
public readonly setStateRoot: (root: Buffer) => Promise<void>
public readonly dumpStorage: (address: Buffer) => Promise<StorageDump>
public readonly hasGenesisState: () => Promise<boolean>
public readonly generateCanonicalGenesis: () => Promise<void>
public readonly generateGenesis: (initState: any) => Promise<void>
public readonly accountIsEmpty: (address: Buffer) => Promise<boolean>
public readonly cleanupTouchedAccounts: () => Promise<void>

constructor(wrapped: StateManager) {
this._wrapped = wrapped
}

copy(): PStateManager {
return new PStateManager(this._wrapped.copy())
}
this.getAccount = promisify(this._wrapped.getAccount.bind(this._wrapped))

getAccount(addr: Buffer): Promise<Account> {
return promisify(this._wrapped.getAccount.bind(this._wrapped))(addr)
}
this.putAccount = promisify(this._wrapped.putAccount.bind(this._wrapped))

putAccount(addr: Buffer, account: Account): Promise<void> {
return promisify(this._wrapped.putAccount.bind(this._wrapped))(addr, account)
}
this.putContractCode = promisify(this._wrapped.putContractCode.bind(this._wrapped))

putContractCode(addr: Buffer, code: Buffer): Promise<void> {
return promisify(this._wrapped.putContractCode.bind(this._wrapped))(addr, code)
}
this.getContractCode = promisify(this._wrapped.getContractCode.bind(this._wrapped))

getContractCode(addr: Buffer): Promise<Buffer> {
return promisify(this._wrapped.getContractCode.bind(this._wrapped))(addr)
}
this.getContractStorage = promisify(this._wrapped.getContractStorage.bind(this._wrapped))

getContractStorage(addr: Buffer, key: Buffer): Promise<any> {
return promisify(this._wrapped.getContractStorage.bind(this._wrapped))(addr, key)
}
this.getOriginalContractStorage = promisify(
this._wrapped.getOriginalContractStorage.bind(this._wrapped),
)

getOriginalContractStorage(addr: Buffer, key: Buffer): Promise<any> {
return promisify(this._wrapped.getOriginalContractStorage.bind(this._wrapped))(addr, key)
}
this.putContractStorage = promisify(this._wrapped.putContractStorage.bind(this._wrapped))

putContractStorage(addr: Buffer, key: Buffer, value: Buffer): Promise<void> {
return promisify(this._wrapped.putContractStorage.bind(this._wrapped))(addr, key, value)
}
this.clearContractStorage = promisify(this._wrapped.clearContractStorage.bind(this._wrapped))

clearContractStorage(addr: Buffer): Promise<void> {
return promisify(this._wrapped.clearContractStorage.bind(this._wrapped))(addr)
}
this.checkpoint = promisify(this._wrapped.checkpoint.bind(this._wrapped))

checkpoint(): Promise<void> {
return promisify(this._wrapped.checkpoint.bind(this._wrapped))()
}
this.commit = promisify(this._wrapped.commit.bind(this._wrapped))

commit(): Promise<void> {
return promisify(this._wrapped.commit.bind(this._wrapped))()
}
this.revert = promisify(this._wrapped.revert.bind(this._wrapped))

revert(): Promise<void> {
return promisify(this._wrapped.revert.bind(this._wrapped))()
}
this.getStateRoot = promisify(this._wrapped.getStateRoot.bind(this._wrapped))

getStateRoot(): Promise<Buffer> {
return promisify(this._wrapped.getStateRoot.bind(this._wrapped))()
}
this.setStateRoot = promisify(this._wrapped.setStateRoot.bind(this._wrapped))

setStateRoot(root: Buffer): Promise<void> {
return promisify(this._wrapped.setStateRoot.bind(this._wrapped))(root)
}
this.dumpStorage = promisify(this._wrapped.dumpStorage.bind(this._wrapped))

dumpStorage(address: Buffer): Promise<StorageDump> {
return promisify(this._wrapped.dumpStorage.bind(this._wrapped))(address)
}
this.hasGenesisState = promisify(this._wrapped.hasGenesisState.bind(this._wrapped))

hasGenesisState(): Promise<boolean> {
return promisify(this._wrapped.hasGenesisState.bind(this._wrapped))()
}
this.generateCanonicalGenesis = promisify(
this._wrapped.generateCanonicalGenesis.bind(this._wrapped),
)

generateCanonicalGenesis(): Promise<void> {
return promisify(this._wrapped.generateCanonicalGenesis.bind(this._wrapped))()
}
this.generateGenesis = promisify(this._wrapped.generateGenesis.bind(this._wrapped))

generateGenesis(initState: any): Promise<void> {
return promisify(this._wrapped.generateGenesis.bind(this._wrapped))(initState)
}
this.accountIsEmpty = promisify(this._wrapped.accountIsEmpty.bind(this._wrapped))

accountIsEmpty(address: Buffer): Promise<boolean> {
return promisify(this._wrapped.accountIsEmpty.bind(this._wrapped))(address)
this.cleanupTouchedAccounts = promisify(
this._wrapped.cleanupTouchedAccounts.bind(this._wrapped),
)
}

cleanupTouchedAccounts(): Promise<void> {
return promisify(this._wrapped.cleanupTouchedAccounts.bind(this._wrapped))()
copy(): PStateManager {
return new PStateManager(this._wrapped.copy())
}
}
2 changes: 2 additions & 0 deletions tests/api/runBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const Block = require('ethereumjs-block')
const Common = require('ethereumjs-common').default
const util = require('ethereumjs-util')
const runBlock = require('../../dist/runBlock').default
const PStateManager = require('../../dist/state/promisified').default
const { StateManager } = require('../../dist/state')
const testData = require('./testdata.json')
const { setupVM } = require('./utils')
Expand All @@ -17,6 +18,7 @@ function setup (vm = null) {
const stateManager = new StateManager()
vm = {
stateManager,
pStateManager: new PStateManager(stateManager),
emit: (e, val, cb) => cb(),
_emit: (e, val) => new Promise((resolve, reject) => resolve()),
runTx: (opts) => new Promise((resolve, reject) => reject(new Error('test'))),
Expand Down
5 changes: 4 additions & 1 deletion tests/api/runBlockchain.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const Block = require('ethereumjs-block')
const Common = require('ethereumjs-common').default
const util = require('ethereumjs-util')
const runBlockchain = require('../../dist/runBlockchain').default
const PStateManager = require('../../dist/state/promisified').default
const { StateManager } = require('../../dist/state')
const { createGenesis } = require('./utils')

Expand All @@ -16,8 +17,10 @@ tape('runBlockchain', (t) => {
chain: 'goerli',
validate: false
})
const stateManager = new StateManager({ common: new Common('goerli') });
const vm = {
stateManager: new StateManager({ common: new Common('goerli') }),
stateManager,
pStateManager: new PStateManager(stateManager),
blockchain: blockchain
}

Expand Down
5 changes: 4 additions & 1 deletion tests/api/runTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ const tape = require('tape')
const Transaction = require('ethereumjs-tx').Transaction
const ethUtil = require('ethereumjs-util')
const runTx = require('../../dist/runTx').default
const PStateManager = require('../../dist/state/promisified').default
const { StateManager } = require('../../dist/state')
const VM = require('../../dist/index').default
const { createAccount } = require('./utils')

function setup (vm = null) {
if (vm === null) {
const stateManager = new StateManager({ })
vm = {
stateManager: new StateManager({ }),
stateManager,
pStateManager: new PStateManager(stateManager),
emit: (e, val, cb) => { cb() },
_emit: (e, val) => new Promise((resolve, reject) => resolve())
}
Expand Down

0 comments on commit 35b4b6c

Please sign in to comment.