Skip to content

Commit 9c24619

Browse files
committed
Added pooled zkapp commands graphql endpoint
1 parent ce13e06 commit 9c24619

File tree

13 files changed

+233
-74
lines changed

13 files changed

+233
-74
lines changed

node/common/src/service/rpc/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ use node::rpc::{
1212
RpcDiscoveryBoostrapStatsResponse, RpcDiscoveryRoutingTableResponse, RpcGetBlockResponse,
1313
RpcHealthCheckResponse, RpcHeartbeatGetResponse, RpcLedgerAccountsResponse,
1414
RpcLedgerSlimAccountsResponse, RpcMessageProgressResponse, RpcPeersGetResponse,
15-
RpcPooledUserCommandsResponse, RpcReadinessCheckResponse, RpcRequest, RpcStateGetError,
16-
RpcStatusGetResponse, RpcTransactionInjectResponse, RpcTransactionPoolResponse,
17-
RpcTransactionStatusGetResponse, RpcTransitionFrontierUserCommandsResponse,
15+
RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse, RpcReadinessCheckResponse,
16+
RpcRequest, RpcStateGetError, RpcStatusGetResponse, RpcTransactionInjectResponse,
17+
RpcTransactionPoolResponse, RpcTransactionStatusGetResponse,
18+
RpcTransitionFrontierUserCommandsResponse,
1819
};
1920
use serde::{Deserialize, Serialize};
2021

@@ -310,6 +311,10 @@ impl node::rpc_effectful::RpcService for NodeService {
310311
rpc_service_impl!(respond_transaction_status, RpcTransactionStatusGetResponse);
311312
rpc_service_impl!(respond_block_get, RpcGetBlockResponse);
312313
rpc_service_impl!(respond_pooled_user_commands, RpcPooledUserCommandsResponse);
314+
rpc_service_impl!(
315+
respond_pooled_zkapp_commands,
316+
RpcPooledZkappCommandsResponse
317+
);
313318
}
314319

315320
#[cfg(test)]

node/native/src/graphql/mod.rs

Lines changed: 93 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ use block::{GraphQLBlock, GraphQLUserCommands};
22
use juniper::{graphql_value, EmptySubscription, FieldError, GraphQLEnum, RootNode};
33
use ledger::Account;
44
use mina_p2p_messages::v2::{
5-
MinaBaseSignedCommandStableV2, MinaBaseUserCommandStableV2,
5+
conv, MinaBaseSignedCommandStableV2, MinaBaseUserCommandStableV2,
66
MinaBaseZkappCommandTStableV1WireStableV1, TokenIdKeyHash, TransactionHash,
77
};
88
use node::{
99
account::AccountPublicKey,
1010
rpc::{
11-
AccountQuery, GetBlockQuery, PooledUserCommandsQuery, RpcGetBlockResponse,
12-
RpcPooledUserCommandsResponse, RpcRequest, RpcSyncStatsGetResponse,
13-
RpcTransactionInjectResponse,
14-
RpcTransactionStatusGetResponse, SyncStatsQuery,
11+
AccountQuery, GetBlockQuery, PooledCommandsQuery, RpcGetBlockResponse,
12+
RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse, RpcRequest,
13+
RpcSyncStatsGetResponse, RpcTransactionInjectResponse, RpcTransactionStatusGetResponse,
14+
SyncStatsQuery,
1515
},
1616
stats::sync::SyncKind,
1717
};
@@ -23,6 +23,7 @@ use openmina_node_common::rpc::RpcSender;
2323
use std::str::FromStr;
2424
use transaction::GraphQLTransactionStatus;
2525
use warp::{Filter, Rejection, Reply};
26+
use zkapp::GraphQLZkapp;
2627

