Skip to content

Commit f534a4d

Browse files
committed
partial review feedback
1 parent 54bdfb4 commit f534a4d

File tree

9 files changed

+59
-48
lines changed

9 files changed

+59
-48
lines changed

cmd/evm/internal/t8ntool/execution.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
194194
}
195195
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
196196
evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig)
197-
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
197+
core.ProcessBeaconBlockRoot(*beaconRoot, evm, statedb, big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp)
198198
}
199199

200200
for i := 0; txIt.Next(); i++ {

consensus/beacon/consensus.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,10 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
361361
amount = amount.Mul(amount, uint256.NewInt(params.GWei))
362362
state.AddBalance(w.Address, amount, tracing.BalanceIncreaseWithdrawal)
363363

364+
// Add the balance of each withdrawal to the witness, no gas will
365+
// be charged.
364366
if chain.Config().IsEIP4762(header.Number, header.Time) {
365-
state.Witness().TouchFullAccount(w.Address[:], true)
367+
state.Witness().TouchBalance(w.Address[:], true)
366368
}
367369
}
368370
// No block reward which is issued by consensus layer instead.

core/state/access_witness.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ func (aw *AccessWitness) Copy() *AccessWitness {
8989
return naw
9090
}
9191

92+
// TouchFullAccount returns the gas to be charged for each of the currently cold
93+
// member fields of an account.
9294
func (aw *AccessWitness) TouchFullAccount(addr []byte, isWrite bool) uint64 {
9395
var gas uint64
9496
for i := utils.VersionLeafKey; i <= utils.CodeSizeLeafKey; i++ {
@@ -97,22 +99,27 @@ func (aw *AccessWitness) TouchFullAccount(addr []byte, isWrite bool) uint64 {
9799
return gas
98100
}
99101

102+
// TouchAndChargeMessageCall returns the gas to be charged for each of the currently
103+
// cold member fields of an account, that need to be touched when making a message
104+
// call to that account.
100105
func (aw *AccessWitness) TouchAndChargeMessageCall(destination []byte) uint64 {
101106
var gas uint64
102107
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.VersionLeafKey, false)
103108
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeSizeLeafKey, false)
104109
return gas
105110
}
106111

112+
// TouchAndChargeValueTransfer returns the gas to be charged for each of the currently
113+
// cold balance member fields of the caller and the callee accounts.
107114
func (aw *AccessWitness) TouchAndChargeValueTransfer(callerAddr, targetAddr []byte) uint64 {
108115
var gas uint64
109116
gas += aw.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
110117
gas += aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
111118
return gas
112119
}
113120

114-
// TouchAndChargeContractCreateInit charges access costs to initiate
115-
// a contract creation
121+
// TouchAndChargeContractCreateInit returns the access gas costs for the initialization of
122+
// a contract creation.
116123
func (aw *AccessWitness) TouchAndChargeContractCreateInit(addr []byte, createSendsValue bool) uint64 {
117124
var gas uint64
118125
gas += aw.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.VersionLeafKey, true)
@@ -123,41 +130,30 @@ func (aw *AccessWitness) TouchAndChargeContractCreateInit(addr []byte, createSen
123130
return gas
124131
}
125132

126-
func (aw *AccessWitness) TouchTxOriginAndComputeGas(originAddr []byte) uint64 {
133+
// TouchTxOrigin adds the member fields of the sender account to the witness,
134+
// so that cold accesses are not charged, since they are covered by the 21000 gas.
135+
func (aw *AccessWitness) TouchTxOrigin(originAddr []byte) {
127136
for i := utils.VersionLeafKey; i <= utils.CodeSizeLeafKey; i++ {
128137
aw.touchAddressAndChargeGas(originAddr, zeroTreeIndex, byte(i), i == utils.BalanceLeafKey || i == utils.NonceLeafKey)
129138
}
130-
131-
// Kaustinen note: we're currently experimenting with stop chargin gas for the origin address
132-
// so simple transfer still take 21000 gas. This is to potentially avoid breaking existing tooling.
133-
// This is the reason why we return 0 instead of `gas`.
134-
// Note that we still have to touch the addresses to make sure the witness is correct.
135-
return 0
136139
}
137140

138-
func (aw *AccessWitness) TouchTxExistingAndComputeGas(targetAddr []byte, sendsValue bool) uint64 {
139-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.VersionLeafKey, false)
140-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.CodeSizeLeafKey, false)
141-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.CodeKeccakLeafKey, false)
142-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.NonceLeafKey, false)
143-
if sendsValue {
144-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, true)
145-
} else {
146-
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BalanceLeafKey, false)
141+
// TouchTxDestination adds the member fields of the sender account to the witness,
142+
// so that cold accesses are not charged, since they are covered by the 21000 gas.
143+
func (aw *AccessWitness) TouchTxDestination(targetAddr []byte, sendsValue bool) {
144+
for i := utils.VersionLeafKey; i <= utils.CodeSizeLeafKey; i++ {
145+
aw.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, byte(i), i == utils.VersionLeafKey && sendsValue)
147146
}
148-
149-
// Kaustinen note: we're currently experimenting with stop chargin gas for the origin address
150-
// so simple transfer still take 21000 gas. This is to potentially avoid breaking existing tooling.
151-
// This is the reason why we return 0 instead of `gas`.
152-
// Note that we still have to touch the addresses to make sure the witness is correct.
153-
return 0
154147
}
155148

