@@ -23,7 +23,7 @@ import (
2323
2424 "github.com/ethereum/go-ethereum/common"
2525 cmath "github.com/ethereum/go-ethereum/common/math"
26- // "github.com/ethereum/go-ethereum/consensus/misc"
26+ "github.com/ethereum/go-ethereum/consensus/misc"
2727 "github.com/ethereum/go-ethereum/core/types"
2828 "github.com/ethereum/go-ethereum/core/vm"
2929 "github.com/ethereum/go-ethereum/crypto"
@@ -72,6 +72,7 @@ type Message interface {
7272 GasPrice () * big.Int
7373 GasFeeCap () * big.Int
7474 GasTipCap () * big.Int
75+ MaxFeePerDataGas () * big.Int
7576 Gas () uint64
7677 Value () * big.Int
7778
@@ -162,25 +163,22 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
162163 gas += uint64 (len (accessList )) * params .TxAccessListAddressGas
163164 gas += uint64 (accessList .StorageKeys ()) * params .TxAccessListStorageKeyGas
164165 }
165- // TODO
166- //if rules.EIP4844 {
167- //gas += uint64(blobCount) * getBlobGas(blockExcessBlobs)
168- //}
169166 return gas , nil
170167}
171168
172169// NewStateTransition initialises and returns a new state transition object.
173170func NewStateTransition (evm * vm.EVM , msg Message , gp * GasPool ) * StateTransition {
174171 return & StateTransition {
175- gp : gp ,
176- evm : evm ,
177- msg : msg ,
178- gasPrice : msg .GasPrice (),
179- gasFeeCap : msg .GasFeeCap (),
180- gasTipCap : msg .GasTipCap (),
181- value : msg .Value (),
182- data : msg .Data (),
183- state : evm .StateDB ,
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 ,
184182 }
185183}
186184
@@ -206,21 +204,35 @@ func (st *StateTransition) to() common.Address {
206204func (st * StateTransition ) buyGas () error {
207205 mgval := new (big.Int ).SetUint64 (st .msg .Gas ())
208206 mgval = mgval .Mul (mgval , st .gasPrice )
209- balanceCheck := mgval
210- if st .gasFeeCap != nil {
211- balanceCheck = new (big.Int ).SetUint64 (st .msg .Gas ())
212- balanceCheck = balanceCheck .Mul (balanceCheck , st .gasFeeCap )
213- balanceCheck .Add (balanceCheck , st .value )
207+
208+ dgval := new (big.Int )
209+ if st .evm .ChainConfig ().IsSharding (st .evm .Context .BlockNumber ) {
210+ // add in fee for eip-4844 data blobs if any
211+ dgval .Mul (misc .GetDataGasPrice (st .evm .Context .ExcessDataGas ), st .dataGasUsed ())
212+ }
213+
214+ balanceCheck := new (big.Int )
215+ if st .gasFeeCap == nil {
216+ balanceCheck .Set (mgval )
217+ } else {
218+ balanceCheck .Add (st .value , dgval )
219+ // EIP-1559 mandates that the sender has enough balance to cover not just actual fee but
220+ // the max gas fee, so we compute this upper bound rather than use mgval here.
221+ maxGasFee := new (big.Int ).SetUint64 (st .msg .Gas ())
222+ maxGasFee .Mul (maxGasFee , st .gasFeeCap )
223+ balanceCheck .Add (balanceCheck , maxGasFee )
214224 }
225+
215226 if have , want := st .state .GetBalance (st .msg .From ()), balanceCheck ; have .Cmp (want ) < 0 {
216227 return fmt .Errorf ("%w: address %v have %v want %v" , ErrInsufficientFunds , st .msg .From ().Hex (), have , want )
217228 }
218229 if err := st .gp .SubGas (st .msg .Gas ()); err != nil {
219230 return err
220231 }
221232 st .gas += st .msg .Gas ()
222-
223233 st .initialGas = st .msg .Gas ()
234+
235+ mgval .Add (mgval , dgval ) // both regular gas fee and data gas fee need to be deducted
224236 st .state .SubBalance (st .msg .From (), mgval )
225237 return nil
226238}
@@ -270,6 +282,13 @@ func (st *StateTransition) preCheck() error {
270282 }
271283 }
272284 }
285+ if st .evm .ChainConfig ().IsSharding (st .evm .Context .BlockNumber ) {
286+ dataGasPrice := misc .GetDataGasPrice (st .evm .Context .ExcessDataGas )
287+ if dataGasPrice .Cmp (st .maxFeePerDataGas ) > 0 {
288+ return fmt .Errorf ("%w: address %v, maxFeePerDataGas: %v dataGasPrice: %v" , ErrMaxFeePerDataGas ,
289+ st .msg .From ().Hex (), st .maxFeePerDataGas , dataGasPrice )
290+ }
291+ }
273292 return st .buyGas ()
274293}
275294
@@ -291,7 +310,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
291310 // applying the message. The rules include these clauses
292311 //
293312 // 1. the nonce of the message caller is correct
294- // 2. caller has enough balance to cover transaction fee(gaslimit * gasprice)
313+ // 2. caller has enough balance to cover:
314+ // Legacy tx: fee(gaslimit * gasprice)
315+ // EIP-1559 tx: tx.value + max-fee(gaslimit * gascap + datagas * datagasprice)
295316 // 3. the amount of gas required is available in the block
296317 // 4. the purchased gas is enough to cover intrinsic usage
297318 // 5. there is no overflow when calculating intrinsic gas
@@ -402,3 +423,13 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
402423func (st * StateTransition ) gasUsed () uint64 {
403424 return st .initialGas - st .gas
404425}
426+
427+ func (st * StateTransition ) dataGasUsed () * big.Int {
428+ dataGas := new (big.Int )
429+ l := int64 (len (st .msg .DataHashes ()))
430+ if l != 0 {
431+ dataGas .SetInt64 (l )
432+ dataGas .Mul (dataGas , big .NewInt (params .DataGasPerBlob ))
433+ }
434+ return dataGas
435+ }
0 commit comments