@@ -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,16 @@ 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 > ,
384
382
value : Word32Cell < F > ,
385
383
mut reversion_info : Option < & mut ReversionInfo < F > > ,
386
384
) -> Self {
387
385
let value_is_zero = cb. is_zero_word ( & value) ;
386
+
388
387
// Create account
389
388
cb. condition (
390
389
and:: expr ( [
391
390
not:: expr ( receiver_exists. expr ( ) ) ,
392
- or :: expr ( [ not:: expr ( value_is_zero. expr ( ) ) , must_create . clone ( ) ] ) ,
391
+ not:: expr ( value_is_zero. expr ( ) ) ,
393
392
] ) ,
394
393
|cb| {
395
394
cb. account_write (
@@ -409,7 +408,6 @@ impl<F: Field> TransferToGadget<F> {
409
408
Self {
410
409
receiver,
411
410
receiver_exists,
412
- must_create,
413
411
value_is_zero,
414
412
}
415
413
}
@@ -436,8 +434,7 @@ impl<F: Field> TransferToGadget<F> {
436
434
pub ( crate ) fn rw_delta ( & self ) -> Expression < F > {
437
435
// +1 Write Account (receiver) CodeHash (account creation via code_hash update)
438
436
and:: expr ( [
439
- not:: expr ( self . receiver_exists . expr ( ) ) ,
440
- or:: expr ( [ not:: expr ( self . value_is_zero . expr ( ) ) , self . must_create . clone ( ) ] ) ,
437
+ not:: expr ( self . receiver_exists . expr ( ) ) , not:: expr ( self . value_is_zero . expr ( ) )
441
438
] ) +
442
439
// +1 Write Account (receiver) Balance
443
440
not:: expr ( self . value_is_zero . expr ( ) )
@@ -452,26 +449,29 @@ impl<F: Field> TransferToGadget<F> {
452
449
/// setting it's code_hash = EMPTY_HASH. The receiver account is also created
453
450
/// unconditionally if must_create is true. This gadget is used in BeginTx.
454
451
#[ derive( Clone , Debug ) ]
455
- pub ( crate ) struct TransferWithGasFeeGadget < F > {
456
- sender_sub_fee : UpdateBalanceGadget < F , 2 , false > ,
452
+ pub ( crate ) struct TransferGadget < F , const WITH_FEE : bool > {
453
+ sender_sub_fee : Option < UpdateBalanceGadget < F , 2 , false > > ,
457
454
sender_sub_value : UpdateBalanceGadget < F , 2 , false > ,
458
455
receiver : TransferToGadget < F > ,
459
- value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
456
+ pub ( crate ) value_is_zero : IsZeroWordGadget < F , Word32Cell < F > > ,
460
457
}
461
458
462
- impl < F : Field > TransferWithGasFeeGadget < F > {
459
+ impl < F : Field , const WITH_FEE : bool > TransferGadget < F , WITH_FEE > {
463
460
#[ allow( clippy:: too_many_arguments) ]
464
461
pub ( crate ) fn construct (
465
462
cb : & mut EVMConstraintBuilder < F > ,
466
463
sender_address : WordLoHi < Expression < F > > ,
467
464
receiver_address : WordLoHi < Expression < F > > ,
468
465
receiver_exists : Expression < F > ,
469
- must_create : Expression < F > ,
470
466
value : Word32Cell < F > ,
471
- gas_fee : Word32Cell < F > ,
472
467
reversion_info : & mut ReversionInfo < F > ,
468
+ gas_fee : Option < Word32Cell < F > > ,
473
469
) -> Self {
474
- let sender_sub_fee = cb. decrease_balance ( sender_address. to_word ( ) , gas_fee, None ) ;
470
+ let sender_sub_fee = if WITH_FEE {
471
+ Some ( cb. decrease_balance ( sender_address. to_word ( ) , gas_fee. expect ( "fee exists" ) , None ) )
472
+ } else {
473
+ None
474
+ } ;
475
475
let value_is_zero = cb. is_zero_word ( & value) ;
476
476
// Skip transfer if value == 0
477
477
let sender_sub_value = cb. condition ( not:: expr ( value_is_zero. expr ( ) ) , |cb| {
@@ -481,7 +481,6 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
481
481
cb,
482
482
receiver_address,
483
483
receiver_exists,
484
- must_create,
485
484
value,
486
485
Some ( reversion_info) ,
487
486
) ;
@@ -496,12 +495,9 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
496
495
497
496
pub ( crate ) fn rw_delta ( & self ) -> Expression < F > {
498
497
// +1 Write Account (sender) Balance (Not Reversible tx fee)
499
- 1 . expr ( ) +
498
+ WITH_FEE . expr ( ) +
500
499
// +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 ( ) +
500
+ self . receiver . rw_delta ( ) +
505
501
// +1 Write Account (sender) Balance
506
502
// +1 Write Account (receiver) Balance
507
503
not:: expr ( self . value_is_zero . expr ( ) ) * 2 . expr ( )
@@ -510,10 +506,7 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
510
506
pub ( crate ) fn reversible_w_delta ( & self ) -> Expression < F > {
511
507
// NOTE: Write Account (sender) Balance (Not Reversible tx fee)
512
508
// +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
- ) ] ) +
509
+ self . receiver . rw_delta ( ) +
517
510
// +1 Write Account (sender) Balance
518
511
// +1 Write Account (receiver) Balance
519
512
not:: expr ( self . value_is_zero . expr ( ) ) * 2 . expr ( )
@@ -524,19 +517,21 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
524
517
& self ,
525
518
region : & mut CachedRegion < ' _ , ' _ , F > ,
526
519
offset : usize ,
527
- ( sender_balance_sub_fee, prev_sender_balance_sub_fee) : ( U256 , U256 ) ,
520
+ ( sender_balance_sub_fee, prev_sender_balance_sub_fee) : ( Option < U256 > , Option < U256 > ) ,
528
521
( sender_balance_sub_value, prev_sender_balance_sub_value) : ( U256 , U256 ) ,
529
522
( receiver_balance, prev_receiver_balance) : ( U256 , U256 ) ,
530
523
value : U256 ,
531
- gas_fee : U256 ,
524
+ gas_fee : Option < U256 > ,
532
525
) -> 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
- ) ?;
526
+ if WITH_FEE {
527
+ self . sender_sub_fee . as_ref ( ) . expect ( "Exists" ) . assign (
528
+ region,
529
+ offset,
530
+ prev_sender_balance_sub_fee. expect ( "exists" ) ,
531
+ vec ! [ gas_fee. expect( "exists" ) ] ,
532
+ sender_balance_sub_fee. expect ( "exists" ) ,
533
+ ) ?;
534
+ }
540
535
self . sender_sub_value . assign (
541
536
region,
542
537
offset,
@@ -556,91 +551,6 @@ impl<F: Field> TransferWithGasFeeGadget<F> {
556
551
}
557
552
}
558
553
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
554
#[ derive( Clone , Debug ) ]
645
555
pub ( crate ) struct CommonCallGadget < F , MemAddrGadget , const IS_SUCCESS_CALL : bool > {
646
556
pub is_success : Cell < F > ,
0 commit comments