149+
// TouchSlotAndChargeGas returns the amount of gas to be charged for a cold storage access.
156150
func (aw *AccessWitness) TouchSlotAndChargeGas(addr []byte, slot common.Hash, isWrite bool) uint64 {
157151
treeIndex, subIndex := utils.StorageIndex(slot.Bytes())
158152
return aw.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite)
159153
}
160154

155+
// touchAddressAndChargeGas adds any missing access event to the witness, and returns the cold
156+
// access cost to be charged, if need be.
161157
func (aw *AccessWitness) touchAddressAndChargeGas(addr []byte, treeIndex uint256.Int, subIndex byte, isWrite bool) uint64 {
162158
stemRead, selectorRead, stemWrite, selectorWrite, selectorFill := aw.touchAddress(addr, treeIndex, subIndex, isWrite)
163159

core/state_transition.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -423,17 +423,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
423423
targetAddr := msg.To
424424
originAddr := msg.From
425425

426-
statelessGasOrigin := st.evm.Accesses.TouchTxOriginAndComputeGas(originAddr.Bytes())
427-
if !tryConsumeGas(&st.gasRemaining, statelessGasOrigin) {
428-
return nil, fmt.Errorf("%w: Insufficient funds to cover witness access costs for transaction: have %d, want %d", ErrInsufficientBalanceWitness, st.gasRemaining, gas)
429-
}
426+
st.evm.Accesses.TouchTxOrigin(originAddr.Bytes())
430427
originNonce := st.evm.StateDB.GetNonce(originAddr)
431428

432429
if msg.To != nil {
433-
statelessGasDest := st.evm.Accesses.TouchTxExistingAndComputeGas(targetAddr.Bytes(), msg.Value.Sign() != 0)
434-
if !tryConsumeGas(&st.gasRemaining, statelessGasDest) {
435-
return nil, fmt.Errorf("%w: Insufficient funds to cover witness access costs for transaction: have %d, want %d", ErrInsufficientBalanceWitness, st.gasRemaining, gas)
436-
}
430+
st.evm.Accesses.TouchTxDestination(targetAddr.Bytes(), msg.Value.Sign() != 0)
437431

438432
// ensure the code size ends up in the access witness
439433
st.evm.StateDB.GetCodeSize(*targetAddr)
@@ -501,7 +495,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
501495

502496
// add the coinbase to the witness iff the fee is greater than 0
503497
if rules.IsEIP4762 && fee.Sign() != 0 {
504-
st.evm.Accesses.TouchFullAccount(st.evm.Context.Coinbase[:], true)
498+
st.evm.Accesses.TouchBalance(st.evm.Context.Coinbase[:], true)
505499
}
506500
}
507501

core/tracing/hooks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ const (
272272
GasChangeCallStorageColdAccess GasChangeReason = 13
273273
// GasChangeCallFailedExecution is the burning of the remaining gas when the execution failed without a revert.
274274
GasChangeCallFailedExecution GasChangeReason = 14
275+
// GasChangeWitnessContractInit is the amount charged for adding to the witness during the contract creation initialization step
276+
GasChangeWitnessContractInit GasChangeReason = 15
277+
// GasChangeWitnessContractCreation is the amount charged for adding to the witness during the contract creation finalization step
278+
GasChangeWitnessContractCreation GasChangeReason = 16
279+
// GasChangeWitnessCodeChunk is the amount charged for touching one or more contract code chunks
280+
GasChangeWitnessCodeChunk GasChangeReason = 17
275281

276282
// GasChangeIgnored is a special value that can be used to indicate that the gas change should be ignored as
277283
// it will be "manually" tracked by a direct emit of the gas change event.

core/vm/eips.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ func enable4762(jt *JumpTable) {
334334
jt[EXTCODEHASH].dynamicGas = gasExtCodeHash4762
335335
jt[EXTCODECOPY].constantGas = 0
336336
jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP4762
337+
jt[CODECOPY].dynamicGas = gasCodeCopyEip4762
337338
jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP4762
338339
jt[CREATE].constantGas = params.CreateNGasEip4762
339340
jt[CREATE2].constantGas = params.CreateNGasEip4762

core/vm/evm.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
510510

511511
// Charge the contract creation init gas in verkle mode
512512
if evm.chainRules.IsEIP4762 {
513-
if !contract.UseGas(evm.Accesses.TouchAndChargeContractCreateInit(address.Bytes(), value.Sign() != 0), evm.Config.Tracer, tracing.GasChangeUnspecified) {
513+
if !contract.UseGas(evm.Accesses.TouchAndChargeContractCreateInit(address.Bytes(), value.Sign() != 0), evm.Config.Tracer, tracing.GasChangeWitnessContractInit) {
514514
err = ErrOutOfGas
515515
}
516516
}
@@ -541,11 +541,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
541541
}
542542
} else {
543543
// Contract creation completed, touch the missing fields in the contract
544-
if !contract.UseGas(evm.Accesses.TouchFullAccount(address.Bytes()[:], true), evm.Config.Tracer, tracing.GasChangeUnspecified) {
544+
if !contract.UseGas(evm.Accesses.TouchFullAccount(address.Bytes()[:], true), evm.Config.Tracer, tracing.GasChangeWitnessContractCreation) {
545545
err = ErrOutOfGas
546546
}
547547

548-
if err != nil && len(ret) > 0 && !contract.UseGas(evm.Accesses.TouchCodeChunksRangeAndChargeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeUnspecified) {
548+
if err != nil && len(ret) > 0 && !contract.UseGas(evm.Accesses.TouchCodeChunksRangeAndChargeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)), true), evm.Config.Tracer, tracing.GasChangeWitnessCodeChunk) {
549549
err = ErrOutOfGas
550550
}
551551
}

core/vm/instructions.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -364,16 +364,8 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
364364
uint64CodeOffset = math.MaxUint64
365365
}
366366

