Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subdivide runState, refactor loop #498

Merged
merged 11 commits into from
Apr 25, 2019
Merged

Subdivide runState, refactor loop #498

merged 11 commits into from
Apr 25, 2019

Conversation

s1na
Copy link
Contributor

@s1na s1na commented Apr 24, 2019

This is a mixed bag PR, that partly aims to prepare future migration of Loop to typescript:

  • It breaks runState into runState, env data and result data
  • Passes these parts individually to EEI
  • (BREAKING) drops emitFreeLogs flag. This is a very custom logic that can be after v4 implemented by inheriting Loop
  • Marks runJit as deprecated, and adds the necessary logic for running precompiles directly to Interpreter
  • Makes runState an attribute of Loop instead of passing it to every method

@coveralls
Copy link

Coverage Status

Coverage increased (+0.05%) to 95.354% when pulling 51b8d6b on refactor/runState into e66ae9d on v4.

@holgerd77
Copy link
Member

runJit has never been part of the documented API, wonder if it is necessary to go through the deprecation process.

Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions to be answered but no blockers - eventually things can subsequently be addressed if necessary, will approve.

@@ -4,7 +4,6 @@ const BN = utils.BN
const exceptions = require('../exceptions.js')
const ERROR = exceptions.ERROR
const VmError = exceptions.VmError
const PStateManager = require('../state/promisified').default
const MASK_160 = new BN(1).shln(160).subn(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great to have StateManager refactored out of here. 👍 😄

if (empty) {
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount')))
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is happening here respectively why has this been added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to calculate the gas cost of selfdestruct. It used to be here, but I had moved it to EEI to avoid using stateManager here. Now I've added the necessary method isAccountEmpty to EEI, and brought the gas calculation again back to the opcode handler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks.

@@ -892,7 +897,7 @@ function updateSstoreGas (runState, found, value) {
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'sstoreReset')))
} else if (value.length === 0 && found.length) {
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'sstoreReset')))
runState.gasRefund.iaddn(runState._common.param('gasPrices', 'sstoreRefund'))
runState.eei.refundGas(runState._common.param('gasPrices', 'sstoreRefund'))
} else if (value.length !== 0 && !found.length) {
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'sstoreSet')))
} else if (value.length !== 0 && found.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transition of environment data access from runState to EEI, nice, looks good.

}

return { name: opcode, opcode: op, fee: fee, dynamic: code[2], isAsync: code[3] }
return { name: opcode, opcode: op, fee: code[1], dynamic: code[2], isAsync: code[3] }
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

freeLogs removal, cleanup, ok.


constructor (env: any) {
constructor (env: any, runState: any, result: any, state: PStateManager, interpreter: any) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner separation like this with reduced runState + env and explicit results.

Not sure if interpreter should be passed to the EEI, but it's at least better to have this passed explicit/separate then being hidden in the environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interpreter is needed for calls and creates. Not sure how to work around it...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might these kind of logic rather belong to the Interpreter itself? We can keep for now and keep this in discussion though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm thinking along the same lines. I think it makes sense to move most of the call/create logic to Interpreter. One downside would be however that the logic would be further away from the opcode handlers.

lib/evm/loop.js Outdated
isStatic: opts.message.isStatic || false,
depth: opts.message.depth || 0,
gasPrice: opts.txContext.gasPrice,
origin: opts.txContext.origin || opts.message.caller || utils.zeros(32),
block: opts.block || new Block()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaner to have this encapsulated in message and txContext, good. 👍


constructor (env: any, runState: any, result: any, state: PStateManager, interpreter: any) {
this._env = env
this._runState = runState
this._result = result
this._state = state
this._interpreter = interpreter
this._lastReturned = Buffer.alloc(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also just for understanding: what is the main reasoning for this move?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reasoning was to localize variables as much as possible. lastReturned is there to track the last value returned from a call/create. It was only used in EEI, so I moved it from runState. But if the call/create logic moves elsewhere (I'm thinking Interpreter) this might need to be moved again. So, not quite sure yet where to put it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, makes sense.

_common: this._vm._common,
stateManager: this._state._wrapped,
storageReader: new StorageReader(this._state._wrapped)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to have this locally here, logically fits.

storageReader: opts.storageReader || new StorageReader(this._state._wrapped)
}
storageReader: opts.storageReader || this._runState.storageReader
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to have this base value initialization and runtime value assignment separation.

gas: this._runState.gasLeft,
gasUsed,
'return': this._result.returnValue ? this._result.returnValue : Buffer.alloc(0)
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inlined parseVmResults, ok.

@s1na s1na merged commit 30154be into v4 Apr 25, 2019
@s1na s1na deleted the refactor/runState branch April 25, 2019 09:00
@s1na s1na mentioned this pull request Apr 25, 2019
23 tasks
@s1na s1na mentioned this pull request May 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants