@@ -75,7 +75,7 @@ type Rollup struct {
7575 // collectedL1FeeSum
7676 collectedL1FeeSum float64
7777 // batchcache
78- batchCache map [ uint64 ] * eth. RPCRollupBatch
78+ batchCache * BatchCache
7979 bm * l1checker.BlockMonitor
8080}
8181
@@ -114,7 +114,7 @@ func NewRollup(
114114 cfg : cfg ,
115115 signer : types .LatestSignerForChainID (chainId ),
116116 externalRsaPriv : rsaPriv ,
117- batchCache : make ( map [ uint64 ] * eth. RPCRollupBatch ),
117+ batchCache : NewBatchCache ( ),
118118 ldb : ldb ,
119119 bm : bm ,
120120 }
@@ -256,7 +256,7 @@ func (r *Rollup) ProcessTx() error {
256256 if ispending {
257257 if txRecord .sendTime + uint64 (r .cfg .TxTimeout .Seconds ()) < uint64 (time .Now ().Unix ()) {
258258 log .Info ("tx timeout" , "tx" , rtx .Hash ().Hex (), "nonce" , rtx .Nonce (), "method" , method )
259- newtx , err := r .ReSubmitTx (false , rtx )
259+ newtx , err := r .ReSubmitTx (false , rtx , r . GetReSubmitBatchIndex ( method , rtx . Data ()) )
260260 if err != nil {
261261 log .Error ("resubmit tx" , "error" , err , "tx" , rtx .Hash ().Hex (), "nonce" , rtx .Nonce ())
262262 return fmt .Errorf ("resubmit tx error:%w" , err )
@@ -281,7 +281,8 @@ func (r *Rollup) ProcessTx() error {
281281 "nonce" , rtx .Nonce (),
282282 "query_times" , txRecord .queryTimes ,
283283 )
284- replacedtx , err := r .ReSubmitTx (true , rtx )
284+
285+ replacedtx , err := r .ReSubmitTx (true , rtx , r .GetReSubmitBatchIndex (method , rtx .Data ()))
285286 if err != nil {
286287 log .Error ("resend discarded tx" , "old_tx" , rtx .Hash ().String (), "nonce" , rtx .Nonce (), "error" , err )
287288 if utils .ErrStringMatch (err , core .ErrNonceTooLow ) {
@@ -358,7 +359,7 @@ func (r *Rollup) ProcessTx() error {
358359 }
359360 r .metrics .SetRollupCost (fee )
360361 index := utils .ParseParentBatchIndex (rtx .Data ()) + 1
361- batch , ok := r .batchCache [ index ]
362+ batch , ok := r .batchCache . Get ( index )
362363 if ok {
363364 collectedL1FeeFloat := ToEtherFloat ((* big .Int )(batch .CollectedL1Fee ))
364365 r .collectedL1FeeSum += collectedL1FeeFloat
@@ -368,7 +369,7 @@ func (r *Rollup) ProcessTx() error {
368369 }
369370 r .metrics .SetCollectedL1Fee (ToEtherFloat ((* big .Int )(batch .CollectedL1Fee )))
370371 // remove batch from cache
371- delete ( r .batchCache , index )
372+ r .batchCache . Delete ( index )
372373 } else {
373374 log .Warn ("batch not found in batchCache while set collect fee metrics" ,
374375 "index" , index ,
@@ -527,7 +528,7 @@ func (r *Rollup) finalize() error {
527528 "size" , signedTx .Size (),
528529 )
529530
530- err = r .SendTx (signedTx )
531+ err = r .SendTx (signedTx , 0 )
531532 if err != nil {
532533 log .Error ("send finalize tx to mempool" , "error" , err .Error ())
533534 if utils .ErrStringMatch (err , core .ErrNonceTooLow ) {
@@ -650,9 +651,13 @@ func (r *Rollup) rollup() error {
650651 return nil
651652 }
652653
653- batch , err := GetRollupBatchByIndex (batchIndex , r .L2Clients )
654- if err != nil {
655- return fmt .Errorf ("get rollup batch by index err:%v" , err )
654+ var batch * eth.RPCRollupBatch
655+ batch , ok := r .batchCache .Get (batchIndex )
656+ if ! ok {
657+ batch , err = GetRollupBatchByIndex (batchIndex , r .L2Clients )
658+ if err != nil {
659+ return fmt .Errorf ("get rollup batch by index err:%v" , err )
660+ }
656661 }
657662
658663 // check if the batch is valid
@@ -668,7 +673,7 @@ func (r *Rollup) rollup() error {
668673
669674 // set batch cache
670675 // it shoud be removed after the batch is committed
671- r .batchCache [ batchIndex ] = batch
676+ r .batchCache . Set ( batchIndex , batch )
672677
673678 signature , err := r .buildSignatureInput (batch )
674679 if err != nil {
@@ -708,7 +713,7 @@ func (r *Rollup) rollup() error {
708713 }
709714
710715 if r .cfg .RoughEstimateGas {
711- msgcnt := utils .ParseL1MessageCnt (batch .BlockContexts )
716+ msgcnt := r .ParseL1MessageCnt (batch .BlockContexts )
712717 gas = r .RoughRollupGasEstimate (msgcnt )
713718 log .Info ("rough estimate rollup tx gas" , "gas" , gas , "msgcnt" , msgcnt )
714719 } else {
@@ -786,7 +791,7 @@ func (r *Rollup) rollup() error {
786791 "blob_len" , len (signedTx .BlobHashes ()),
787792 )
788793
789- err = r .SendTx (signedTx )
794+ err = r .SendTx (signedTx , batchIndex )
790795 if err != nil {
791796 log .Error ("send tx to mempool" , "error" , err .Error ())
792797 if utils .ErrStringMatch (err , core .ErrNonceTooLow ) {
@@ -1091,7 +1096,7 @@ func UpdateGasLimit(tx *types.Transaction) (*types.Transaction, error) {
10911096}
10921097
10931098// send tx to l1 with business logic check
1094- func (r * Rollup ) SendTx (tx * types.Transaction ) error {
1099+ func (r * Rollup ) SendTx (tx * types.Transaction , batchIndex uint64 ) error {
10951100
10961101 // judge tx info is valid
10971102 if tx == nil {
@@ -1101,7 +1106,30 @@ func (r *Rollup) SendTx(tx *types.Transaction) error {
11011106 if ! r .bm .IsGrowth () {
11021107 return fmt .Errorf ("block not growth in %d blocks time" , r .cfg .BlockNotIncreasedThreshold )
11031108 }
1109+ // check batch loss
1110+ if r .cfg .RollupLossControl {
1111+ // calc fee
1112+ fee := utils .CalcFeeForTx (tx )
1113+ // get batch
1114+ var collectedL1Fee * big.Int
1115+ batch , ok := r .batchCache .Get (batchIndex )
1116+ if ok {
1117+ collectedL1Fee = batch .CollectedL1Fee .ToInt ()
1118+ if collectedL1Fee == nil {
1119+ collectedL1Fee = big .NewInt (0 )
1120+ }
1121+ } else {
1122+ log .Warn ("batch not found in cache when calc fee before SendTx" , "batchIndex" , batchIndex )
1123+ collectedL1Fee = big .NewInt (0 )
1124+ }
1125+ // targetFee = fee * (100 + cfg.RotatorBuffer)/100
1126+ targetFee := new (big.Int ).Mul (fee , big .NewInt (100 + r .cfg .RotatorBuffer ))
1127+ targetFee .Div (targetFee , big .NewInt (100 ))
11041128
1129+ if collectedL1Fee .Cmp (targetFee ) < 0 {
1130+ return fmt .Errorf ("tx fee exceed collectedL1Fee: targetFee=%v,fee=%v,collectedL1Fee:=%v" , targetFee , fee , collectedL1Fee )
1131+ }
1132+ }
11051133 err := sendTx (r .L1Client , r .cfg .TxFeeLimit , tx )
11061134 if err != nil {
11071135 return err
@@ -1138,7 +1166,7 @@ func sendTx(client iface.Client, txFeeLimit uint64, tx *types.Transaction) error
11381166 return client .SendTransaction (context .Background (), tx )
11391167}
11401168
1141- func (r * Rollup ) ReSubmitTx (resend bool , tx * types.Transaction ) (* types.Transaction , error ) {
1169+ func (r * Rollup ) ReSubmitTx (resend bool , tx * types.Transaction , batchIndex uint64 ) (* types.Transaction , error ) {
11421170 if tx == nil {
11431171 return nil , errors .New ("nil tx" )
11441172 }
@@ -1229,7 +1257,7 @@ func (r *Rollup) ReSubmitTx(resend bool, tx *types.Transaction) (*types.Transact
12291257 return nil , fmt .Errorf ("sign tx error:%w" , err )
12301258 }
12311259 // send tx
1232- err = r .SendTx (newTx )
1260+ err = r .SendTx (newTx , batchIndex )
12331261 if err != nil {
12341262 return nil , fmt .Errorf ("send tx error:%w" , err )
12351263 }
@@ -1335,3 +1363,11 @@ func (r *Rollup) InitFeeMetricsSum() error {
13351363 r .metrics .CollectedL1FeeSum .Add (r .collectedL1FeeSum )
13361364 return nil
13371365}
1366+
1367+ func (r * Rollup ) GetReSubmitBatchIndex (method string , calldta []byte ) uint64 {
1368+ if method == "commitBatch" {
1369+ return utils .ParseBatchIndex (method , calldta )
1370+ } else {
1371+ return 0
1372+ }
1373+ }
0 commit comments