@@ -681,34 +681,43 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
681681 ret []byte
682682 vmerr error // vm errors do not effect consensus and are therefore not assigned to err
683683 )
684- if contractCreation {
685- deployedContract = & common.Address {}
686- ret , * deployedContract , st .gasRemaining , multiGas , vmerr = st .evm .Create (msg .From , msg .Data , st .gasRemaining , value )
687- usedMultiGas = usedMultiGas .SaturatingAdd (multiGas )
688- } else {
689- // Increment the nonce for the next transaction.
690- st .state .SetNonce (msg .From , st .state .GetNonce (msg .From )+ 1 , tracing .NonceChangeEoACall )
691684
692- // Apply EIP-7702 authorizations.
693- if msg .SetCodeAuthorizations != nil {
694- for _ , auth := range msg .SetCodeAuthorizations {
695- // Note errors are ignored, we simply skip invalid authorizations here.
696- st .applyAuthorization (& auth )
685+ // Check against hardcoded transaction hashes that have previously reverted, so instead
686+ // of executing the transaction we just update state nonce and remaining gas to avoid
687+ // state divergence.
688+ usedMultiGas , vmerr = st .handleRevertedTx (msg , usedMultiGas )
689+
690+ // vmerr is only not nil when we find a previous reverted transaction
691+ if vmerr == nil {
692+ if contractCreation {
693+ deployedContract = & common.Address {}
694+ ret , * deployedContract , st .gasRemaining , multiGas , vmerr = st .evm .Create (msg .From , msg .Data , st .gasRemaining , value )
695+ usedMultiGas = usedMultiGas .SaturatingAdd (multiGas )
696+ } else {
697+ // Increment the nonce for the next transaction.
698+ st .state .SetNonce (msg .From , st .state .GetNonce (msg .From )+ 1 , tracing .NonceChangeEoACall )
699+
700+ // Apply EIP-7702 authorizations.
701+ if msg .SetCodeAuthorizations != nil {
702+ for _ , auth := range msg .SetCodeAuthorizations {
703+ // Note errors are ignored, we simply skip invalid authorizations here.
704+ st .applyAuthorization (& auth )
705+ }
697706 }
698- }
699707
700- // Perform convenience warming of sender's delegation target. Although the
701- // sender is already warmed in Prepare(..), it's possible a delegation to
702- // the account was deployed during this transaction. To handle correctly,
703- // simply wait until the final state of delegations is determined before
704- // performing the resolution and warming.
705- if addr , ok := types .ParseDelegation (st .state .GetCode (* msg .To )); ok {
706- st .state .AddAddressToAccessList (addr )
707- }
708+ // Perform convenience warming of sender's delegation target. Although the
709+ // sender is already warmed in Prepare(..), it's possible a delegation to
710+ // the account was deployed during this transaction. To handle correctly,
711+ // simply wait until the final state of delegations is determined before
712+ // performing the resolution and warming.
713+ if addr , ok := types .ParseDelegation (st .state .GetCode (* msg .To )); ok {
714+ st .state .AddAddressToAccessList (addr )
715+ }
708716
709- // Execute the transaction's call.
710- ret , st .gasRemaining , multiGas , vmerr = st .evm .Call (msg .From , st .to (), msg .Data , st .gasRemaining , value )
711- usedMultiGas = usedMultiGas .SaturatingAdd (multiGas )
717+ // Execute the transaction's call.
718+ ret , st .gasRemaining , multiGas , vmerr = st .evm .Call (msg .From , st .to (), msg .Data , st .gasRemaining , value )
719+ usedMultiGas = usedMultiGas .SaturatingAdd (multiGas )
720+ }
712721 }
713722
714723 // Refund the gas that was held to limit the amount of computation done.
@@ -787,6 +796,30 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
787796 }, nil
788797}
789798
799+ // handleRevertedTx attempts to process a reverted transaction. It returns
800+ // ErrExecutionReverted with the updated multiGas if a matching reverted
801+ // tx is found; otherwise, it returns nil error with unchangedmultiGas
802+ func (st * stateTransition ) handleRevertedTx (msg * Message , usedMultiGas multigas.MultiGas ) (multigas.MultiGas , error ) {
803+ if msg .Tx == nil {
804+ return usedMultiGas , nil
805+ }
806+
807+ txHash := msg .Tx .Hash ()
808+ if l2GasUsed , ok := RevertedTxGasUsed [txHash ]; ok {
809+ st .state .SetNonce (msg .From , st .state .GetNonce (msg .From )+ 1 , tracing .NonceChangeEoACall )
810+
811+ // Calculate adjusted gas since l2GasUsed contains params.TxGas
812+ adjustedGas := l2GasUsed - params .TxGas
813+ st .gasRemaining -= adjustedGas
814+
815+ // Update multigas and return ErrExecutionReverted error
816+ usedMultiGas = usedMultiGas .SaturatingAdd (multigas .ComputationGas (adjustedGas ))
817+ return usedMultiGas , vm .ErrExecutionReverted
818+ }
819+
820+ return usedMultiGas , nil
821+ }
822+
790823// validateAuthorization validates an EIP-7702 authorization against the state.
791824func (st * stateTransition ) validateAuthorization (auth * types.SetCodeAuthorization ) (authority common.Address , err error ) {
792825 // Verify chain ID is null or equal to current chain ID.
0 commit comments