-
Notifications
You must be signed in to change notification settings - Fork 765
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
[VM/Common] move gas base fees to Common #806
Conversation
Codecov Report
@@ Coverage Diff @@
## master #806 +/- ##
=======================================
Coverage 84.56% 84.56%
=======================================
Files 18 18
Lines 1250 1250
Branches 247 247
=======================================
Hits 1057 1057
Misses 125 125
Partials 68 68
Continue to review full report at Codecov.
|
I assumed base fees in |
[VM] remove unneeded opcode entries which only introduced gas changes [VM/Common] Add right fork base fees, remove STATICCALL from base opcodes [Common] remove STATICCALL from chainstart
b76ad58
to
2bef38c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, nice work @jochem-brouwer and - very cool - this even directly make it still into it's way to the new Common
release @evertonfraga is preparing, Common
is getting a lot more complete with that. 👍
throw new Error('base fee not defined for: ' + opcodeBuilder[key].name) | ||
} | ||
opcodeBuilder[key].fee = common.param('gasPrices', opcodeBuilder[key].name.toLowerCase()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, didn't get that at first and thought that the dictionary changes from above would be a breaking change we would eventually life with. Just seeing here that the structure is kept "as is". Nice implementation! 😄
0x3f: { name: 'EXTCODEHASH', fee: 700, isAsync: true }, // gas price change, EIP 1884 | ||
0x46: { name: 'CHAINID', fee: 2, isAsync: false }, // EIP 1344 | ||
0x47: { name: 'SELFBALANCE', fee: 5, isAsync: false }, // EIP 1884 | ||
0x54: { name: 'SLOAD', fee: 800, isAsync: true }, // gas price change, EIP 1884 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whew, really strange and a bit spooky that we have these gas price changes integrated here within this hardfork list creation structure, nice that this is factored out now.
}, | ||
"returndatacopy": { | ||
"v": 3, | ||
"d": "Base fee of the RETURNDATACOPY opcode" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Byzantium looks good, all opcodes included.
}, | ||
"create2": { | ||
"v": 32000, | ||
"d": "Base fee of the CREATE2 opcode" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Constantinople
looks ok, was a bit confused (again, this will likely never end 😋 ) on the Constantinople
/Petersburg
relation and how this translates to here but this look ok from this angle as well (since it's Constantinople
introducing all those opcodes), Petersburg
is just reverting changes to SSTORE
gas calculation.
"v": 40, | ||
"d": "Base fee of the DELEGATECALL opcode" | ||
} | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Homestead
looks good as well.
}, | ||
"selfdestruct": { | ||
"v": 5000, | ||
"d": "Base fee of the SELFDESTRUCT opcode" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TangerineWhistle
looks ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taken from: https://eips.ethereum.org/EIPS/eip-150 (the only EIP included)
@@ -806,9 +773,6 @@ export const handlers: { [k: string]: OpHandler } = { | |||
runState.eei.finish(returnData) | |||
}, | |||
REVERT: function (runState: RunState) { | |||
if (!runState._common.gteHardfork('byzantium')) { | |||
trap(ERROR.INVALID_OPCODE) | |||
} | |||
const [offset, length] = runState.stack.popN(2) | |||
subMemUsage(runState, offset, length) | |||
let returnData = Buffer.alloc(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had a short look here to give this an additional thought if there might be side effects (conclusion: no).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good PR Jochem!
Just documenting a few tiny nitpicks I noticed for later on.
if (baseFee === undefined) { | ||
throw new Error('base fee not defined for: ' + opcodeBuilder[key].name) | ||
} | ||
opcodeBuilder[key].fee = common.param('gasPrices', opcodeBuilder[key].name.toLowerCase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opcodeBuilder[key].fee = baseFee
also it'd be great if someone could have a look at optimizing common.param
(see #775)
}) | ||
0xfe: { name: 'INVALID', isAsync: false }, | ||
0xff: { name: 'SELFDESTRUCT', isAsync: true }, | ||
} | ||
|
||
// Array of hard forks in order. These changes are repeatedly applied to `opcodes` until the hard fork is in the future based upon the common | ||
// TODO: All gas price changes should be moved to common |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this TODO can be removed
@@ -36,198 +36,194 @@ export interface OpcodeList { | |||
} | |||
|
|||
// Base opcode list. The opcode list is extended in future hardforks | |||
const opcodes: OpcodeList = createOpcodes({ | |||
const opcodes = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can later on be renamed to chainstartOpcodes
for clarification (after support for other old HFs is added)
|
||
for (let fork = 0; fork < hardforkOpcodes.length; fork++) { | ||
if (common.gteHardfork(hardforkOpcodes[fork].hardforkName)) { | ||
opcodeBuilder = { ...opcodeBuilder, ...hardforkOpcodes[fork].opcodes } | ||
} | ||
} | ||
|
||
return opcodeBuilder | ||
for (let key in opcodeBuilder) { | ||
let baseFee = common.param('gasPrices', opcodeBuilder[key].name.toLowerCase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Post-review note: this toLowerCase()
is a pretty dangerous assumption - since Common
is using camelCase for multi-word parameter names - I actually wonder that this is working at all on second thought since Common
throws on using the wrong case. Probably some lucky coincidence on what values are read in this context. 😄
We should definitely improve here otherwise this is bound to go wrong at some PIT. Not sure how to tackle:
- Ignore case on the the common side respectively only compare lower case versions? Side effects?
- Use the upcoming release on Common and move everything to lowercase and enforce? Hmm.
- Other suggestions?
Not completely convinced myself on any of the solutions proposed yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a quick script to extract opcode fees from the opcodes object and then lower cased them since that seemed to be the standard in Common (had sload gasprice instead of sLoad or something different). But I agree we should standardize this or something, good point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing is, lower case is NOT standard in Common
but camelCase and camelCase names are all over the place - see e.g. the chainstart.json file. I would guess that this didn't trigger an exception here is out of pure randomness, maybe all the camelCase names are for non-base fee gas prices or precompiles (like ecAdd
e.g.), but that was likely pure luck here. 😄
Therefore the somewhat urgency of the comment. Or are we talking past each other somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand your concern. I think we can change it to camelCase just to be consistent, but to implement this in a clean way in opcodes.ts
we also need to change all uppercase opcodes there to the right camelCased opcodes.
Closes #803
This PR moves all gas base fees to Common. It also disables checks within the opcodes to see if the opcode is available. These opcodes are not available if VM has a Common defined before the hardfork which introduced this opcode. See
getOpcodesForHF
here.Also started adding the right fee values for
ChainStart
andTangerineWhistle
so this also introduces some work to support ChainStart/TangerineWhistle again! 😄 Related issue: #652This only makes
opcodes.ts
slightly less typesafe by callingcreateOpcodes
ingetOpcodesForHF
.