@@ -42,6 +42,8 @@ const (
42
42
// defaultDialTimeout is default duration the service will wait on
43
43
// startup to make a connection to either the L1 or L2 backends.
44
44
defaultDialTimeout = 5 * time .Second
45
+ // SYSCOIN
46
+ appendSequencerBatchMethodName = "appendSequencerBatch()"
45
47
)
46
48
47
49
// Main is the entrypoint into the Batch Submitter. This method returns a
@@ -206,6 +208,16 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
206
208
return nil , err
207
209
}
208
210
211
+ // SYSCOIN
212
+ syscoinClient , err := dialSyscoinClientWithTimeout (ctx , cfg .SyscoinRpc )
213
+ if err != nil {
214
+ return nil , err
215
+ }
216
+ podaClient , err := dialPoDAClientWithTimeout (ctx , cfg .PoDARpc )
217
+ if err != nil {
218
+ return nil , err
219
+ }
220
+
209
221
chainID , err := l1Client .ChainID (ctx )
210
222
if err != nil {
211
223
return nil , err
@@ -217,7 +229,6 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
217
229
}
218
230
219
231
log .Info ("starting batch submitter" , "submitter_addr" , addr , "submitter_bal" , sequencerBalance )
220
-
221
232
txManagerConfig := txmgr.Config {
222
233
Log : l ,
223
234
Name : "Batch Submitter" ,
@@ -233,6 +244,8 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
233
244
L1Client : l1Client ,
234
245
L2Client : l2Client ,
235
246
RollupNode : rollupClient ,
247
+ SyscoinNode : syscoinClient ,
248
+ PoDANode : podaClient ,
236
249
MinL1TxSize : cfg .MinL1TxSize ,
237
250
MaxL1TxSize : cfg .MaxL1TxSize ,
238
251
BatchInboxAddress : batchInboxAddress ,
@@ -243,7 +256,6 @@ func NewBatchSubmitter(cfg Config, l log.Logger) (*BatchSubmitter, error) {
243
256
}
244
257
245
258
ctx , cancel := context .WithCancel (context .Background ())
246
-
247
259
return & BatchSubmitter {
248
260
cfg : batcherCfg ,
249
261
addr : addr ,
@@ -338,6 +350,7 @@ mainLoop:
338
350
continue
339
351
}
340
352
// Hand role do-while loop to fully pull all frames out of the channel
353
+ VHs := make ([]common.Hash , 0 )
341
354
for {
342
355
// Collect the output frame
343
356
data := new (bytes.Buffer )
@@ -350,52 +363,74 @@ mainLoop:
350
363
l .log .Error ("error outputting frame" , "err" , err )
351
364
continue mainLoop
352
365
}
353
-
354
- // Query for the submitter's current nonce.
355
- walletAddr := crypto .PubkeyToAddress (l .cfg .PrivKey .PublicKey )
356
- ctx , cancel = context .WithTimeout (l .ctx , time .Second * 10 )
357
- nonce , err := l .cfg .L1Client .NonceAt (ctx , walletAddr , nil )
358
- cancel ()
366
+ // post data.Bytes() into SYS RPC to get version hash
367
+ vh , err := l .cfg .SyscoinNode .CreatePoDA (ctx , data .Bytes ())
359
368
if err != nil {
360
- l .log .Error ("unable to get current nonce " , "err" , err )
369
+ l .log .Error ("unable to create PoDA tx " , "err" , err )
361
370
continue mainLoop
362
371
}
363
-
364
- // Create the transaction
365
- ctx , cancel = context .WithTimeout (l .ctx , time .Second * 10 )
366
- tx , err := l .CraftTx (ctx , data .Bytes (), nonce )
367
- cancel ()
372
+ VHs = append (VHs , vh )
373
+ // If `ch.OutputFrame` returned io.EOF we don't need to submit any more frames for this channel.
374
+ if done {
375
+ break // local do-while loop
376
+ }
377
+ }
378
+ vhBytes := make ([]byte , 0 )
379
+ for _ , vh := range VHs {
380
+ // wait for VH to confirm (MTP > 0)
381
+ podaCreateStatus , err := l .cfg .SyscoinNode .IsPoDAConfirmed (ctx , vh )
368
382
if err != nil {
369
- l .log .Error ("unable to craft tx " , "err" , err )
383
+ l .log .Error ("unable to check for PoDA confirmation " , "err" , err )
370
384
continue mainLoop
371
385
}
372
-
373
- // Construct the a closure that will update the txn with the current gas prices.
374
- updateGasPrice := func (ctx context.Context ) (* types.Transaction , error ) {
375
- l .log .Debug ("updating batch tx gas price" )
376
- return l .UpdateGasPrice (ctx , tx )
377
- }
378
-
379
- // Wait until one of our submitted transactions confirms. If no
380
- // receipt is received it's likely our gas price was too low.
381
- // TODO: does the tx manager nicely replace the tx?
382
- // (submit a new one, that's within the channel timeout, but higher fee than previously submitted tx? Or use a cheap cancel tx?)
383
- ctx , cancel = context .WithTimeout (l .ctx , time .Second * time .Duration (l .cfg .ChannelTimeout ))
384
- receipt , err := l .txMgr .Send (ctx , updateGasPrice , l .cfg .L1Client .SendTransaction )
385
- cancel ()
386
- if err != nil {
387
- l .log .Warn ("unable to publish tx" , "err" , err )
386
+ if podaCreateStatus == false {
387
+ l .log .Error ("PoDA not confirmed" , "err" , err )
388
388
continue mainLoop
389
389
}
390
+ vhBytes = append (vhBytes , vh .Bytes ()... )
391
+ }
392
+ // Query for the submitter's current nonce.
393
+ walletAddr := crypto .PubkeyToAddress (l .cfg .PrivKey .PublicKey )
394
+ ctx , cancel = context .WithTimeout (l .ctx , time .Second * 10 )
395
+ nonce , err := l .cfg .L1Client .NonceAt (ctx , walletAddr , nil )
396
+ cancel ()
397
+ if err != nil {
398
+ l .log .Error ("unable to get current nonce" , "err" , err )
399
+ continue mainLoop
400
+ }
401
+ // Create the transaction
402
+ ctx , cancel = context .WithTimeout (l .ctx , time .Second * 10 )
403
+ // call the appendSequencerBatch in the batch inbox contract, append the function sig infront of array of VH 32 byte array
404
+ sig := crypto .Keccak256 ([]byte (appendSequencerBatchMethodName ))[:4 ]
405
+ calldata := append (sig , vhBytes ... )
406
+ tx , err := l .CraftTx (ctx , calldata , nonce )
407
+ cancel ()
408
+ if err != nil {
409
+ l .log .Error ("unable to craft tx" , "err" , err )
410
+ continue mainLoop
411
+ }
390
412
391
- // The transaction was successfully submitted.
392
- l .log .Info ("tx successfully published" , "tx_hash" , receipt .TxHash , "channel_id" , l .ch .ID ())
413
+ // Construct the a closure that will update the txn with the current gas prices.
414
+ updateGasPrice := func (ctx context.Context ) (* types.Transaction , error ) {
415
+ l .log .Debug ("updating batch tx gas price" )
416
+ return l .UpdateGasPrice (ctx , tx , uint64 (len (VHs ))* 1800 )
417
+ }
393
418
394
- // If `ch.OutputFrame` returned io.EOF we don't need to submit any more frames for this channel.
395
- if done {
396
- break // local do-while loop
397
- }
419
+ // Wait until one of our submitted transactions confirms. If no
420
+ // receipt is received it's likely our gas price was too low.
421
+ // TODO: does the tx manager nicely replace the tx?
422
+ // (submit a new one, that's within the channel timeout, but higher fee than previously submitted tx? Or use a cheap cancel tx?)
423
+ ctx , cancel = context .WithTimeout (l .ctx , time .Second * time .Duration (l .cfg .ChannelTimeout ))
424
+ receipt , err := l .txMgr .Send (ctx , updateGasPrice , l .cfg .L1Client .SendTransaction )
425
+ cancel ()
426
+ if err != nil {
427
+ l .log .Warn ("unable to publish tx" , "err" , err )
428
+ continue mainLoop
398
429
}
430
+
431
+ // The transaction was successfully submitted.
432
+ l .log .Info ("tx successfully published" , "tx_hash" , receipt .TxHash , "channel_id" , l .ch .ID ())
433
+
399
434
// TODO: if we exit to the mainLoop early on an error,
400
435
// it would be nice if we can determine which blocks are still readable from the partially submitted data.
401
436
// We can open a channel-in-reader, parse the data up to which we managed to submit it,
@@ -423,7 +458,6 @@ func (l *BatchSubmitter) CraftTx(ctx context.Context, data []byte, nonce uint64)
423
458
}
424
459
425
460
gasFeeCap := txmgr .CalcGasFeeCap (head .BaseFee , gasTipCap )
426
-
427
461
rawTx := & types.DynamicFeeTx {
428
462
ChainID : l .cfg .ChainID ,
429
463
Nonce : nonce ,
@@ -447,7 +481,7 @@ func (l *BatchSubmitter) CraftTx(ctx context.Context, data []byte, nonce uint64)
447
481
// updated gas prices sampled from the existing network conditions.
448
482
//
449
483
// NOTE: Thie method SHOULD NOT publish the resulting transaction.
450
- func (l * BatchSubmitter ) UpdateGasPrice (ctx context.Context , tx * types.Transaction ) (* types.Transaction , error ) {
484
+ func (l * BatchSubmitter ) UpdateGasPrice (ctx context.Context , tx * types.Transaction , additionalGas uint64 ) (* types.Transaction , error ) {
451
485
gasTipCap , err := l .cfg .L1Client .SuggestGasTipCap (ctx )
452
486
if err != nil {
453
487
return nil , err
@@ -466,7 +500,7 @@ func (l *BatchSubmitter) UpdateGasPrice(ctx context.Context, tx *types.Transacti
466
500
To : tx .To (),
467
501
GasTipCap : gasTipCap ,
468
502
GasFeeCap : gasFeeCap ,
469
- Gas : tx .Gas (),
503
+ Gas : tx .Gas () + additionalGas ,
470
504
Data : tx .Data (),
471
505
}
472
506
@@ -506,6 +540,33 @@ func dialRollupClientWithTimeout(ctx context.Context, url string) (*sources.Roll
506
540
return sources .NewRollupClient (client .NewBaseRPCClient (rpcCl )), nil
507
541
}
508
542
543
+ // SYSCOIN
544
+ // dialRollupClientWithTimeout attempts to dial the RPC provider using the provided
545
+ // URL. If the dial doesn't complete within defaultDialTimeout seconds, this
546
+ // method will return an error.
547
+ func dialSyscoinClientWithTimeout (ctx context.Context , url string ) (* sources.SyscoinClient , error ) {
548
+ ctxt , cancel := context .WithTimeout (ctx , defaultDialTimeout )
549
+ defer cancel ()
550
+
551
+ rpcCl , err := rpc .DialContext (ctxt , url )
552
+ if err != nil {
553
+ return nil , err
554
+ }
555
+
556
+ return sources .NewSyscoinClient (client .NewBaseRPCClient (rpcCl )), nil
557
+ }
558
+ func dialPoDAClientWithTimeout (ctx context.Context , url string ) (* sources.PoDAClient , error ) {
559
+ ctxt , cancel := context .WithTimeout (ctx , defaultDialTimeout )
560
+ defer cancel ()
561
+
562
+ rpcCl , err := rpc .DialContext (ctxt , url )
563
+ if err != nil {
564
+ return nil , err
565
+ }
566
+
567
+ return sources .NewPoDAClient (client .NewBaseRPCClient (rpcCl )), nil
568
+ }
569
+
509
570
// parseAddress parses an ETH address from a hex string. This method will fail if
510
571
// the address is not a valid hexadecimal address.
511
572
func parseAddress (address string ) (common.Address , error ) {
0 commit comments