2023-06-09 12:27:31 +02:00
|
|
|
package eip3529tests
|
2023-06-07 14:16:01 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
|
|
|
"github.com/ethereum/go-ethereum/core/vm"
|
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
|
)
|
|
|
|
|
2024-03-22 22:37:47 +08:00
|
|
|
func postHertzPreShanghaiConfig() *params.ChainConfig {
|
2023-06-07 14:16:01 +02:00
|
|
|
config := *params.ParliaTestChainConfig
|
2024-03-22 22:37:47 +08:00
|
|
|
config.ShanghaiTime = nil
|
|
|
|
config.KeplerTime = nil
|
|
|
|
config.FeynmanTime = nil
|
|
|
|
config.FeynmanFixTime = nil
|
|
|
|
config.CancunTime = nil
|
2023-06-07 14:16:01 +02:00
|
|
|
return &config
|
|
|
|
}
|
|
|
|
|
|
|
|
func preHertzConfig() *params.ChainConfig {
|
|
|
|
config := *params.ParliaTestChainConfig
|
|
|
|
config.LondonBlock = nil
|
|
|
|
config.BerlinBlock = nil
|
|
|
|
config.HertzBlock = nil
|
2023-12-04 13:56:14 +08:00
|
|
|
config.HertzfixBlock = nil
|
2024-03-22 22:37:47 +08:00
|
|
|
config.ShanghaiTime = nil
|
|
|
|
config.KeplerTime = nil
|
|
|
|
config.FeynmanTime = nil
|
|
|
|
config.FeynmanFixTime = nil
|
|
|
|
config.CancunTime = nil
|
2023-06-07 14:16:01 +02:00
|
|
|
return &config
|
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSelfDestructGasPreHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PC),
|
|
|
|
byte(vm.SELFDESTRUCT),
|
|
|
|
}
|
|
|
|
|
|
|
|
// Expected gas is (intrinsic + selfdestruct cost ) / 2
|
|
|
|
// The refund of 24000 gas (i.e. params.SelfdestructRefundGas) is not applied since refunds pre-EIP3529 are
|
|
|
|
// capped to half of the transaction's gas.
|
|
|
|
expectedGasUsed := (params.TxGas + vm.GasQuickStep + params.SelfdestructGasEIP150) / 2
|
2023-06-09 12:27:31 +02:00
|
|
|
TestGasUsage(t, preHertzConfig(), ethash.NewFaker(), bytecode, nil, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreClearGasPreHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x0, // value
|
|
|
|
byte(vm.PUSH1), 0x1, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[1] = 0
|
|
|
|
}
|
|
|
|
// initialize contract storage
|
|
|
|
initialStorage := make(map[common.Hash]common.Hash)
|
|
|
|
// Populate two slots
|
|
|
|
initialStorage[common.HexToHash("01")] = common.HexToHash("01")
|
|
|
|
initialStorage[common.HexToHash("02")] = common.HexToHash("02")
|
|
|
|
|
|
|
|
// Expected gas is (intrinsic + 2*pushGas + SstoreReset (a->b such that a!=0) ) / 2
|
|
|
|
// The refund of params.SstoreClearsScheduleRefundEIP2200 is not applied because of the refund cap to half the gas cost.
|
|
|
|
expectedGasUsage := (params.TxGas + 2*vm.GasFastestStep + params.SstoreResetGasEIP2200) / 2
|
2023-06-09 12:27:31 +02:00
|
|
|
TestGasUsage(t, preHertzConfig(), ethash.NewFaker(), bytecode, initialStorage, 60_000, expectedGasUsage)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreModifyGasPreHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x3, // value
|
|
|
|
byte(vm.PUSH1), 0x1, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[1] = 3
|
|
|
|
}
|
|
|
|
// initialize contract storage
|
|
|
|
initialStorage := make(map[common.Hash]common.Hash)
|
|
|
|
// Populate two slots
|
|
|
|
initialStorage[common.HexToHash("01")] = common.HexToHash("01")
|
|
|
|
initialStorage[common.HexToHash("02")] = common.HexToHash("02")
|
|
|
|
// Expected gas is intrinsic + 2*pushGas + SstoreReset (a->b such that a!=0)
|
|
|
|
// i.e. no refund
|
|
|
|
expectedGasUsed := params.TxGas + 2*vm.GasFastestStep + params.SstoreResetGasEIP2200
|
2023-06-09 12:27:31 +02:00
|
|
|
TestGasUsage(t, preHertzConfig(), ethash.NewFaker(), bytecode, initialStorage, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreGasPreHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x3, // value
|
|
|
|
byte(vm.PUSH1), 0x3, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[3] = 3
|
|
|
|
}
|
|
|
|
// Expected gas is intrinsic + 2*pushGas + SstoreGas
|
|
|
|
// i.e. No refund
|
|
|
|
expectedGasUsed := params.TxGas + 2*vm.GasFastestStep + params.SstoreSetGasEIP2200
|
2023-06-09 12:27:31 +02:00
|
|
|
TestGasUsage(t, preHertzConfig(), ethash.NewFaker(), bytecode, nil, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSelfDestructGasPostHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PC),
|
|
|
|
byte(vm.SELFDESTRUCT),
|
|
|
|
}
|
|
|
|
// Expected gas is intrinsic + pc + cold load (due to legacy tx) + SelfDestructGas
|
|
|
|
// i.e. No refund
|
|
|
|
expectedGasUsed := params.TxGas + vm.GasQuickStep + params.ColdAccountAccessCostEIP2929 + params.SelfdestructGasEIP150
|
2024-03-22 22:37:47 +08:00
|
|
|
TestGasUsage(t, postHertzPreShanghaiConfig(), ethash.NewFaker(), bytecode, nil, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreGasPostHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x3, // value
|
|
|
|
byte(vm.PUSH1), 0x3, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[3] = 3
|
|
|
|
}
|
|
|
|
// Expected gas is intrinsic + 2*pushGas + cold load (due to legacy tx) + SstoreGas
|
|
|
|
// i.e. No refund
|
|
|
|
expectedGasUsed := params.TxGas + 2*vm.GasFastestStep + params.ColdSloadCostEIP2929 + params.SstoreSetGasEIP2200
|
2024-03-22 22:37:47 +08:00
|
|
|
TestGasUsage(t, postHertzPreShanghaiConfig(), ethash.NewFaker(), bytecode, nil, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreModifyGasPostHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x3, // value
|
|
|
|
byte(vm.PUSH1), 0x1, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[1] = 3
|
|
|
|
}
|
|
|
|
// initialize contract storage
|
|
|
|
initialStorage := make(map[common.Hash]common.Hash)
|
|
|
|
// Populate two slots
|
|
|
|
initialStorage[common.HexToHash("01")] = common.HexToHash("01")
|
|
|
|
initialStorage[common.HexToHash("02")] = common.HexToHash("02")
|
|
|
|
// Expected gas is intrinsic + 2*pushGas + cold load (due to legacy tx) + SstoreReset (a->b such that a!=0)
|
|
|
|
// i.e. No refund
|
|
|
|
expectedGasUsed := params.TxGas + 2*vm.GasFastestStep + params.SstoreResetGasEIP2200
|
2024-03-22 22:37:47 +08:00
|
|
|
TestGasUsage(t, postHertzPreShanghaiConfig(), ethash.NewFaker(), bytecode, initialStorage, 60_000, expectedGasUsed)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 12:27:31 +02:00
|
|
|
func TestSstoreClearGasPostHertz(t *testing.T) {
|
2023-06-07 14:16:01 +02:00
|
|
|
bytecode := []byte{
|
|
|
|
byte(vm.PUSH1), 0x0, // value
|
|
|
|
byte(vm.PUSH1), 0x1, // location
|
|
|
|
byte(vm.SSTORE), // Set slot[1] = 0
|
|
|
|
}
|
|
|
|
// initialize contract storage
|
|
|
|
initialStorage := make(map[common.Hash]common.Hash)
|
|
|
|
// Populate two slots
|
|
|
|
initialStorage[common.HexToHash("01")] = common.HexToHash("01")
|
|
|
|
initialStorage[common.HexToHash("02")] = common.HexToHash("02")
|
|
|
|
|
2023-06-07 16:11:30 +02:00
|
|
|
// Expected gas is intrinsic + 2*pushGas + SstoreReset (a->b such that a!=0) - sstoreClearGasRefund
|
2023-06-07 14:16:01 +02:00
|
|
|
expectedGasUsage := params.TxGas + 2*vm.GasFastestStep + params.SstoreResetGasEIP2200 - params.SstoreClearsScheduleRefundEIP3529
|
2024-03-22 22:37:47 +08:00
|
|
|
TestGasUsage(t, postHertzPreShanghaiConfig(), ethash.NewFaker(), bytecode, initialStorage, 60_000, expectedGasUsage)
|
2023-06-07 14:16:01 +02:00
|
|
|
}
|