367-
contractAddr := scope.Contract.Address()
368-
paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(scope.Contract.Code, uint64CodeOffset, length.Uint64())
369-
if interpreter.evm.chainRules.IsEIP4762 && !scope.Contract.IsDeployment {
370-
statelessGas := interpreter.evm.Accesses.TouchCodeChunksRangeAndChargeGas(contractAddr[:], copyOffset, nonPaddedCopyLength, uint64(len(scope.Contract.Code)), false)
371-
if !scope.Contract.UseGas(statelessGas, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified) {
372-
scope.Contract.Gas = 0
373-
return nil, ErrOutOfGas
374-
}
375-
}
376-
scope.Memory.Set(memOffset.Uint64(), uint64(len(paddedCodeCopy)), paddedCodeCopy)
367+
codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
368+
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
377369
return nil, nil
378370
}
379371

core/vm/operations_verkle.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ func gasSelfdestructEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Mem
108108
return statelessGas, nil
109109
}
110110

111+
func gasCodeCopyEip4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
112+
gas, err := gasCodeCopy(evm, contract, stack, mem, memorySize)
113+
if err != nil {
114+
return 0, err
115+
}
116+
var (
117+
codeOffset = stack.Back(1)
118+
length = stack.Back(2)
119+
)
120+
uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
121+
if overflow {
122+
uint64CodeOffset = math.MaxUint64
123+
}
124+
_, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(contract.Code, uint64CodeOffset, length.Uint64())
125+
if !contract.IsDeployment {
126+
gas += evm.Accesses.TouchCodeChunksRangeAndChargeGas(contract.Address().Bytes(), copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false)
127+
}
128+
return gas, nil
129+
}
130+
111131
func gasExtCodeCopyEIP4762(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
112132
// memory expansion first (dynamic part of pre-2929 implementation)
113133
gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize)

0 commit comments

Comments
 (0)