@@ -11,6 +11,7 @@ import (
1111
1212 espressoClient "github.com/EspressoSystems/espresso-network/sdks/go/client"
1313 espressoLightClient "github.com/EspressoSystems/espresso-network/sdks/go/light-client"
14+ "github.com/ethereum-optimism/optimism/espresso"
1415 opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto"
1516 "github.com/ethereum/go-ethereum/ethclient"
1617 "github.com/ethereum/go-ethereum/log"
@@ -24,6 +25,7 @@ import (
2425 "github.com/ethereum-optimism/optimism/op-node/chaincfg"
2526 "github.com/ethereum-optimism/optimism/op-node/params"
2627 "github.com/ethereum-optimism/optimism/op-node/rollup"
28+ "github.com/ethereum-optimism/optimism/op-node/rollup/derive"
2729 "github.com/ethereum-optimism/optimism/op-service/cliapp"
2830 "github.com/ethereum-optimism/optimism/op-service/dial"
2931 "github.com/ethereum-optimism/optimism/op-service/eth"
@@ -91,7 +93,8 @@ type BatcherService struct {
9193 NotSubmittingOnStart bool
9294
9395 opcrypto.ChainSigner
94- Espresso * espressoClient.MultipleNodesClient
96+ EspressoStreamer espresso.EspressoStreamer [derive.EspressoBatch ]
97+ EspressoClient espressoClient.EspressoClient
9598 EspressoLightClient * espressoLightClient.LightclientCaller
9699 Attestation * nitrite.Result
97100}
@@ -135,53 +138,6 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string,
135138 return err
136139 }
137140
138- if cfg .Espresso .Enabled {
139- bs .EspressoPollInterval = cfg .Espresso .PollInterval
140- client , err := espressoClient .NewMultipleNodesClient (cfg .Espresso .QueryServiceURLs )
141- if err != nil {
142- return fmt .Errorf ("failed to create Espresso client: %w" , err )
143- }
144- bs .Espresso = client
145- espressoLightClient , err := espressoLightClient .NewLightclientCaller (cfg .Espresso .LightClientAddr , bs .L1Client )
146- if err != nil {
147- return fmt .Errorf ("failed to create Espresso light client" )
148- }
149- bs .EspressoLightClient = espressoLightClient
150- bs .UseEspresso = true
151- if err := bs .initKeyPair (); err != nil {
152- return fmt .Errorf ("failed to create key pair for batcher: %w" , err )
153- }
154-
155- // try to generate attestationBytes on public key when start batcher
156- attestationBytes , err := enclave .AttestationWithPublicKey (bs .BatcherPublicKey )
157- if err != nil {
158- bs .Log .Info ("Not running in enclave, skipping attestation" , "info" , err )
159-
160- // Replace ephemeral keys with configured keys, as in devnet they'll be pre-approved for batching
161- privateKey := cfg .Espresso .TestingBatcherPrivateKey
162- if privateKey == nil {
163- return fmt .Errorf ("when not running in enclave, testing batcher private key should be set" )
164- }
165-
166- publicKey := privateKey .Public ()
167- publicKeyECDSA , ok := publicKey .(* ecdsa.PublicKey )
168- if ! ok {
169- return fmt .Errorf ("error casting public key to ECDSA" )
170- }
171-
172- bs .BatcherPrivateKey = privateKey
173- bs .BatcherPublicKey = publicKeyECDSA
174- } else {
175- // output length of attestation
176- bs .Log .Info ("Successfully got attestation. Attestation length" , "length" , len (attestationBytes ))
177- result , err := nitrite .Verify (attestationBytes , nitrite.VerifyOptions {})
178- if err != nil {
179- return fmt .Errorf ("Couldn't verify attestation: %w" , err )
180- }
181- bs .Attestation = result
182- }
183- }
184-
185141 if err := bs .initRollupConfig (ctx ); err != nil {
186142 return fmt .Errorf ("failed to load rollup config: %w" , err )
187143 }
@@ -202,6 +158,9 @@ func (bs *BatcherService) initFromCLIConfig(ctx context.Context, version string,
202158 if err := bs .initPProf (cfg ); err != nil {
203159 return fmt .Errorf ("failed to init profiling: %w" , err )
204160 }
161+ if err := bs .initEspresso (cfg ); err != nil {
162+ return fmt .Errorf ("failed to init Espresso: %w" , err )
163+ }
205164 bs .initDriver (opts ... )
206165 if err := bs .initRPCServer (cfg ); err != nil {
207166 return fmt .Errorf ("failed to start RPC server: %w" , err )
@@ -427,11 +386,10 @@ func (bs *BatcherService) initDriver(opts ...DriverSetupOption) {
427386 ChannelConfig : bs .ChannelConfig ,
428387 AltDA : bs .AltDA ,
429388
430- SequencerAddress : bs .TxManager .From (),
431- ChainSigner : bs .ChainSigner ,
432- Espresso : bs .Espresso ,
433- EspressoLightClient : bs .EspressoLightClient ,
434- Attestation : bs .Attestation ,
389+ EspressoStreamer : bs .EspressoStreamer ,
390+ EspressoClient : bs .EspressoClient ,
391+ ChainSigner : bs .ChainSigner ,
392+ Attestation : bs .Attestation ,
435393 }
436394 for _ , opt := range opts {
437395 opt (& ds )
@@ -579,3 +537,75 @@ func (bs *BatcherService) HTTPEndpoint() string {
579537 }
580538 return "http://" + bs .rpcServer .Endpoint ()
581539}
540+
541+ func (bs * BatcherService ) initEspresso (cfg * CLIConfig ) error {
542+ if ! cfg .Espresso .Enabled {
543+ return nil
544+ }
545+
546+ bs .UseEspresso = true
547+ bs .EspressoPollInterval = cfg .Espresso .PollInterval
548+
549+ client , err := espressoClient .NewMultipleNodesClient (cfg .Espresso .QueryServiceURLs )
550+ if err != nil {
551+ return fmt .Errorf ("failed to create Espresso client: %w" , err )
552+ }
553+ bs .EspressoClient = client
554+
555+ espressoLightClient , err := espressoLightClient .NewLightclientCaller (cfg .Espresso .LightClientAddr , bs .L1Client )
556+ if err != nil {
557+ return fmt .Errorf ("failed to create Espresso light client" )
558+ }
559+ bs .EspressoLightClient = espressoLightClient
560+
561+ if err := bs .initKeyPair (); err != nil {
562+ return fmt .Errorf ("failed to create key pair for batcher: %w" , err )
563+ }
564+
565+ unbufferedStreamer := espresso .NewEspressoStreamer (
566+ bs .RollupConfig .L2ChainID .Uint64 (),
567+ NewAdaptL1BlockRefClient (bs .L1Client ),
568+ client ,
569+ bs .EspressoLightClient ,
570+ bs .Log ,
571+ func (data []byte ) (* derive.EspressoBatch , error ) {
572+ return derive .UnmarshalEspressoTransaction (data , bs .TxManager .From ())
573+ },
574+ 2 * time .Second ,
575+ )
576+ unbufferedStreamer .UseFetchApi = cfg .Espresso .UseFetchAPI
577+
578+ // We wrap the streamer in a BufferedStreamer to reduce impact of streamer resets
579+ bs .EspressoStreamer = espresso .NewBufferedEspressoStreamer (unbufferedStreamer )
580+
581+ // try to generate attestationBytes on public key when start batcher
582+ attestationBytes , err := enclave .AttestationWithPublicKey (bs .BatcherPublicKey )
583+ if err != nil {
584+ bs .Log .Info ("Not running in enclave, skipping attestation" , "info" , err )
585+
586+ // Replace ephemeral keys with configured keys, as in devnet they'll be pre-approved for batching
587+ privateKey := cfg .Espresso .TestingBatcherPrivateKey
588+ if privateKey == nil {
589+ return fmt .Errorf ("when not running in enclave, testing batcher private key should be set" )
590+ }
591+
592+ publicKey := privateKey .Public ()
593+ publicKeyECDSA , ok := publicKey .(* ecdsa.PublicKey )
594+ if ! ok {
595+ return fmt .Errorf ("error casting public key to ECDSA" )
596+ }
597+
598+ bs .BatcherPrivateKey = privateKey
599+ bs .BatcherPublicKey = publicKeyECDSA
600+ } else {
601+ // output length of attestation
602+ bs .Log .Info ("Successfully got attestation. Attestation length" , "length" , len (attestationBytes ))
603+ result , err := nitrite .Verify (attestationBytes , nitrite.VerifyOptions {})
604+ if err != nil {
605+ return fmt .Errorf ("Couldn't verify attestation: %w" , err )
606+ }
607+ bs .Attestation = result
608+ }
609+
610+ return nil
611+ }
0 commit comments