Skip to content

Commit 91322eb

Browse files
Make tx/message data get accessed consistently through st.msg (#35)
1 parent 0aa8f1d commit 91322eb

File tree

1 file changed

+41
-53
lines changed

1 file changed

+41
-53
lines changed

core/state_transition.go

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,11 @@ The state transitioning model does all the necessary work to work out a valid ne
5050
6) Derive new state root
5151
*/
5252
type StateTransition struct {
53-
gp *GasPool
54-
msg Message
55-
gas uint64
56-
gasPrice *big.Int
57-
gasFeeCap *big.Int
58-
gasTipCap *big.Int
59-
maxFeePerDataGas *big.Int
60-
initialGas uint64
61-
value *big.Int
62-
data []byte
63-
state vm.StateDB
64-
evm *vm.EVM
53+
gp *GasPool
54+
msg Message
55+
gasRemaining uint64
56+
state vm.StateDB
57+
evm *vm.EVM
6558
}
6659

6760
// Message represents a message sent to a contract.
@@ -169,16 +162,10 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
169162
// NewStateTransition initialises and returns a new state transition object.
170163
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
171164
return &StateTransition{
172-
gp: gp,
173-
evm: evm,
174-
msg: msg,
175-
gasPrice: msg.GasPrice(),
176-
gasFeeCap: msg.GasFeeCap(),
177-
gasTipCap: msg.GasTipCap(),
178-
maxFeePerDataGas: msg.MaxFeePerDataGas(),
179-
value: msg.Value(),
180-
data: msg.Data(),
181-
state: evm.StateDB,
165+
gp: gp,
166+
evm: evm,
167+
msg: msg,
168+
state: evm.StateDB,
182169
}
183170
}
184171

@@ -203,7 +190,7 @@ func (st *StateTransition) to() common.Address {
203190

204191
func (st *StateTransition) buyGas() error {
205192
mgval := new(big.Int).SetUint64(st.msg.Gas())
206-
mgval = mgval.Mul(mgval, st.gasPrice)
193+
mgval = mgval.Mul(mgval, st.msg.GasPrice())
207194

208195
// compute data fee for eip-4844 data blobs if any
209196
dgval := new(big.Int)
@@ -219,14 +206,14 @@ func (st *StateTransition) buyGas() error {
219206

220207
// perform the required user balance checks
221208
balanceRequired := new(big.Int)
222-
if st.gasFeeCap == nil {
209+
if st.msg.GasFeeCap() == nil {
223210
balanceRequired.Set(mgval)
224211
} else {
225-
balanceRequired.Add(st.value, dgval)
212+
balanceRequired.Add(st.msg.Value(), dgval)
226213
// EIP-1559 mandates that the sender has enough balance to cover not just actual fee but
227214
// the max gas fee, so we compute this upper bound rather than use mgval here.
228215
maxGasFee := new(big.Int).SetUint64(st.msg.Gas())
229-
maxGasFee.Mul(maxGasFee, st.gasFeeCap)
216+
maxGasFee.Mul(maxGasFee, st.msg.GasFeeCap())
230217
balanceRequired.Add(balanceRequired, maxGasFee)
231218
}
232219
if have, want := st.state.GetBalance(st.msg.From()), balanceRequired; have.Cmp(want) < 0 {
@@ -237,8 +224,7 @@ func (st *StateTransition) buyGas() error {
237224
if err := st.gp.SubGas(st.msg.Gas()); err != nil {
238225
return err
239226
}
240-
st.gas += st.msg.Gas()
241-
st.initialGas = st.msg.Gas()
227+
st.gasRemaining += st.msg.Gas()
242228
if err := st.gp.SubDataGas(dataGasUsed); err != nil {
243229
return err
244230
}
@@ -270,37 +256,39 @@ func (st *StateTransition) preCheck() error {
270256
st.msg.From().Hex(), codeHash)
271257
}
272258
}
273-
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
259+
// Make sure that transaction GasFeeCap is greater than the baseFee (post london)
274260
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
261+
gasFeeCap := st.msg.GasFeeCap()
262+
gasTipCap := st.msg.GasTipCap()
275263
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
276-
if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
277-
if l := st.gasFeeCap.BitLen(); l > 256 {
264+
if !st.evm.Config.NoBaseFee || gasFeeCap.BitLen() > 0 || gasTipCap.BitLen() > 0 {
265+
if l := gasFeeCap.BitLen(); l > 256 {
278266
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
279267
st.msg.From().Hex(), l)
280268
}
281-
if l := st.gasTipCap.BitLen(); l > 256 {
269+
if l := gasTipCap.BitLen(); l > 256 {
282270
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
283271
st.msg.From().Hex(), l)
284272
}
285-
if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
273+
if gasFeeCap.Cmp(gasTipCap) < 0 {
286274
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
287-
st.msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
275+
st.msg.From().Hex(), gasTipCap, gasFeeCap)
288276
}
289277
// This will panic if baseFee is nil, but basefee presence is verified
290278
// as part of header validation.
291-
if st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
279+
if gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
292280
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
293-
st.msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
281+
st.msg.From().Hex(), gasFeeCap, st.evm.Context.BaseFee)
294282
}
295283
}
296284
}
297285
usesDataGas := st.dataGasUsed().Sign() > 0
298286
if usesDataGas && st.evm.ChainConfig().IsSharding(st.evm.Context.BlockNumber) {
299287
dataGasPrice := misc.GetDataGasPrice(st.evm.Context.ExcessDataGas)
300-
if dataGasPrice.Cmp(st.maxFeePerDataGas) > 0 {
288+
if dataGasPrice.Cmp(st.msg.MaxFeePerDataGas()) > 0 {
301289
return fmt.Errorf("%w: address %v, maxFeePerDataGas: %v dataGasPrice: %v, excessDataGas: %v",
302290
ErrMaxFeePerDataGas,
303-
st.msg.From().Hex(), st.maxFeePerDataGas, dataGasPrice, st.evm.Context.ExcessDataGas)
291+
st.msg.From().Hex(), st.msg.MaxFeePerDataGas(), dataGasPrice, st.evm.Context.ExcessDataGas)
304292
}
305293
}
306294
return st.buyGas()
@@ -338,9 +326,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
338326
}
339327

