core/vm, params: make 2200 in line with spec (#21605)
This commit is contained in:
parent
a90e645ccd
commit
0ddd4612b7
@ -163,18 +163,18 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
||||
}
|
||||
|
||||
// 0. If *gasleft* is less than or equal to 2300, fail the current call.
|
||||
// 1. If current value equals new value (this is a no-op), SSTORE_NOOP_GAS gas is deducted.
|
||||
// 1. If current value equals new value (this is a no-op), SLOAD_GAS is deducted.
|
||||
// 2. If current value does not equal new value:
|
||||
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context):
|
||||
// 2.1.1. If original value is 0, SSTORE_INIT_GAS gas is deducted.
|
||||
// 2.1.2. Otherwise, SSTORE_CLEAN_GAS gas is deducted. If new value is 0, add SSTORE_CLEAR_REFUND to refund counter.
|
||||
// 2.2. If original value does not equal current value (this storage slot is dirty), SSTORE_DIRTY_GAS gas is deducted. Apply both of the following clauses:
|
||||
// 2.1.1. If original value is 0, SSTORE_SET_GAS (20K) gas is deducted.
|
||||
// 2.1.2. Otherwise, SSTORE_RESET_GAS gas is deducted. If new value is 0, add SSTORE_CLEARS_SCHEDULE to refund counter.
|
||||
// 2.2. If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses:
|
||||
// 2.2.1. If original value is not 0:
|
||||
// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEAR_REFUND gas from refund counter. We can prove that refund counter will never go below 0.
|
||||
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEAR_REFUND gas to refund counter.
|
||||
// 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEARS_SCHEDULE gas from refund counter.
|
||||
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEARS_SCHEDULE gas to refund counter.
|
||||
// 2.2.2. If original value equals new value (this storage slot is reset):
|
||||
// 2.2.2.1. If original value is 0, add SSTORE_INIT_REFUND to refund counter.
|
||||
// 2.2.2.2. Otherwise, add SSTORE_CLEAN_REFUND 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.
|
||||
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 {
|
||||
@ -188,33 +188,33 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
|
||||
value := common.Hash(y.Bytes32())
|
||||
|
||||
if current == value { // noop (1)
|
||||
return params.SstoreNoopGasEIP2200, nil
|
||||
return params.SloadGasEIP2200, nil
|
||||
}
|
||||
original := evm.StateDB.GetCommittedState(contract.Address(), common.Hash(x.Bytes32()))
|
||||
if original == current {
|
||||
if original == (common.Hash{}) { // create slot (2.1.1)
|
||||
return params.SstoreInitGasEIP2200, nil
|
||||
return params.SstoreSetGasEIP2200, nil
|
||||
}
|
||||
if value == (common.Hash{}) { // delete slot (2.1.2b)
|
||||
evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200)
|
||||
evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200)
|
||||
}
|
||||
return params.SstoreCleanGasEIP2200, nil // write existing slot (2.1.2)
|
||||
return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2)
|
||||
}
|
||||
if original != (common.Hash{}) {
|
||||
if current == (common.Hash{}) { // recreate slot (2.2.1.1)
|
||||
evm.StateDB.SubRefund(params.SstoreClearRefundEIP2200)
|
||||
evm.StateDB.SubRefund(params.SstoreClearsScheduleRefundEIP2200)
|
||||
} else if value == (common.Hash{}) { // delete slot (2.2.1.2)
|
||||
evm.StateDB.AddRefund(params.SstoreClearRefundEIP2200)
|
||||
evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200)
|
||||
}
|
||||
}
|
||||
if original == value {
|
||||
if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
|
||||
evm.StateDB.AddRefund(params.SstoreInitRefundEIP2200)
|
||||
evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200)
|
||||
} else { // reset to original existing slot (2.2.2.2)
|
||||
evm.StateDB.AddRefund(params.SstoreCleanRefundEIP2200)
|
||||
evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200)
|
||||
}
|
||||
}
|
||||
return params.SstoreDirtyGasEIP2200, nil // dirty update (2.2)
|
||||
return params.SloadGasEIP2200, nil // dirty update (2.2)
|
||||
}
|
||||
|
||||
func makeGasLog(n uint64) gasFunc {
|
||||
|
@ -53,13 +53,9 @@ const (
|
||||
NetSstoreResetClearRefund uint64 = 19800 // Once per SSTORE operation for resetting to the original zero value
|
||||
|
||||
SstoreSentryGasEIP2200 uint64 = 2300 // Minimum gas required to be present for an SSTORE call, not consumed
|
||||
SstoreNoopGasEIP2200 uint64 = 800 // Once per SSTORE operation if the value doesn't change.
|
||||
SstoreDirtyGasEIP2200 uint64 = 800 // Once per SSTORE operation if a dirty value is changed.
|
||||
SstoreInitGasEIP2200 uint64 = 20000 // Once per SSTORE operation from clean zero to non-zero
|
||||
SstoreInitRefundEIP2200 uint64 = 19200 // Once per SSTORE operation for resetting to the original zero value
|
||||
SstoreCleanGasEIP2200 uint64 = 5000 // Once per SSTORE operation from clean non-zero to something else
|
||||
SstoreCleanRefundEIP2200 uint64 = 4200 // Once per SSTORE operation for resetting to the original non-zero value
|
||||
SstoreClearRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
|
||||
SstoreSetGasEIP2200 uint64 = 20000 // Once per SSTORE operation from clean zero to non-zero
|
||||
SstoreResetGasEIP2200 uint64 = 5000 // Once per SSTORE operation from clean non-zero to something else
|
||||
SstoreClearsScheduleRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
|
||||
|
||||
JumpdestGas uint64 = 1 // Once per JUMPDEST operation.
|
||||
EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
|
||||
|
Loading…
Reference in New Issue
Block a user