@@ -17,7 +17,7 @@ use crate::{
17
17
Transition :: { Delta , Same , To } ,
18
18
} ,
19
19
math_gadget:: { AddWordsGadget , RangeCheckGadget } ,
20
- not, or , Cell ,
20
+ not, Cell ,
21
21
} ,
22
22
} ,
23
23
table:: { AccountFieldTag , CallContextFieldTag } ,
@@ -370,7 +370,6 @@ impl<F: Field, const N_ADDENDS: usize, const INCREASE: bool>
370
370
pub ( crate ) struct TransferToGadget < F > {
371
371
receiver : UpdateBalanceGadget < F , 2 , true > ,
372
372
receiver_exists : Expression < F > ,
373
- must_create : Expression < F > ,
374
373
value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
375
374
}
376
375
@@ -380,16 +379,17 @@ impl<F: Field> TransferToGadget<F> {
380
379
cb : & mut EVMConstraintBuilder < F > ,
381
380
receiver_address : WordLoHi < Expression < F > > ,
382
381
receiver_exists : Expression < F > ,
383
- must_create : Expression < F > ,
382
+
384
383
value : Word32Cell < F > ,
385
384
mut reversion_info : Option < & mut ReversionInfo < F > > ,
386
385
) -> Self {
387
386
let value_is_zero = cb. is_zero_word ( & value) ;
387
+
388
388
// Create account
389
389
cb. condition (
390
390
and:: expr ( [
391
391
not:: expr ( receiver_exists. expr ( ) ) ,
392
- or :: expr ( [ not:: expr ( value_is_zero. expr ( ) ) , must_create . clone ( ) ] ) ,
392
+ not:: expr ( value_is_zero. expr ( ) ) ,
393
393
] ) ,
394
394
|cb| {
395
395
cb. account_write (
@@ -409,7 +409,6 @@ impl<F: Field> TransferToGadget<F> {
409
409
Self {
410
410
receiver,
411
411
receiver_exists,
412
- must_create,
413
412
value_is_zero,
414
413
}
415
414
}
@@ -436,8 +435,7 @@ impl<F: Field> TransferToGadget<F> {
436
435
pub ( crate ) fn rw_delta ( & self ) -> Expression < F > {
437
436
// +1 Write Account (receiver) CodeHash (account creation via code_hash update)
438
437
and:: expr ( [
439
- not:: expr ( self . receiver_exists . expr ( ) ) ,
440
- or:: expr ( [ not:: expr ( self . value_is_zero . expr ( ) ) , self . must_create . clone ( ) ] ) ,
438
+ not:: expr ( self . receiver_exists . expr ( ) ) , not:: expr ( self . value_is_zero . expr ( ) )
441
439
] ) +
442
440
// +1 Write Account (receiver) Balance
443
441
not:: expr ( self . value_is_zero . expr ( ) )
@@ -452,26 +450,29 @@ impl<F: Field> TransferToGadget<F> {
452
450
/// setting it's code_hash = EMPTY_HASH. The receiver account is also created
453
451
/// unconditionally if must_create is true. This gadget is used in BeginTx.
454
452
#[ derive( Clone , Debug ) ]
455
- pub ( crate ) struct TransferWithGasFeeGadget < F > {
456
- sender_sub_fee : UpdateBalanceGadget < F , 2 , false > ,
453
+ pub ( crate ) struct TransferGadget < F , const WITH_FEE : bool > {
454
+ sender_sub_fee : Option < UpdateBalanceGadget < F , 2 , false > > ,
457
455
sender_sub_value : UpdateBalanceGadget < F , 2 , false > ,
458
456
receiver : TransferToGadget < F > ,
459
- value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
457
+ pub ( crate ) value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
460
458
}
461
459
462
- impl < F : Field > TransferWithGasFeeGadget < F > {
460
+ impl < F : Field , const WITH_FEE : bool > TransferGadget < F , WITH_FEE > {
463
461
#[ allow( clippy:: too_many_arguments) ]
464
462
pub ( crate ) fn construct (
465
463
cb : & mut EVMConstraintBuilder < F > ,
466
464
sender_address : WordLoHi < Expression < F > > ,
467
465
receiver_address : WordLoHi < Expression < F > > ,
468
466
receiver_exists : Expression < F > ,
469
- must_create : Expression < F > ,
470
467
value : Word32Cell < F > ,
471
- gas_fee : Word32Cell < F > ,
472
468
reversion_info : & mut ReversionInfo < F > ,
469
+ gas_fee : Option < Word32Cell < F > > ,
473
470
) -> Self {
474
- let sender_sub_fee = cb. decrease_balance ( sender_address. to_word ( ) , gas_fee, None ) ;
471
+ let sender_sub_fee = if WITH_FEE {
472
+ Some ( cb. decrease_balance ( sender_address. to_word ( ) , gas_fee. expect ( "fee exists" ) , None ) )
473
+ } else {
474
+ None
475
+ } ;
475
476
let value_is_zero = cb. is_zero_word ( & value) ;
476
477
// Skip transfer if value == 0
477
478
let sender_sub_value = cb. condition ( not:: expr ( value_is_zero. expr ( ) ) , |cb| {
@@ -481,7 +482,6 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
481
482
cb,
482
483
receiver_address,
483
484
receiver_exists,
484
- must_create,
485
485
value,
486
486
Some ( reversion_info) ,
487
487
) ;
@@ -496,12 +496,9 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
496
496
497
497
pub ( crate ) fn rw_delta ( & self ) -> Expression < F > {
498
498
// +1 Write Account (sender) Balance (Not Reversible tx fee)
499
- 1 . expr ( ) +
499
+ WITH_FEE . expr ( ) +
500
500
// +1 Write Account (receiver) CodeHash (account creation via code_hash update)
501
- and:: expr ( [ not:: expr ( self . receiver . receiver_exists . expr ( ) ) , or:: expr ( [
502
- not:: expr ( self . value_is_zero . expr ( ) ) ,
503
- self . receiver . must_create . clone ( ) ]
504
- ) ] ) * 1 . expr ( ) +
501
+ self . receiver . rw_delta ( ) +
505
502
// +1 Write Account (sender) Balance
506
503
// +1 Write Account (receiver) Balance
507
504
not:: expr ( self . value_is_zero . expr ( ) ) * 2 . expr ( )
@@ -510,10 +507,7 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
510
507
pub ( crate ) fn reversible_w_delta ( & self ) -> Expression < F > {
511
508
// NOTE: Write Account (sender) Balance (Not Reversible tx fee)
512
509
// +1 Write Account (receiver) CodeHash (account creation via code_hash update)
513
- and:: expr ( [ not:: expr ( self . receiver . receiver_exists . expr ( ) ) , or:: expr ( [
514
- not:: expr ( self . value_is_zero . expr ( ) ) ,
515
- self . receiver . must_create . clone ( ) ]
516
- ) ] ) +
510
+ self . receiver . rw_delta ( ) +
517
511
// +1 Write Account (sender) Balance
518
512
// +1 Write Account (receiver) Balance
519
513
not:: expr ( self . value_is_zero . expr ( ) ) * 2 . expr ( )
@@ -524,19 +518,21 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
524
518
& self ,
525
519
region : & mut CachedRegion < ' _ , ' _ , F > ,
526
520
offset : usize ,
527
- ( sender_balance_sub_fee, prev_sender_balance_sub_fee) : ( U256 , U256 ) ,
521
+ ( sender_balance_sub_fee, prev_sender_balance_sub_fee) : ( Option < U256 > , Option < U256 > ) ,
528
522
( sender_balance_sub_value, prev_sender_balance_sub_value) : ( U256 , U256 ) ,
529
523
( receiver_balance, prev_receiver_balance) : ( U256 , U256 ) ,
530
524
value : U256 ,
531
- gas_fee : U256 ,
525
+ gas_fee : Option < U256 > ,
532
526
) -> Result < ( ) , Error > {
533
- self . sender_sub_fee . assign (
534
- region,
535
- offset,
536
- prev_sender_balance_sub_fee,
537
- vec ! [ gas_fee] ,
538
- sender_balance_sub_fee,
539
- ) ?;
527
+ if WITH_FEE {
528
+ self . sender_sub_fee . as_ref ( ) . expect ( "Exists" ) . assign (
529
+ region,
530
+ offset,
531
+ prev_sender_balance_sub_fee. expect ( "exists" ) ,
532
+ vec ! [ gas_fee. expect( "exists" ) ] ,
533
+ sender_balance_sub_fee. expect ( "exists" ) ,
534
+ ) ?;
535
+ }
540
536
self . sender_sub_value . assign (
541
537
region,
542
538
offset,
@@ -556,91 +552,6 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
556
552
}
557
553
}
558
554
559
- /// The TransferGadget handles a transfer of value from sender to receiver. The
560
- /// transfer is only performed if the value is not zero. If the transfer is
561
- /// performed and the receiver account doesn't exist, it will be created by
562
- /// setting it's code_hash = EMPTY_HASH. This gadget is used in callop.
563
- #[ derive( Clone , Debug ) ]
564
- pub ( crate ) struct TransferGadget < F > {
565
- sender : UpdateBalanceGadget < F , 2 , false > ,
566
- receiver : TransferToGadget < F > ,
567
- pub ( crate ) value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
568
- }
569
-
570
- impl < F : Field > TransferGadget < F > {
571
- pub ( crate ) fn construct (
572
- cb : & mut EVMConstraintBuilder < F > ,
573
- sender_address : WordLoHi < Expression < F > > ,
574
- receiver_address : WordLoHi < Expression < F > > ,
575
- receiver_exists : Expression < F > ,
576
- must_create : bool ,
577
- value : Word32Cell < F > ,
578
- reversion_info : & mut ReversionInfo < F > ,
579
- ) -> Self {
580
- let value_is_zero = cb. is_zero_word ( & value) ;
581
- // Skip transfer if value == 0
582
- let sender = cb. condition ( not:: expr ( value_is_zero. expr ( ) ) , |cb| {
583
- cb. decrease_balance ( sender_address, value. clone ( ) , Some ( reversion_info) )
584
- } ) ;
585
- let receiver = TransferToGadget :: construct (
586
- cb,
587
- receiver_address,
588
- receiver_exists,
589
- must_create. expr ( ) ,
590
- value,
591
- Some ( reversion_info) ,
592
- ) ;
593
-
594
- Self {
595
- sender,
596
- receiver,
597
- value_is_zero,
598
- }
599
- }
600
-
601
- pub ( crate ) fn reversible_w_delta ( & self ) -> Expression < F > {
602
- // +1 Write Account (receiver) CodeHash (account creation via code_hash update)
603
- or:: expr ( [
604
- not:: expr ( self . value_is_zero . expr ( ) ) * not:: expr ( self . receiver . receiver_exists . clone ( ) ) ,
605
- self . receiver . must_create . clone ( ) ]
606
- ) * 1 . expr ( ) +
607
- // +1 Write Account (sender) Balance
608
- // +1 Write Account (receiver) Balance
609
- not:: expr ( self . value_is_zero . expr ( ) ) * 2 . expr ( )
610
- }
611
-
612
- pub ( crate ) fn assign (
613
- & self ,
614
- region : & mut CachedRegion < ' _ , ' _ , F > ,
615
- offset : usize ,
616
- ( sender_balance, sender_balance_prev) : ( U256 , U256 ) ,
617
- ( receiver_balance, receiver_balance_prev) : ( U256 , U256 ) ,
618
- value : U256 ,
619
- ) -> Result < ( ) , Error > {
620
- self . sender . assign (
621
- region,
622
- offset,
623
- sender_balance_prev,
624
- vec ! [ value] ,
625
- sender_balance,
626
- ) ?;
627
- self . receiver . assign (
628
- region,
629
- offset,
630
- ( receiver_balance, receiver_balance_prev) ,
631
- value,
632
- ) ?;
633
- self . value_is_zero
634
- . assign_value ( region, offset, Value :: known ( WordLoHi :: from ( value) ) ) ?;
635
- Ok ( ( ) )
636
- }
637
-
638
- pub ( crate ) fn rw_delta ( & self ) -> Expression < F > {
639
- // +1 Write Account (sender) Balance
640
- not:: expr ( self . value_is_zero . expr ( ) ) + self . receiver . rw_delta ( )
641
- }
642
- }
643
-
644
555
#[ derive( Clone , Debug ) ]
645
556
pub ( crate ) struct CommonCallGadget < F , MemAddrGadget , const IS_SUCCESS_CALL : bool > {
646
557
pub is_success : Cell < F > ,
0 commit comments