mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 22:43:47 +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)
|
y, x = stack.Back(1), stack.Back(0)
|
||||||
current = evm.StateDB.GetState(contract.Address(), x.Bytes32())
|
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
|
// 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)
|
// Legacy rules should be applied if we are in Petersburg (removal of EIP-1283)
|
||||||
// OR Constantinople is not active
|
// 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)
|
if current == value { // noop (1)
|
||||||
return params.NetSstoreNoopGas, nil
|
return params.NetSstoreNoopGas, nil
|
||||||
}
|
}
|
||||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
|
||||||
if original == current {
|
if original == current {
|
||||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||||
return params.NetSstoreInitGas, nil
|
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.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.
|
// 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) {
|
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
|
// Gas sentry honoured, do the actual gas calculation based on the stored value
|
||||||
var (
|
var (
|
||||||
y, x = stack.Back(1), stack.Back(0)
|
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())
|
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)
|
if current == value { // noop (1)
|
||||||
return params.SloadGasEIP2200, nil
|
return params.SloadGasEIP2200, nil
|
||||||
}
|
}
|
||||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
|
||||||
if original == current {
|
if original == current {
|
||||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||||
return params.SstoreSetGasEIP2200, nil
|
return params.SstoreSetGasEIP2200, nil
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@ import (
|
||||||
|
|
||||||
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||||
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
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
|
// Gas sentry honoured, do the actual gas calculation based on the stored value
|
||||||
var (
|
var (
|
||||||
y, x = stack.Back(1), stack.peek()
|
y, x = stack.Back(1), stack.peek()
|
||||||
|
|
@ -38,6 +34,15 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||||
current = evm.StateDB.GetState(contract.Address(), slot)
|
current = evm.StateDB.GetState(contract.Address(), slot)
|
||||||
cost = uint64(0)
|
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
|
// Check slot presence in the access list
|
||||||
if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent {
|
if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent {
|
||||||
cost = params.ColdSloadCostEIP2929
|
cost = params.ColdSloadCostEIP2929
|
||||||
|
|
@ -57,7 +62,6 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc {
|
||||||
// return params.SloadGasEIP2200, nil
|
// return params.SloadGasEIP2200, nil
|
||||||
return cost + params.WarmStorageReadCostEIP2929, nil // SLOAD_GAS
|
return cost + params.WarmStorageReadCostEIP2929, nil // SLOAD_GAS
|
||||||
}
|
}
|
||||||
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
|
|
||||||
if original == current {
|
if original == current {
|
||||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||||
return cost + params.SstoreSetGasEIP2200, nil
|
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 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
|
// If he does afford it, we can skip checking the same thing later on, during execution
|
||||||
evm.StateDB.AddSlotToAccessList(contract.Address(), slot)
|
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.ColdSloadCostEIP2929, nil
|
||||||
}
|
}
|
||||||
return params.WarmStorageReadCostEIP2929, nil
|
return params.WarmStorageReadCostEIP2929, nil
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 8 // Minor 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
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue