Skip to content

Commit

Permalink
W3IP-4: add NoQuadMemoryGas (ethereum#71)
Browse files Browse the repository at this point in the history
Co-authored-by: Qi Zhou <[email protected]>
  • Loading branch information
qizhou and Qi Zhou authored Apr 14, 2022
1 parent 76e8432 commit f8e1fc6
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
23 changes: 13 additions & 10 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (

// memoryGasCost calculates the quadratic gas for memory expansion. It does so
// only for the memory region that is expanded, not the total memory.
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
func memoryGasCost(evm *EVM, mem *Memory, newMemSize uint64) (uint64, error) {
if newMemSize == 0 {
return 0, nil
}
Expand All @@ -45,6 +45,9 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
square := newMemSizeWords * newMemSizeWords
linCoef := newMemSizeWords * params.MemoryGas
quadCoef := square / params.QuadCoeffDiv
if evm != nil && evm.chainRules.IsPisa {
quadCoef = 0
}
newTotalFee := linCoef + quadCoef

fee := newTotalFee - mem.lastGasCost
Expand All @@ -65,7 +68,7 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
func memoryCopierGas(stackpos int) gasFunc {
return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
// Gas for expanding the memory
gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -224,7 +227,7 @@ func makeGasLog(n uint64) gasFunc {
return 0, ErrGasUintOverflow
}

gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand All @@ -248,7 +251,7 @@ func makeGasLog(n uint64) gasFunc {
}

func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand All @@ -269,7 +272,7 @@ func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor
// static cost have a dynamic cost which is solely based on the memory
// expansion
func pureMemoryGascost(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return memoryGasCost(mem, memorySize)
return memoryGasCost(evm, mem, memorySize)
}

var (
Expand All @@ -282,7 +285,7 @@ var (
)

func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -351,7 +354,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
if transfersValue {
gas += params.CallValueTransferGas
}
memoryGas, err := memoryGasCost(mem, memorySize)
memoryGas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand All @@ -375,7 +378,7 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize
}

func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
memoryGas, err := memoryGasCost(mem, memorySize)
memoryGas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -405,7 +408,7 @@ func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memory

func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
address := common.Address(stack.Back(1).Bytes20())
gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand All @@ -425,7 +428,7 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me

func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
address := common.Address(stack.Back(1).Bytes20())
gas, err := memoryGasCost(mem, memorySize)
gas, err := memoryGasCost(evm, mem, memorySize)
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion core/vm/gas_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestMemoryGasCost(t *testing.T) {
{0x1fffffffe1, 0, true},
}
for i, tt := range tests {
v, err := memoryGasCost(&Memory{}, tt.size)
v, err := memoryGasCost(nil, &Memory{}, tt.size)
if (err == ErrGasUintOverflow) != tt.overflow {
t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == ErrGasUintOverflow, tt.overflow)
}
Expand Down
41 changes: 36 additions & 5 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,39 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}

// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}

TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil}
AllCliqueProtocolChanges = &ChainConfig{
ChainID: big.NewInt(1337),
HomesteadBlock: big.NewInt(0),
DAOForkBlock: nil,
DAOForkSupport: false,
EIP150Block: big.NewInt(0),
EIP150Hash: common.Hash{},
EIP155Block: big.NewInt(0),
EIP158Block: big.NewInt(0),
ByzantiumBlock: big.NewInt(0),
ConstantinopleBlock: big.NewInt(0),
PetersburgBlock: big.NewInt(0),
IstanbulBlock: big.NewInt(0),
MuirGlacierBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ArrowGlacierBlock: nil,
MergeForkBlock: nil,
PisaBlock: big.NewInt(0),
TerminalTotalDifficulty: nil,
Ethash: nil,
Clique: &CliqueConfig{Period: 0, Epoch: 30000},
Tendermint: nil,
}

TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int), false)
)

Expand Down Expand Up @@ -446,6 +469,8 @@ type ChainConfig struct {
ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
MergeForkBlock *big.Int `json:"mergeForkBlock,omitempty"` // EIP-3675 (TheMerge) switch block (nil = no fork, 0 = already in merge proceedings)

PisaBlock *big.Int `json:"pisaBlock,omitempty"` // W3IP-4, EIP-4488 fork

// TerminalTotalDifficulty is the amount of total difficulty reached by
// the network that triggers the consensus upgrade.
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
Expand Down Expand Up @@ -580,6 +605,11 @@ func (c *ChainConfig) IsLondon(num *big.Int) bool {
return isForked(c.LondonBlock, num)
}

// IsPisa returns whether num is either equal to the Pisa fork block or greater.
func (c *ChainConfig) IsPisa(num *big.Int) bool {
return isForked(c.PisaBlock, num)
}

// IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater.
func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool {
return isForked(c.ArrowGlacierBlock, num)
Expand Down Expand Up @@ -777,7 +807,7 @@ type Rules struct {
ChainID *big.Int
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
IsBerlin, IsLondon bool
IsBerlin, IsLondon, IsPisa bool
IsMerge bool
}

Expand All @@ -799,6 +829,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules {
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
IsPisa: c.IsPisa(num),
IsMerge: isMerge,
}
}

0 comments on commit f8e1fc6

Please sign in to comment.