2728
pub mod account;
2829
pub mod block;
@@ -53,6 +54,8 @@ pub enum ConversionError {
5354
SerdeJson(#[from] serde_json::Error),
5455
#[error("Base58Check: {0}")]
5556
Base58Check(#[from] mina_p2p_messages::b58::FromBase58CheckError),
57+
#[error("Base58 error: {0}")]
58+
Base58(#[from] bs58::decode::Error),
5659
#[error(transparent)]
5760
InvalidDecimalNumber(#[from] mina_p2p_messages::bigint::InvalidDecimalNumber),
5861
#[error("Invalid bigint")]
@@ -322,42 +325,27 @@ impl Query {
322325
}
323326
}
324327

328+
/// Retrieve all the scheduled user commands for a specified sender that
329+
/// the current daemon sees in its transaction pool. All scheduled
330+
/// commands are queried if no sender is specified
331+
///
332+
/// Arguments:
333+
/// - `public_key`: base58 encoded [`AccountPublicKey`]
334+
/// - `hashes`: list of base58 encoded [`TransactionHash`]es
335+
/// - `ids`: list of base64 encoded [`MinaBaseZkappCommandTStableV1WireStableV1`]
325336
async fn pooled_user_commands(
326337
&self,
327338
public_key: Option<String>,
328339
hashes: Option<Vec<String>>,
329340
ids: Option<Vec<String>>,
330341
context: &Context,
331342
) -> juniper::FieldResult<Vec<GraphQLUserCommands>> {
332-
let public_key = match public_key {
333-
Some(public_key) => Some(AccountPublicKey::from_str(&public_key)?),
334-
None => None,
335-
};
336-
337-
let hashes = match hashes {
338-
Some(hashes) => Some(
339-
hashes
340-
.into_iter()
341-
.map(|tx| TransactionHash::from_str(tx.as_str()))
342-
.collect::<Result<Vec<_>, _>>()?,
343-
),
344-
None => None,
345-
};
346-
347-
let ids = match ids {
348-
Some(ids) => Some(
349-
ids.into_iter()
350-
.map(|id| MinaBaseSignedCommandStableV2::from_base64(id.as_str()))
351-
.collect::<Result<Vec<_>, _>>()?,
352-
),
353-
None => None,
354-
};
355-
356-
let query = PooledUserCommandsQuery {
343+
let query = parse_pooled_commands_query(
357344
public_key,
358345
hashes,
359346
ids,
360-
};
347+
MinaBaseSignedCommandStableV2::from_base64,
348+
)?;
361349

362350
let res: RpcPooledUserCommandsResponse = context
363351
.0
@@ -370,6 +358,39 @@ impl Query {
370358
.map(GraphQLUserCommands::try_from)
371359
.collect::<Result<Vec<_>, _>>()?)
372360
}
361+
362+
/// Retrieve all the scheduled zkApp commands for a specified sender that
363+
/// the current daemon sees in its transaction pool. All scheduled
364+
/// commands are queried if no sender is specified
365+
///
366+
/// Arguments:
367+
/// - `public_key`: base58 encoded [`AccountPublicKey`]
368+
/// - `hashes`: list of base58 encoded [`TransactionHash`]es
369+
/// - `ids`: list of base64 encoded [`MinaBaseZkappCommandTStableV1WireStableV1`]
370+
async fn pooled_zkapp_commands(
371+
public_key: Option<String>,
372+
hashes: Option<Vec<String>>,
373+
ids: Option<Vec<String>>,
374+
context: &Context,
375+
) -> juniper::FieldResult<Vec<GraphQLZkapp>> {
376+
let query = parse_pooled_commands_query(
377+
public_key,
378+
hashes,
379+
ids,
380+
MinaBaseZkappCommandTStableV1WireStableV1::from_base64,
381+
)?;
382+
383+
let res: RpcPooledZkappCommandsResponse = context
384+
.0
385+
.oneshot_request(RpcRequest::PooledZkappCommands(query))
386+
.await
387+
.ok_or(Error::StateMachineEmptyResponse)?;
388+
389+
Ok(res
390+
.into_iter()
391+
.map(GraphQLZkapp::try_from)
392+
.collect::<Result<Vec<_>, _>>()?)
393+
}
373394
}
374395

375396
async fn inject_tx<R>(
@@ -540,3 +561,44 @@ pub fn routes(
540561
// )))
541562
// .or(homepage)
542563
// .with(log);
564+
565+
/// Helper function used by [`Query::pooled_user_commands`] and [`Query::pooled_zkapp_commands`] to parse public key, transaction hashes and command ids
566+
fn parse_pooled_commands_query<ID, F>(
567+
public_key: Option<String>,
568+
hashes: Option<Vec<String>>,
569+
ids: Option<Vec<String>>,
570+
id_map_fn: F,
571+
) -> Result<PooledCommandsQuery<ID>, ConversionError>
572+
where
573+
F: Fn(&str) -> Result<ID, conv::Error>,
574+
{
575+
let public_key = match public_key {
576+
Some(public_key) => Some(AccountPublicKey::from_str(&public_key)?),
577+
None => None,
578+
};
579+
580+
let hashes = match hashes {
581+
Some(hashes) => Some(
582+
hashes
583+
.into_iter()
584+
.map(|tx| TransactionHash::from_str(tx.as_str()))
585+
.collect::<Result<Vec<_>, _>>()?,
586+
),
587+
None => None,
588+
};
589+
590+
let ids = match ids {
591+
Some(ids) => Some(
592+
ids.into_iter()
593+
.map(|id| id_map_fn(id.as_str()))
594+
.collect::<Result<Vec<_>, _>>()?,
595+
),
596+
None => None,
597+
};
598+
599+
Ok(PooledCommandsQuery {
600+
public_key,
601+
hashes,
602+
ids,
603+
})
604+
}

node/native/src/graphql/zkapp.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -103,29 +103,37 @@ pub struct InputGraphQLZkappCommand {
103103
pub fee_payer: InputGraphQLFeePayer,
104104
}
105105

106+
impl TryFrom<MinaBaseZkappCommandTStableV1WireStableV1> for GraphQLZkapp {
107+
type Error = ConversionError;
108+
109+
fn try_from(zkapp: MinaBaseZkappCommandTStableV1WireStableV1) -> Result<Self, Self::Error> {
110+
let account_updates = zkapp
111+
.account_updates
112+
.clone()
113+
.into_iter()
114+
.map(|v| v.elt.account_update.try_into())
115+
.collect::<Result<Vec<_>, _>>()?;
116+
117+
Ok(GraphQLZkapp {
118+
hash: zkapp.hash()?.to_string(),
119+
failure_reason: None,
120+
id: zkapp.to_base64()?,
121+
zkapp_command: GraphQLZkappCommand {
122+
memo: zkapp.memo.to_base58check(),
123+
account_updates,
124+
fee_payer: GraphQLFeePayer::from(zkapp.fee_payer),
125+
},
126+
})
127+
}
128+
}
129+
106130
impl TryFrom<MinaBaseUserCommandStableV2> for GraphQLSendZkappResponse {
107131
type Error = ConversionError;
108132
fn try_from(value: MinaBaseUserCommandStableV2) -> Result<Self, Self::Error> {
109133
if let MinaBaseUserCommandStableV2::ZkappCommand(zkapp) = value {
110-
let account_updates = zkapp
111-
.account_updates
112-
.clone()
113-
.into_iter()
114-
.map(|v| v.elt.account_update.try_into())
115-
.collect::<Result<Vec<_>, _>>()?;
116-
let res = GraphQLSendZkappResponse {
117-
zkapp: GraphQLZkapp {
118-
hash: zkapp.hash()?.to_string(),
119-
failure_reason: None,
120-
id: zkapp.to_base64()?,
121-
zkapp_command: GraphQLZkappCommand {
122-
memo: zkapp.memo.to_base58check(),
123-
account_updates,
124-
fee_payer: GraphQLFeePayer::from(zkapp.fee_payer),
125-
},
126-
},
127-
};
128-
Ok(res)
134+
Ok(GraphQLSendZkappResponse {
135+
zkapp: GraphQLZkapp::try_from(zkapp)?,
136+
})
129137
} else {
130138
Err(ConversionError::WrongVariant)
131139
}

node/src/action_kind.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,7 @@ pub enum ActionKind {
495495
RpcP2pConnectionOutgoingSuccess,
496496
RpcPeersGet,
497497
RpcPooledUserCommands,
498+
RpcPooledZkappCommands,
498499
RpcReadinessCheck,
499500
RpcScanStateSummaryGetInit,
500501
RpcScanStateSummaryGetPending,
@@ -535,6 +536,7 @@ pub enum ActionKind {
535536
RpcEffectfulP2pConnectionOutgoingSuccess,
536537
RpcEffectfulPeersGet,
537538
RpcEffectfulPooledUserCommands,
539+
RpcEffectfulPooledZkappCommands,
538540
RpcEffectfulReadinessCheck,
539541
RpcEffectfulScanStateSummaryGetSuccess,
540542
RpcEffectfulSnarkPoolAvailableJobsGet,
@@ -720,7 +722,7 @@ pub enum ActionKind {
720722
}
721723

722724
impl ActionKind {
723-
pub const COUNT: u16 = 610;
725+
pub const COUNT: u16 = 612;
724726
}
725727

726728
impl std::fmt::Display for ActionKind {
@@ -1091,6 +1093,7 @@ impl ActionKindGet for RpcAction {
10911093
Self::TransactionStatusGet { .. } => ActionKind::RpcTransactionStatusGet,
10921094
Self::BlockGet { .. } => ActionKind::RpcBlockGet,
10931095
Self::PooledUserCommands { .. } => ActionKind::RpcPooledUserCommands,
1096+
Self::PooledZkappCommands { .. } => ActionKind::RpcPooledZkappCommands,
10941097
Self::Finish { .. } => ActionKind::RpcFinish,
10951098
}
10961099
}
@@ -1158,6 +1161,7 @@ impl ActionKindGet for RpcEffectfulAction {
11581161
Self::TransactionStatusGet { .. } => ActionKind::RpcEffectfulTransactionStatusGet,
11591162
Self::BlockGet { .. } => ActionKind::RpcEffectfulBlockGet,
11601163
Self::PooledUserCommands { .. } => ActionKind::RpcEffectfulPooledUserCommands,
1164+
Self::PooledZkappCommands { .. } => ActionKind::RpcEffectfulPooledZkappCommands,
11611165
}
11621166
}
11631167
}

node/src/event_source/event.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl std::fmt::Display for Event {
7474
RpcRequest::TransactionStatusGet(..) => write!(f, "TransactionStatusGet"),
7575
RpcRequest::GetBlock(..) => write!(f, "GetBlock"),
7676
RpcRequest::PooledUserCommands(..) => write!(f, "PooledUserCommands"),
77+
RpcRequest::PooledZkappCommands(..) => write!(f, "PooledZkappCommands"),
7778
}
7879
}
7980
Self::ExternalSnarkWorker(event) => {

node/src/event_source/event_source_effects.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ pub fn event_source_effects<S: Service>(store: &mut Store<S>, action: EventSourc
394394
RpcRequest::PooledUserCommands(query) => {
395395
store.dispatch(RpcAction::PooledUserCommands { rpc_id, query });
396396
}
397+
RpcRequest::PooledZkappCommands(query) => {
398+
store.dispatch(RpcAction::PooledZkappCommands { rpc_id, query });
399+
}
397400
},
398401
Event::ExternalSnarkWorker(e) => match e {
399402
ExternalSnarkWorkerEvent::Started => {

node/src/rpc/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use mina_p2p_messages::bigint::BigInt;
1212
use mina_p2p_messages::v2::{
1313
MinaBaseSignedCommandPayloadBodyStableV2, MinaBaseSignedCommandStableV2,
1414
MinaBaseTransactionStatusStableV2, MinaBaseUserCommandStableV2,
15-
MinaTransactionTransactionStableV2, SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse,
16-
StateHash, TransactionHash,
15+
MinaBaseZkappCommandTStableV1WireStableV1, MinaTransactionTransactionStableV2,
16+
SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse, StateHash, TransactionHash,
1717
};
1818
use openmina_core::block::AppliedBlock;
1919
use openmina_core::consensus::ConsensusConstants;
@@ -89,6 +89,7 @@ pub enum RpcRequest {
8989
TransactionStatusGet(MinaBaseUserCommandStableV2),
9090
GetBlock(GetBlockQuery),
9191
PooledUserCommands(PooledUserCommandsQuery),
92+
PooledZkappCommands(PooledZkappsCommandsQuery),
9293
}
9394

9495
pub type MaxLength = u32;
@@ -370,6 +371,7 @@ pub type RpcBestChainResponse = Vec<AppliedBlock>;
370371
pub type RpcConsensusConstantsGetResponse = ConsensusConstants;
371372
pub type RpcTransactionStatusGetResponse = TransactionStatus;
372373
pub type RpcPooledUserCommandsResponse = Vec<MinaBaseSignedCommandStableV2>;
374+
pub type RpcPooledZkappCommandsResponse = Vec<MinaBaseZkappCommandTStableV1WireStableV1>;
373375

374376
#[derive(Serialize, Deserialize, Debug, Clone, strum_macros::Display)]
375377
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
@@ -644,12 +646,15 @@ pub enum GetBlockQuery {
644646
pub type RpcGetBlockResponse = Option<AppliedBlock>;
645647

646648
#[derive(Serialize, Deserialize, Debug, Clone)]
647-
pub struct PooledUserCommandsQuery {
649+
pub struct PooledCommandsQuery<ID> {
648650
pub public_key: Option<AccountPublicKey>,
649651
pub hashes: Option<Vec<TransactionHash>>,
650-
pub ids: Option<Vec<MinaBaseSignedCommandStableV2>>,
652+
pub ids: Option<Vec<ID>>,
651653
}
652654

655+
pub type PooledUserCommandsQuery = PooledCommandsQuery<MinaBaseSignedCommandStableV2>;
656+
pub type PooledZkappsCommandsQuery = PooledCommandsQuery<MinaBaseZkappCommandTStableV1WireStableV1>;
657+
653658
pub mod discovery {
654659
use p2p::{
655660
libp2p_identity::DecodingError, ConnectionType, P2pNetworkKadBucket, P2pNetworkKadDist,

node/src/rpc/rpc_actions.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use crate::p2p::connection::outgoing::{P2pConnectionOutgoingError, P2pConnection
1515
use crate::p2p::connection::P2pConnectionResponse;
1616

1717
use super::{
18-
ActionStatsQuery, GetBlockQuery, PooledUserCommandsQuery, RpcId, RpcScanStateSummaryGetQuery,
19-
RpcScanStateSummaryScanStateJob, SyncStatsQuery,
18+
ActionStatsQuery, GetBlockQuery, PooledUserCommandsQuery, PooledZkappsCommandsQuery, RpcId,
19+
RpcScanStateSummaryGetQuery, RpcScanStateSummaryScanStateJob, SyncStatsQuery,
2020
};
2121

2222
#[derive(Serialize, Deserialize, Debug, Clone, ActionEvent)]
@@ -215,6 +215,10 @@ pub enum RpcAction {
215215
rpc_id: RpcId,
216216
query: PooledUserCommandsQuery,
217217
},
218+
PooledZkappCommands {
219+
rpc_id: RpcId,
220+
query: PooledZkappsCommandsQuery,
221+
},
218222

219223
Finish {
220224
rpc_id: RpcId,
@@ -312,6 +316,7 @@ impl redux::EnablingCondition<crate::State> for RpcAction {
312316
RpcAction::BestChain { .. } => state.transition_frontier.best_tip().is_some(),
313317
RpcAction::TransactionStatusGet { .. } => true,
314318
RpcAction::PooledUserCommands { .. } => true,
319+
RpcAction::PooledZkappCommands { .. } => true,
315320
RpcAction::LedgerAccountsGetInit { .. } => {
316321
state.transition_frontier.best_tip().is_some()
317322
}

0 commit comments

Comments
 (0)