340328
if st.evm.Config.Debug {
341-
st.evm.Config.Tracer.CaptureTxStart(st.initialGas)
329+
st.evm.Config.Tracer.CaptureTxStart(st.msg.Gas())
342330
defer func() {
343-
st.evm.Config.Tracer.CaptureTxEnd(st.gas)
331+
st.evm.Config.Tracer.CaptureTxEnd(st.gasRemaining)
344332
}()
345333
}
346334

@@ -357,14 +345,14 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
357345
EIP4844: rules.IsSharding,
358346
}
359347
// Check clauses 4-5, subtract intrinsic gas if everything is correct
360-
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, intrinsicGasRules)
348+
gas, err := IntrinsicGas(msg.Data(), st.msg.AccessList(), contractCreation, intrinsicGasRules)
361349
if err != nil {
362350
return nil, err
363351
}
364-
if st.gas < gas {
365-
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
352+
if st.gasRemaining < gas {
353+
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
366354
}
367-
st.gas -= gas
355+
st.gasRemaining -= gas
368356

369357
// Check clause 6
370358
if msg.Value().Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
@@ -380,11 +368,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
380368
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
381369
)
382370
if contractCreation {
383-
ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value)
371+
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data(), st.gasRemaining, msg.Value())
384372
} else {
385373
// Increment the nonce for the next transaction
386374
st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
387-
ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
375+
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data(), st.gasRemaining, msg.Value())
388376
}
389377

390378
// Note that unlike regular gas, data fee gas is not refunded if the tx is reverted, per
@@ -397,12 +385,12 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
397385
st.refundGas(params.RefundQuotientEIP3529)
398386
}
399387

400-
effectiveTip := st.gasPrice
388+
effectiveTip := msg.GasPrice()
401389
if rules.IsLondon {
402-
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
390+
effectiveTip = cmath.BigMin(msg.GasTipCap(), new(big.Int).Sub(msg.GasFeeCap(), st.evm.Context.BaseFee))
403391
}
404392

405-
if st.evm.Config.NoBaseFee && st.gasFeeCap.Sign() == 0 && st.gasTipCap.Sign() == 0 {
393+
if st.evm.Config.NoBaseFee && msg.GasFeeCap().Sign() == 0 && msg.GasTipCap().Sign() == 0 {
406394
// Skip fee payment when NoBaseFee is set and the fee fields
407395
// are 0. This avoids a negative effectiveTip being applied to
408396
// the coinbase when simulating calls.
@@ -425,20 +413,20 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
425413
if refund > st.state.GetRefund() {
426414
refund = st.state.GetRefund()
427415
}
428-
st.gas += refund
416+
st.gasRemaining += refund
429417

430418
// Return ETH for remaining gas, exchanged at the original rate.
431-
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
419+
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gasRemaining), st.msg.GasPrice())
432420
st.state.AddBalance(st.msg.From(), remaining)
433421

434422
// Also return remaining gas to the block gas counter so it is
435423
// available for the next transaction.
436-
st.gp.AddGas(st.gas)
424+
st.gp.AddGas(st.gasRemaining)
437425
}
438426

439427
// gasUsed returns the amount of gas used up by the state transition.
440428
func (st *StateTransition) gasUsed() uint64 {
441-
return st.initialGas - st.gas
429+
return st.msg.Gas() - st.gasRemaining
442430
}
443431

444432
func (st *StateTransition) dataGasUsed() *big.Int {

0 commit comments

Comments
 (0)