Skip to content

Commit

Permalink
simplify warm costs
Browse files Browse the repository at this point in the history
Signed-off-by: Ignacio Hagopian <[email protected]>
  • Loading branch information
jsign committed Sep 23, 2024
1 parent fdb9c50 commit 9ea37be
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 28 deletions.
20 changes: 12 additions & 8 deletions core/state/access_witness.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@ func (aw *AccessWitness) TouchFullAccount(addr []byte, isWrite bool, useGasFn Us
return true
}

func (aw *AccessWitness) TouchAndChargeMessageCall(addr []byte, useGasFn UseGasFn) (uint64, bool) {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, false, useGasFn)
func (aw *AccessWitness) TouchAndChargeMessageCall(addr []byte, useGasFn UseGasFn) bool {
chargedGas, ok := aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, false, useGasFn)
return ok && (chargedGas > 0 || useGasFn(params.WarmStorageReadCostEIP2929))
}

func (aw *AccessWitness) TouchAndChargeValueTransfer(callerAddr, targetAddr []byte, useGasFn UseGasFn) bool {
Expand Down Expand Up @@ -146,9 +147,10 @@ func (aw *AccessWitness) TouchTxExistingAndComputeGas(targetAddr []byte, sendsVa
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.CodeHashLeafKey, false, nil)
}

func (aw *AccessWitness) TouchSlotAndChargeGas(addr []byte, slot common.Hash, isWrite bool, useGasFn UseGasFn) (uint64, bool) {
func (aw *AccessWitness) TouchSlotAndChargeGas(addr []byte, slot common.Hash, isWrite bool, useGasFn UseGasFn, warmCostCharging bool) bool {
treeIndex, subIndex := utils.GetTreeKeyStorageSlotTreeIndexes(slot.Bytes())
return aw.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite, useGasFn)
chargedGas, ok := aw.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite, useGasFn)
return ok && (!warmCostCharging || chargedGas > 0 || useGasFn(params.WarmStorageReadCostEIP2929))
}

func (aw *AccessWitness) touchAddressAndChargeGas(addr []byte, treeIndex uint256.Int, subIndex byte, isWrite bool, useGasFn UseGasFn) (uint64, bool) {
Expand Down Expand Up @@ -272,10 +274,12 @@ func (aw *AccessWitness) TouchCodeChunksRangeAndChargeGas(contractAddr []byte, s
return true
}

func (aw *AccessWitness) TouchBasicData(addr []byte, isWrite bool, useGasFn UseGasFn) (uint64, bool) {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, useGasFn)
func (aw *AccessWitness) TouchBasicData(addr []byte, isWrite bool, useGasFn UseGasFn, warmCostCharging bool) bool {
chargedGas, ok := aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, useGasFn)
return ok && (!warmCostCharging || chargedGas > 0 || useGasFn(params.WarmStorageReadCostEIP2929))
}

