github.com/ethereum-optimism/optimism@v1.7.2/op-node/node/conductor.go (about) 1 package node 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/ethereum-optimism/optimism/op-node/metrics" 9 "github.com/ethereum-optimism/optimism/op-node/rollup/conductor" 10 "github.com/ethereum-optimism/optimism/op-service/dial" 11 "github.com/ethereum-optimism/optimism/op-service/eth" 12 "github.com/ethereum-optimism/optimism/op-service/retry" 13 "github.com/ethereum/go-ethereum/log" 14 15 conductorRpc "github.com/ethereum-optimism/optimism/op-conductor/rpc" 16 ) 17 18 // ConductorClient is a client for the op-conductor RPC service. 19 type ConductorClient struct { 20 cfg *Config 21 metrics *metrics.Metrics 22 log log.Logger 23 apiClient *conductorRpc.APIClient 24 } 25 26 var _ conductor.SequencerConductor = &ConductorClient{} 27 28 // NewConductorClient returns a new conductor client for the op-conductor RPC service. 29 func NewConductorClient(cfg *Config, log log.Logger, metrics *metrics.Metrics) *ConductorClient { 30 return &ConductorClient{cfg: cfg, metrics: metrics, log: log} 31 } 32 33 // Initialize initializes the conductor client. 34 func (c *ConductorClient) initialize() error { 35 if c.apiClient != nil { 36 return nil 37 } 38 conductorRpcClient, err := dial.DialRPCClientWithTimeout(context.Background(), time.Minute*1, c.log, c.cfg.ConductorRpc) 39 if err != nil { 40 return fmt.Errorf("failed to dial conductor RPC: %w", err) 41 } 42 c.apiClient = conductorRpc.NewAPIClient(conductorRpcClient) 43 return nil 44 } 45 46 // Leader returns true if this node is the leader sequencer. 47 func (c *ConductorClient) Leader(ctx context.Context) (bool, error) { 48 if err := c.initialize(); err != nil { 49 return false, err 50 } 51 ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout) 52 defer cancel() 53 54 isLeader, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) { 55 record := c.metrics.RecordRPCClientRequest("conductor_leader") 56 result, err := c.apiClient.Leader(ctx) 57 record(err) 58 return result, err 59 }) 60 return isLeader, err 61 } 62 63 // CommitUnsafePayload commits an unsafe payload to the conductor log. 64 func (c *ConductorClient) CommitUnsafePayload(ctx context.Context, payload *eth.ExecutionPayloadEnvelope) error { 65 if err := c.initialize(); err != nil { 66 return err 67 } 68 ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout) 69 defer cancel() 70 71 // extra bool return value is required for the generic, can be ignored. 72 _, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) { 73 record := c.metrics.RecordRPCClientRequest("conductor_commitUnsafePayload") 74 err := c.apiClient.CommitUnsafePayload(ctx, payload) 75 record(err) 76 return true, err 77 }) 78 return err 79 } 80 81 func (c *ConductorClient) Close() { 82 if c.apiClient == nil { 83 return 84 } 85 c.apiClient.Close() 86 c.apiClient = nil 87 }