1use crate::AdminApiServer;
4use alloy_primitives::B256;
5use async_trait::async_trait;
6use jsonrpsee::{
7 core::RpcResult,
8 types::{ErrorCode, ErrorObject},
9};
10use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelope;
11use tokio::sync::oneshot;
12
13#[derive(Debug)]
15pub enum SequencerAdminQuery {
16 SequencerActive(oneshot::Sender<bool>),
18 StartSequencer,
20 StopSequencer(oneshot::Sender<B256>),
22 ConductorEnabled(oneshot::Sender<bool>),
24 SetRecoveryMode(bool),
26 OverrideLeader,
28}
29
30#[derive(Debug)]
32pub enum NetworkAdminQuery {
33 PostUnsafePayload {
35 payload: OpExecutionPayloadEnvelope,
37 },
38}
39
40type SequencerQuerySender = tokio::sync::mpsc::Sender<SequencerAdminQuery>;
41type NetworkAdminQuerySender = tokio::sync::mpsc::Sender<NetworkAdminQuery>;
42
43#[derive(Debug)]
45pub struct AdminRpc {
46 pub sequencer_sender: Option<SequencerQuerySender>,
48 pub network_sender: NetworkAdminQuerySender,
50}
51
52#[async_trait]
53impl AdminApiServer for AdminRpc {
54 async fn admin_post_unsafe_payload(
55 &self,
56 payload: OpExecutionPayloadEnvelope,
57 ) -> RpcResult<()> {
58 kona_macros::inc!(gauge, kona_p2p::Metrics::RPC_CALLS, "method" => "admin_postUnsafePayload");
59 self.network_sender
60 .send(NetworkAdminQuery::PostUnsafePayload { payload })
61 .await
62 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))
63 }
64
65 async fn admin_sequencer_active(&self) -> RpcResult<bool> {
66 let Some(ref sequencer_sender) = self.sequencer_sender else {
68 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
69 };
70
71 let (tx, rx) = oneshot::channel();
72 sequencer_sender
73 .send(SequencerAdminQuery::SequencerActive(tx))
74 .await
75 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?;
76 rx.await.map_err(|_| ErrorObject::from(ErrorCode::InternalError))
77 }
78
79 async fn admin_start_sequencer(&self) -> RpcResult<()> {
80 let Some(ref sequencer_sender) = self.sequencer_sender else {
82 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
83 };
84
85 sequencer_sender
86 .send(SequencerAdminQuery::StartSequencer)
87 .await
88 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))
89 }
90
91 async fn admin_stop_sequencer(&self) -> RpcResult<B256> {
92 let Some(ref sequencer_sender) = self.sequencer_sender else {
94 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
95 };
96
97 let (tx, rx) = oneshot::channel();
98
99 sequencer_sender
100 .send(SequencerAdminQuery::StopSequencer(tx))
101 .await
102 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?;
103 rx.await.map_err(|_| ErrorObject::from(ErrorCode::InternalError))
104 }
105
106 async fn admin_conductor_enabled(&self) -> RpcResult<bool> {
107 let Some(ref sequencer_sender) = self.sequencer_sender else {
109 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
110 };
111
112 let (tx, rx) = oneshot::channel();
113
114 sequencer_sender
115 .send(SequencerAdminQuery::ConductorEnabled(tx))
116 .await
117 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?;
118 rx.await.map_err(|_| ErrorObject::from(ErrorCode::InternalError))
119 }
120
121 async fn admin_set_recover_mode(&self, mode: bool) -> RpcResult<()> {
122 let Some(ref sequencer_sender) = self.sequencer_sender else {
124 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
125 };
126
127 sequencer_sender
128 .send(SequencerAdminQuery::SetRecoveryMode(mode))
129 .await
130 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))
131 }
132
133 async fn admin_override_leader(&self) -> RpcResult<()> {
134 let Some(ref sequencer_sender) = self.sequencer_sender else {
136 return Err(ErrorObject::from(ErrorCode::MethodNotFound));
137 };
138
139 sequencer_sender
140 .send(SequencerAdminQuery::OverrideLeader)
141 .await
142 .map_err(|_| ErrorObject::from(ErrorCode::InternalError))
143 }
144}