func (aw *AccessWitness) TouchCodeHash(addr []byte, isWrite bool, useGasFn UseGasFn) (uint64, bool) {
return aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, useGasFn)
func (aw *AccessWitness) TouchCodeHash(addr []byte, isWrite bool, useGasFn UseGasFn) bool {
chargedGas, ok := aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, useGasFn)
return ok && (chargedGas > 0 || useGasFn(params.WarmStorageReadCostEIP2929))
}
2 changes: 1 addition & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,5 @@ func ProcessParentBlockHash(statedb *state.StateDB, prevNumber uint64, prevHash
var key common.Hash
binary.BigEndian.PutUint64(key[24:], ringIndex)
statedb.SetState(params.HistoryStorageAddress, key, prevHash)
statedb.Witness().TouchSlotAndChargeGas(params.HistoryStorageAddress[:], key, true, nil)
statedb.Witness().TouchSlotAndChargeGas(params.HistoryStorageAddress[:], key, true, nil, false)
}
31 changes: 12 additions & 19 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,7 @@ func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
slot := scope.Stack.peek()
address := common.Address(slot.Bytes20())
if interpreter.evm.chainRules.IsVerkle {
chargedGas, ok := interpreter.evm.Accesses.TouchBasicData(address[:], false, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchBasicData(address[:], false, scope.Contract.UseGas, true) {
return nil, ErrExecutionReverted
}
}
Expand Down Expand Up @@ -357,8 +356,7 @@ func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
return nil, ErrExecutionReverted
}
} else {
chargedGas, ok := interpreter.evm.Accesses.TouchBasicData(address[:], false, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchBasicData(address[:], false, scope.Contract.UseGas, true) {
return nil, ErrExecutionReverted
}
}
Expand Down Expand Up @@ -413,8 +411,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
return nil, ErrExecutionReverted
}
} else {
chargedGas, ok := interpreter.evm.Accesses.TouchBasicData(addr[:], false, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchBasicData(addr[:], false, scope.Contract.UseGas, true) {
return nil, ErrExecutionReverted
}
}
Expand Down Expand Up @@ -480,8 +477,7 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
return nil, ErrExecutionReverted
}
} else {
chargedGas, ok := interpreter.evm.Accesses.TouchCodeHash(address[:], false, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchCodeHash(address[:], false, scope.Contract.UseGas) {
return nil, ErrExecutionReverted
}
}
Expand Down Expand Up @@ -523,7 +519,7 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) (
ringIndex := num64 % params.Eip2935BlockHashHistorySize
var pnum common.Hash
binary.BigEndian.PutUint64(pnum[24:], ringIndex)
if _, ok := evm.Accesses.TouchSlotAndChargeGas(params.HistoryStorageAddress[:], pnum, false, scope.Contract.UseGas); !ok {
if !evm.Accesses.TouchSlotAndChargeGas(params.HistoryStorageAddress[:], pnum, false, scope.Contract.UseGas, false) {
return nil, ErrExecutionReverted
}
blockHash := evm.StateDB.GetState(params.HistoryStorageAddress, pnum)
Expand Down Expand Up @@ -599,8 +595,7 @@ func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
loc := scope.Stack.peek()
hash := common.Hash(loc.Bytes32())
if interpreter.evm.chainRules.IsVerkle {
chargedGas, ok := interpreter.evm.Accesses.TouchSlotAndChargeGas(scope.Contract.Address().Bytes(), loc.Bytes32(), false, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchSlotAndChargeGas(scope.Contract.Address().Bytes(), loc.Bytes32(), false, scope.Contract.UseGas, true) {
return nil, ErrExecutionReverted
}
}
Expand All @@ -616,8 +611,7 @@ func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
loc := scope.Stack.pop()
val := scope.Stack.pop()
if interpreter.evm.chainRules.IsVerkle {
chargedGas, ok := interpreter.evm.Accesses.TouchSlotAndChargeGas(scope.Contract.Address().Bytes(), loc.Bytes32(), true, scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !interpreter.evm.Accesses.TouchSlotAndChargeGas(scope.Contract.Address().Bytes(), loc.Bytes32(), true, scope.Contract.UseGas, true) {
return nil, ErrExecutionReverted
}
}
Expand Down Expand Up @@ -777,8 +771,7 @@ func chargeCallVariantEIP4762(evm *EVM, scope *ScopeContext) bool {
// (so before we get to this point)
// But the message call is part of the subcall, for which only 63/64th
// of the gas should be available.
chargedGas, ok := evm.Accesses.TouchAndChargeMessageCall(target.Bytes(), scope.Contract.UseGas)
if !ok || (chargedGas == 0 && !scope.Contract.UseGas(params.WarmStorageReadCostEIP2929)) {
if !evm.Accesses.TouchAndChargeMessageCall(target.Bytes(), scope.Contract.UseGas) {
return false
}
return true
Expand Down Expand Up @@ -994,25 +987,25 @@ func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeCon
beneficiaryAddr := common.Address(scope.Stack.peek().Bytes20())
contractAddr := scope.Contract.Address()

if _, ok := interpreter.evm.Accesses.TouchBasicData(contractAddr[:], false, scope.Contract.UseGas); !ok {
if !interpreter.evm.Accesses.TouchBasicData(contractAddr[:], false, scope.Contract.UseGas, false) {
return nil, ErrExecutionReverted
}
balanceIsZero := interpreter.evm.StateDB.GetBalance(contractAddr).Sign() == 0

if _, isPrecompile := interpreter.evm.precompile(beneficiaryAddr); !(isPrecompile && balanceIsZero) {
if contractAddr != beneficiaryAddr {
if _, ok := interpreter.evm.Accesses.TouchBasicData(beneficiaryAddr[:], false, scope.Contract.UseGas); !ok {
if !interpreter.evm.Accesses.TouchBasicData(beneficiaryAddr[:], false, scope.Contract.UseGas, false) {
return nil, ErrExecutionReverted
}
}
// Charge write costs if it transfers value
if !balanceIsZero {
if _, ok := interpreter.evm.Accesses.TouchBasicData(contractAddr[:], true, scope.Contract.UseGas); !ok {
if !interpreter.evm.Accesses.TouchBasicData(contractAddr[:], true, scope.Contract.UseGas, false) {
return nil, ErrExecutionReverted
}
if contractAddr != beneficiaryAddr {
if interpreter.evm.StateDB.Exist(beneficiaryAddr) {
if _, ok := interpreter.evm.Accesses.TouchBasicData(beneficiaryAddr[:], true, scope.Contract.UseGas); !ok {
if !interpreter.evm.Accesses.TouchBasicData(beneficiaryAddr[:], true, scope.Contract.UseGas, false) {
return nil, ErrExecutionReverted
}
} else {
Expand Down

0 comments on commit 9ea37be

Please sign in to comment.