-
Notifications
You must be signed in to change notification settings - Fork 777
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
evm: verkle updates #3832
evm: verkle updates #3832
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
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 you be more explicit about what these changes are targeting? If I understand it correctly, you're dealing with the following items:
- Checking to see if an accessed address is a system contract/precompile so we don't charge AccessWitness read for the account header fields
- Verifying that we only add the miner to the write portion of the System Verkle Witness if the miner actually get a reward for the transaction
Is that correct or is there more being covered here?
Just clarified the description to be more explicit about the changes |
@@ -166,7 +166,8 @@ export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynami | |||
let charge2929Gas = true | |||
if ( | |||
common.isActivatedEIP(6800) && | |||
runState.interpreter._evm.getPrecompile(address) === undefined | |||
runState.interpreter._evm.getPrecompile(address) === undefined && | |||
!address.equals(createAddressFromStackBigInt(common.param('systemAddress'))) |
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.
My only concern with this is that should consider the larger picture, mentioned by @g11tech, that it makes sense to store system contract address, codehash, and code, in memory the way we do for precompiles. I think we should go ahead and merge this as is but then do some work to make the system contract (plus any future ones) available in memory so we don't need to read code from storage for them.
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.
yea we need to address this both for system calls which will have address equal to system address as well as normal contract calls into system contracts
(same comment for similar handling in below changes)
if (common.isActivatedEIP(6800) === true && reward !== BIGINT_0) { | ||
if (evm.systemVerkleAccessWitness === undefined) { | ||
throw Error(`verkleAccessWitness required if verkle (EIP-6800) is activated`) | ||
} | ||
evm.verkleAccessWitness.readAccountHeader(address) | ||
evm.systemVerkleAccessWitness.writeAccountHeader(address) | ||
} | ||
account = new Account() | ||
} | ||
account.balance += reward | ||
await evm.journal.putAccount(address, account) | ||
|
||
if (common.isActivatedEIP(6800) === true) { | ||
if (evm.verkleAccessWitness === undefined) { | ||
if (common.isActivatedEIP(6800) === true && reward !== BIGINT_0) { | ||
if (evm.systemVerkleAccessWitness === undefined) { | ||
throw Error(`verkleAccessWitness required if verkle (EIP-6800) is activated`) | ||
} | ||
// use vm utility to build access but the computed gas is not charged and hence free | ||
evm.verkleAccessWitness.writeAccountBasicData(address) | ||
evm.verkleAccessWitness.readAccountCodeHash(address) | ||
evm.systemVerkleAccessWitness.writeAccountBasicData(address) | ||
evm.systemVerkleAccessWitness.readAccountCodeHash(address) |
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 we consolidate all this down? Instead of having a whole code block to check to write the account header when we have account non-existence and then a second check, can we just do (this is pseudo code but you get the idea)
let accountExists = true
if (account === undefined) {
accountExists = false
account = new Account()
}
if (6800 is active and reward > 0)
accountExists ? writeAccountData/readCodHash : writeAccountHeader
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.
Yeah thanks, this makes total sense and is simpler + more efficient
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 looks good. I'm going to test out my proposed simplification of the miner address AW in runTx
logic locally and it the tests are still passing the same way, will add a commit so we can merge.
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.
LGTM. Please review my last commit before merging
} else if (chargeGas && common.isActivatedEIP(6800)) { | ||
// If Verkle is active, then the warmstoragereadGas should still be charged | ||
// This is because otherwise opcodes will have cost 0 (this is thus the base fee) | ||
return common.param('warmstoragereadGas') |
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.
we have a check for warm in L26, so this should just be cold gas segment no?
@@ -318,7 +318,7 @@ export class StatefulVerkleStateManager implements StateManagerInterface { | |||
chunkStems[0], | |||
chunkSuffixes.slice( | |||
0, | |||
codeChunks.length <= VERKLE_CODE_OFFSET ? codeChunks.length : VERKLE_CODE_OFFSET, | |||
chunkSuffixes.length <= VERKLE_CODE_OFFSET ? chunkSuffixes.length : VERKLE_CODE_OFFSET, |
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.
is there a difference in code chunks and suffixes length?
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.
No, but it seemed more correct to actually use chunkSuffixes for this slice rather than implicitly relying that codeChunks.length === codeSuffixes.length
This PR extracts some Verkle-related updates and fixes from #3716: