@@ -24,7 +24,7 @@ use crate::{
24
24
} ,
25
25
} ;
26
26
use bus_mapping:: circuit_input_builder:: CopyDataType ;
27
- use eth_types:: { Address , Field , ToLittleEndian , ToScalar , U256 } ;
27
+ use eth_types:: { geth_types :: TxType :: L1Msg , Address , Field , ToLittleEndian , ToScalar , U256 } ;
28
28
use ethers_core:: utils:: { get_contract_address, keccak256, rlp:: RlpStream } ;
29
29
use gadgets:: util:: { expr_from_bytes, not, or, Expr } ;
30
30
use halo2_proofs:: { circuit:: Value , plonk:: Error } ;
@@ -42,6 +42,8 @@ use gadgets::util::select;
42
42
#[ derive( Clone , Debug ) ]
43
43
pub ( crate ) struct BeginTxGadget < F > {
44
44
tx_id : Cell < F > ,
45
+ tx_type : Cell < F > ,
46
+ tx_is_l1msg : IsEqualGadget < F > ,
45
47
tx_nonce : Cell < F > ,
46
48
tx_gas : Cell < F > ,
47
49
tx_gas_price : Word < F > ,
@@ -99,7 +101,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
99
101
100
102
let tx_id = cb. query_cell ( ) ;
101
103
102
- let [ tx_nonce, tx_gas, tx_caller_address, tx_callee_address, tx_is_create, tx_call_data_length, tx_call_data_gas_cost, tx_data_gas_cost] =
104
+ let [ tx_nonce, tx_gas, tx_caller_address, tx_callee_address, tx_is_create, tx_call_data_length, tx_call_data_gas_cost, tx_data_gas_cost, tx_type ] =
103
105
[
104
106
TxContextFieldTag :: Nonce ,
105
107
TxContextFieldTag :: Gas ,
@@ -109,10 +111,18 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
109
111
TxContextFieldTag :: CallDataLength ,
110
112
TxContextFieldTag :: CallDataGasCost ,
111
113
TxContextFieldTag :: TxDataGasCost ,
114
+ TxContextFieldTag :: TxType ,
112
115
]
113
116
. map ( |field_tag| cb. tx_context ( tx_id. expr ( ) , field_tag, None ) ) ;
114
117
115
- let tx_l1_fee = TxL1FeeGadget :: construct ( cb, tx_id. expr ( ) , tx_data_gas_cost. expr ( ) ) ;
118
+ let tx_is_l1msg = IsEqualGadget :: construct ( cb, tx_type. expr ( ) , ( L1Msg as u64 ) . expr ( ) ) ;
119
+ let tx_l1_fee = cb. condition ( not:: expr ( tx_is_l1msg. expr ( ) ) , |cb| {
120
+ TxL1FeeGadget :: construct ( cb, tx_id. expr ( ) , tx_data_gas_cost. expr ( ) )
121
+ } ) ;
122
+ cb. condition ( tx_is_l1msg. expr ( ) , |cb| {
123
+ cb. require_zero ( "l1fee is 0 for l1msg" , tx_data_gas_cost. expr ( ) ) ;
124
+ } ) ;
125
+ let tx_l1_fee_rw_delta = select:: expr ( tx_is_l1msg. expr ( ) , 0 . expr ( ) , tx_l1_fee. rw_delta ( ) ) ;
116
126
117
127
cb. call_context_lookup (
118
128
1 . expr ( ) ,
@@ -179,8 +189,11 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
179
189
180
190
cb. require_equal (
181
191
"tx_fee == l1_fee + l2_fee" ,
182
- from_bytes:: expr ( & tx_l1_fee. tx_l1_fee ( ) . cells [ ..] )
183
- + from_bytes:: expr ( & mul_gas_fee_by_gas. product ( ) . cells [ ..16 ] ) ,
192
+ select:: expr (
193
+ tx_is_l1msg. expr ( ) ,
194
+ 0 . expr ( ) ,
195
+ from_bytes:: expr ( & tx_l1_fee. tx_l1_fee ( ) . cells [ ..] ) ,
196
+ ) + from_bytes:: expr ( & mul_gas_fee_by_gas. product ( ) . cells [ ..16 ] ) ,
184
197
from_bytes:: expr ( & tx_fee. cells [ ..16 ] ) ,
185
198
) ;
186
199
@@ -438,7 +451,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
438
451
// - Write CallContext CodeHash
439
452
rw_counter : Delta (
440
453
22 . expr ( )
441
- + tx_l1_fee . rw_delta ( )
454
+ + tx_l1_fee_rw_delta . expr ( )
442
455
+ transfer_with_gas_fee. rw_delta ( )
443
456
+ SHANGHAI_RW_DELTA . expr ( )
444
457
+ PRECOMPILE_COUNT . expr ( ) ,
@@ -494,7 +507,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
494
507
// - a TransferWithGasFeeGadget
495
508
rw_counter : Delta (
496
509
7 . expr ( )
497
- + tx_l1_fee . rw_delta ( )
510
+ + tx_l1_fee_rw_delta . expr ( )
498
511
+ transfer_with_gas_fee. rw_delta ( )
499
512
+ SHANGHAI_RW_DELTA . expr ( )
500
513
+ PRECOMPILE_COUNT . expr ( )
@@ -547,7 +560,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
547
560
// - a TransferWithGasFeeGadget
548
561
rw_counter : Delta (
549
562
8 . expr ( )
550
- + tx_l1_fee . rw_delta ( )
563
+ + tx_l1_fee_rw_delta . expr ( )
551
564
+ transfer_with_gas_fee. rw_delta ( )
552
565
+ SHANGHAI_RW_DELTA . expr ( )
553
566
+ PRECOMPILE_COUNT . expr ( ) ,
@@ -619,7 +632,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
619
632
// - Write CallContext CodeHash
620
633
rw_counter : Delta (
621
634
21 . expr ( )
622
- + tx_l1_fee . rw_delta ( )
635
+ + tx_l1_fee_rw_delta . expr ( )
623
636
+ transfer_with_gas_fee. rw_delta ( )
624
637
+ SHANGHAI_RW_DELTA . expr ( )
625
638
+ PRECOMPILE_COUNT . expr ( ) ,
@@ -638,6 +651,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
638
651
639
652
Self {
640
653
tx_id,
654
+ tx_type,
655
+ tx_is_l1msg,
641
656
tx_nonce,
642
657
tx_gas,
643
658
tx_gas_price,
@@ -690,7 +705,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
690
705
let zero = eth_types:: Word :: zero ( ) ;
691
706
692
707
let mut rws = StepRws :: new ( block, step) ;
693
- rws. offset_add ( 10 + PRECOMPILE_COUNT ) ;
708
+ rws. offset_add ( if tx . tx_type . is_l1_msg ( ) { 7 } else { 10 } + PRECOMPILE_COUNT ) ;
694
709
695
710
#[ cfg( feature = "shanghai" ) ]
696
711
let is_coinbase_warm = rws. next ( ) . tx_access_list_value_pair ( ) . 1 ;
@@ -727,6 +742,14 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
727
742
728
743
self . tx_id
729
744
. assign ( region, offset, Value :: known ( F :: from ( tx. id as u64 ) ) ) ?;
745
+ self . tx_type
746
+ . assign ( region, offset, Value :: known ( F :: from ( tx. tx_type as u64 ) ) ) ?;
747
+ self . tx_is_l1msg . assign (
748
+ region,
749
+ offset,
750
+ F :: from ( tx. tx_type as u64 ) ,
751
+ F :: from ( L1Msg as u64 ) ,
752
+ ) ?;
730
753
self . tx_nonce
731
754
. assign ( region, offset, Value :: known ( F :: from ( tx. nonce ) ) ) ?;
732
755
self . tx_gas
@@ -917,7 +940,12 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
917
940
self . is_coinbase_warm
918
941
. assign ( region, offset, Value :: known ( F :: from ( is_coinbase_warm) ) ) ?;
919
942
920
- let tx_l1_fee = tx. l1_fee . tx_l1_fee ( tx. tx_data_gas_cost ) . 0 ;
943
+ let tx_l1_fee = if tx. tx_type . is_l1_msg ( ) {
944
+ log:: trace!( "tx is l1msg and l1 fee is 0" ) ;
945
+ 0
946
+ } else {
947
+ tx. l1_fee . tx_l1_fee ( tx. tx_data_gas_cost ) . 0
948
+ } ;
921
949
let tx_l2_fee = tx. gas_price * tx. gas ;
922
950
if tx_fee != tx_l2_fee + tx_l1_fee {
923
951
log:: error!(
0 commit comments