mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-28 23:56:43 +00:00
fix: add sload witness when calculating dynamic gas (#1157)
* add sload witness when calculating dynamic gas * change sstore * tweaks * fix * move get sload witness only when in cold sload * remove a fake comment * tweak logs * nit
This commit is contained in:
parent
048db62267
commit
c529171c9b
3 changed files with 30 additions and 12 deletions
|
|
@ -100,6 +100,10 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
|||
y, x = stack.Back(1), stack.Back(0)
|
||||
current = evm.StateDB.GetState(contract.Address(), x.Bytes32())
|
||||
)
|
||||
|
||||
// Try updating the witness of SSTORE at first to align with reth's witness implementation.
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
|
||||
// The legacy gas metering only takes into consideration the current state
|
||||
// Legacy rules should be applied if we are in Petersburg (removal of EIP-1283)
|
||||
// OR Constantinople is not active
|
||||
|
|
@ -137,7 +141,6 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
|||
if current == value { // noop (1)
|
||||
return params.NetSstoreNoopGas, nil
|
||||
}
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
if original == current {
|
||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||
return params.NetSstoreInitGas, nil
|
||||
|
|
@ -178,10 +181,6 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
|||
// 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter.
|
||||
// 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter.
|
||||
func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
// If we fail the minimum gas availability invariant, fail (0)
|
||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||
}
|
||||
// Gas sentry honoured, do the actual gas calculation based on the stored value
|
||||
var (
|
||||
y, x = stack.Back(1), stack.Back(0)
|
||||
|
|
@ -189,10 +188,17 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
|
|||
)
|
||||
value := common.Hash(y.Bytes32())
|
||||
|
||||
// Try updating the witness of SSTORE at first to align with reth's witness implementation.
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
|
||||
// If we fail the minimum gas availability invariant, fail (0)
|
||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||
}
|
||||
|
||||
if current == value { // noop (1)
|
||||
return params.SloadGasEIP2200, nil
|
||||
}
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
if original == current {
|
||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||
return params.SstoreSetGasEIP2200, nil
|
||||
|
|
|
|||
|
|
@ -27,10 +27,6 @@ import (
|
|||
|
||||
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||
// If we fail the minimum gas availability invariant, fail (0)
|
||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||
}
|
||||
// Gas sentry honoured, do the actual gas calculation based on the stored value
|
||||
var (
|
||||
y, x = stack.Back(1), stack.peek()
|
||||
|
|
@ -38,6 +34,15 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
|||
current = evm.StateDB.GetState(contract.Address(), slot)
|
||||
cost = uint64(0)
|
||||
)
|
||||
|
||||
// Try updating the witness of SSTORE at first to align with reth's witness implementation.
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
|
||||
// If we fail the minimum gas availability invariant, fail (0)
|
||||
if contract.Gas <= params.SstoreSentryGasEIP2200 {
|
||||
return 0, errors.New("not enough gas for reentrancy sentry")
|
||||
}
|
||||
|
||||
// Check slot presence in the access list
|
||||
if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent {
|
||||
cost = params.ColdSloadCostEIP2929
|
||||
|
|
@ -57,7 +62,6 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
|||
// return params.SloadGasEIP2200, nil
|
||||
return cost + params.WarmStorageReadCostEIP2929, nil // SLOAD_GAS
|
||||
}
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
||||
if original == current {
|
||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||
return cost + params.SstoreSetGasEIP2200, nil
|
||||
|
|
@ -109,6 +113,14 @@ func gasSLoadEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
|
|||
// If the caller cannot afford the cost, this change will be rolled back
|
||||
// If he does afford it, we can skip checking the same thing later on, during execution
|
||||
evm.StateDB.AddSlotToAccessList(contract.Address(), slot)
|
||||
|
||||
// Try updating the witness of SLOAD to align with reth's witness implementation.
|
||||
// Another place that needs to change is when calculating the gas cost after Frontier and before EIP-2929.
|
||||
// Frontier gas cost simply uses params.SloadGasFrontier (i.e., 50 gas), so changing the gas cost there
|
||||
// might affect code cleanliness. Usually, this won't be a problem because EIP-2929 is enabled by default.
|
||||
// Thus, adding the SLOAD witness before EIP-2929 is left as a TODO here.
|
||||
evm.StateDB.GetCommittedState(contract.Address(), loc.Bytes32())
|
||||
|
||||
return params.ColdSloadCostEIP2929, nil
|
||||
}
|
||||
return params.WarmStorageReadCostEIP2929, nil
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 5 // Major version component of the current release
|
||||
VersionMinor = 8 // Minor version component of the current release
|
||||
VersionPatch = 29 // Patch version component of the current release
|
||||
VersionPatch = 30 // Patch version component of the current release
|
||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue