core/vm: remove eip 1283 sstore gas change

This commit is contained in:
Martin Holst Swende 2019-01-16 10:57:30 +01:00
parent f50d66f2d8
commit ac18679d55
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0

View file

@ -120,66 +120,20 @@ func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m
y, x = stack.Back(1), stack.Back(0) y, x = stack.Back(1), stack.Back(0)
current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x)) current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
) )
// The legacy gas metering only takes into consideration the current state // This checks for 3 scenario's and calculates gas accordingly:
if !evm.chainRules.IsConstantinople {
// This checks for 3 scenario's and calculates gas accordingly:
//
// 1. From a zero-value address to a non-zero value (NEW VALUE)
// 2. From a non-zero value address to a zero-value address (DELETE)
// 3. From a non-zero to a non-zero (CHANGE)
switch {
case current == (common.Hash{}) && y.Sign() != 0: // 0 => non 0
return params.SstoreSetGas, nil
case current != (common.Hash{}) && y.Sign() == 0: // non 0 => 0
evm.StateDB.AddRefund(params.SstoreRefundGas)
return params.SstoreClearGas, nil
default: // non 0 => non 0 (or 0 => 0)
return params.SstoreResetGas, nil
}
}
// The new gas metering is based on net gas costs (EIP-1283):
// //
// 1. If current value equals new value (this is a no-op), 200 gas is deducted. // 1. From a zero-value address to a non-zero value (NEW VALUE)
// 2. If current value does not equal new value // 2. From a non-zero value address to a zero-value address (DELETE)
// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context) // 3. From a non-zero to a non-zero (CHANGE)
// 2.1.1. If original value is 0, 20000 gas is deducted. switch {
// 2.1.2. Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter. case current == (common.Hash{}) && y.Sign() != 0: // 0 => non 0
// 2.2. If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. return params.SstoreSetGas, nil
// 2.2.1. If original value is not 0 case current != (common.Hash{}) && y.Sign() == 0: // non 0 => 0
// 2.2.1.1. If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. evm.StateDB.AddRefund(params.SstoreRefundGas)
// 2.2.1.2. If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. return params.SstoreClearGas, nil
// 2.2.2. If original value equals new value (this storage slot is reset) default: // non 0 => non 0 (or 0 => 0)
// 2.2.2.1. If original value is 0, add 19800 gas to refund counter. return params.SstoreResetGas, nil
// 2.2.2.2. Otherwise, add 4800 gas to refund counter.
value := common.BigToHash(y)
if current == value { // noop (1)
return params.NetSstoreNoopGas, nil
} }
original := evm.StateDB.GetCommittedState(contract.Address(), common.BigToHash(x))
if original == current {
if original == (common.Hash{}) { // create slot (2.1.1)
return params.NetSstoreInitGas, nil
}
if value == (common.Hash{}) { // delete slot (2.1.2b)
evm.StateDB.AddRefund(params.NetSstoreClearRefund)
}
return params.NetSstoreCleanGas, 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.NetSstoreClearRefund)
} else if value == (common.Hash{}) { // delete slot (2.2.1.2)
evm.StateDB.AddRefund(params.NetSstoreClearRefund)
}
}
if original == value {
if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1)
evm.StateDB.AddRefund(params.NetSstoreResetClearRefund)
} else { // reset to original existing slot (2.2.2.2)
evm.StateDB.AddRefund(params.NetSstoreResetRefund)
}
}
return params.NetSstoreDirtyGas, nil
} }
func makeGasLog(n uint64) gasFunc { func makeGasLog(n uint64) gasFunc {