Skip to content

Commit 2dd3d26

Browse files
authored
Merge pull request #1127 from 0xMimir/feat/graphql-snark-pool
Snark pool graphql routes
2 parents f3ac44a + 5b5fc2c commit 2dd3d26

File tree

16 files changed

+314
-11
lines changed

16 files changed

+314
-11
lines changed

core/src/snark/snark.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ impl From<TransactionSnarkWorkTStableV2> for Snark {
7777
}
7878
}
7979

80+
impl From<Snark> for TransactionSnarkWorkTStableV2 {
81+
fn from(value: Snark) -> Self {
82+
Self {
83+
fee: value.fee,
84+
proofs: value.proofs.as_ref().clone(),
85+
prover: value.snarker,
86+
}
87+
}
88+
}
89+
8090
impl From<NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1> for Snark {
8191
fn from(value: NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1) -> Self {
8292
Self {

core/src/snark/snark_job_id.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ mod tests {
145145

146146
#[test]
147147
fn test_snark_job_id_to_string_from_string() {
148-
let s = "jw9nPCs68UNaKaLZwV6QzdswKWomwQxvTgrpmKWmnFJyswnrn4N:jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc->jwiLuRrEqNgASgXEqibGs4VqKwSwiuFEtuPD53v8hiTtVuLfmTr:jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc";
148+
let s = "jw9nPCs68UNaKaLZwV6QzdswKWomwQxvTgrpmKWmnFJyswnrn4N_jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc-jwiLuRrEqNgASgXEqibGs4VqKwSwiuFEtuPD53v8hiTtVuLfmTr_jwhHYWzvJG8esmqtYXbUZy3UGbLSjhKvn1FSxBGL1JDFHqbHMJc";
149149
let decoded = SnarkJobId::from_str(s).unwrap();
150150
assert_eq!(decoded.to_string(), s);
151151
}

ledger/src/scan_state/scan_state.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ use super::{
5959

6060
pub use super::parallel_scan::base::Job as JobValueBase;
6161
pub use super::parallel_scan::merge::Job as JobValueMerge;
62-
pub use super::parallel_scan::{JobValue, JobValueWithIndex, SpacePartition};
62+
pub use super::parallel_scan::{
63+
AvailableJob as ParallelScanAvailableJob, JobValue, JobValueWithIndex, SpacePartition,
64+
};
6365

6466
// type LedgerProof = LedgerProofProdStableV2;
6567
// type LedgerProofWithSokMessage = TransactionSnarkScanStateLedgerProofWithSokMessageStableV2;

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use node::rpc::{
1313
RpcGetBlockResponse, RpcHealthCheckResponse, RpcHeartbeatGetResponse,
1414
RpcLedgerAccountsResponse, RpcLedgerSlimAccountsResponse, RpcMessageProgressResponse,
1515
RpcPeersGetResponse, RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse,
16-
RpcReadinessCheckResponse, RpcRequest, RpcStateGetError, RpcStatusGetResponse,
16+
RpcReadinessCheckResponse, RpcRequest, RpcSnarkPoolCompletedJobsResponse,
17+
RpcSnarkPoolPendingJobsGetResponse, RpcStateGetError, RpcStatusGetResponse,
1718
RpcTransactionInjectResponse, RpcTransactionPoolResponse, RpcTransactionStatusGetResponse,
1819
RpcTransitionFrontierUserCommandsResponse,
1920
};
@@ -272,6 +273,14 @@ impl node::rpc_effectful::RpcService for NodeService {
272273
);
273274
rpc_service_impl!(respond_snark_pool_get, RpcSnarkPoolGetResponse);
274275
rpc_service_impl!(respond_snark_pool_job_get, RpcSnarkPoolJobGetResponse);
276+
rpc_service_impl!(
277+
respond_snark_pool_completed_jobs_get,
278+
RpcSnarkPoolCompletedJobsResponse
279+
);
280+
rpc_service_impl!(
281+
respond_snark_pool_pending_jobs_get,
282+
RpcSnarkPoolPendingJobsGetResponse
283+
);
275284
rpc_service_impl!(respond_snarker_job_commit, RpcSnarkerJobCommitResponse);
276285
rpc_service_impl!(
277286
respond_snarker_job_spec,

node/native/src/graphql/mod.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use block::{GraphQLBlock, GraphQLUserCommands};
1+
use block::{GraphQLBlock, GraphQLSnarkJob, GraphQLUserCommands};
22
use juniper::{graphql_value, EmptySubscription, FieldError, GraphQLEnum, RootNode};
33
use ledger::Account;
44
use mina_p2p_messages::v2::{
@@ -10,8 +10,9 @@ use node::{
1010
rpc::{
1111
AccountQuery, GetBlockQuery, PooledCommandsQuery, RpcGenesisBlockResponse,
1212
RpcGetBlockResponse, RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse,
13-
RpcRequest, RpcSyncStatsGetResponse, RpcTransactionInjectResponse,
14-
RpcTransactionStatusGetResponse, SyncStatsQuery,
13+
RpcRequest, RpcSnarkPoolCompletedJobsResponse, RpcSnarkPoolPendingJobsGetResponse,
14+
RpcSyncStatsGetResponse, RpcTransactionInjectResponse, RpcTransactionStatusGetResponse,
15+
SyncStatsQuery,
1516
},
1617
stats::sync::SyncKind,
1718
};
@@ -20,6 +21,7 @@ use openmina_core::{
2021
block::AppliedBlock, consensus::ConsensusConstants, constants::constraint_constants,
2122
};
2223
use openmina_node_common::rpc::RpcSender;
24+
use snark::GraphQLPendingSnarkWork;
2325
use std::str::FromStr;
2426
use transaction::GraphQLTransactionStatus;
2527
use warp::{Filter, Rejection, Reply};
@@ -28,6 +30,7 @@ use zkapp::GraphQLZkapp;
2830
pub mod account;
2931
pub mod block;
3032
pub mod constants;
33+
pub mod snark;
3134
pub mod transaction;
3235
pub mod user_command;
3336
pub mod zkapp;
@@ -405,6 +408,31 @@ impl Query {
405408
just_emitted_a_proof: false,
406409
})?)
407410
}
411+
412+
async fn snark_pool(context: &Context) -> juniper::FieldResult<Vec<GraphQLSnarkJob>> {
413+
let jobs: RpcSnarkPoolCompletedJobsResponse = context
414+
.0
415+
.oneshot_request(RpcRequest::SnarkPoolCompletedJobsGet)
416+
.await
417+
.ok_or(Error::StateMachineEmptyResponse)?;
418+
419+
Ok(jobs.iter().map(GraphQLSnarkJob::from).collect())
420+
}
421+
422+
async fn pending_snark_work(
423+
context: &Context,
424+
) -> juniper::FieldResult<Vec<GraphQLPendingSnarkWork>> {
425+
let jobs: RpcSnarkPoolPendingJobsGetResponse = context
426+
.0
427+
.oneshot_request(RpcRequest::SnarkPoolPendingJobsGet)
428+
.await
429+
.ok_or(Error::StateMachineEmptyResponse)?;
430+
431+
Ok(jobs
432+
.into_iter()
433+
.map(GraphQLPendingSnarkWork::try_from)
434+
.collect::<Result<Vec<_>, _>>()?)
435+
}
408436
}
409437

410438
async fn inject_tx<R>(

node/native/src/graphql/snark.rs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
use juniper::GraphQLObject;
2+
use ledger::scan_state::scan_state::{AvailableJobMessage, ParallelScanAvailableJob};
3+
use mina_p2p_messages::v2::{
4+
MinaBaseFeeExcessStableV1, MinaStateBlockchainStateValueStableV2SignedAmount,
5+
TransactionSnarkScanStateTransactionWithWitnessStableV2, TransactionSnarkStableV2,
6+
};
7+
use node::snark_pool::JobState;
8+
9+
use super::ConversionError;
10+
11+
#[derive(GraphQLObject, Debug)]
12+
#[graphql(description = "A Mina block")]
13+
pub struct GraphQLPendingSnarkWork {
14+
/// Work bundle with one or two snark work
15+
pub work_bundle: Vec<GraphQLWorkDescription>,
16+
}
17+
18+
#[derive(GraphQLObject, Debug)]
19+
pub struct GraphQLWorkDescription {
20+
/// Base58Check-encoded hash of the source first-pass ledger
21+
pub source_first_pass_ledger_hash: String,
22+
/// Base58Check-encoded hash of the target first-pass ledger
23+
pub target_first_pass_ledger_hash: String,
24+
/// Base58Check-encoded hash of the source second-pass ledger
25+
pub source_second_pass_ledger_hash: String,
26+
/// Base58Check-encoded hash of the target second-pass ledger
27+
pub target_second_pass_ledger_hash: String,
28+
/// Total transaction fee that is not accounted for in the transition from source ledger to target ledger
29+
pub fee_excess: GraphQLFeeExcesses,
30+
/// Increase/Decrease in total supply
31+
pub supply_change: GraphQLSupplyChange,
32+
/// Increase in total supply
33+
pub supply_increase: String,
34+
/// Unique identifier for a snark work
35+
pub work_id: i32,
36+
}
37+
38+
#[derive(GraphQLObject, Debug)]
39+
pub struct GraphQLFeeExcesses {
40+
pub fee_token_left: String,
41+
pub fee_excess_left: GraphQLFeeExcess,
42+
pub fee_token_right: String,
43+
pub fee_excess_right: GraphQLFeeExcess,
44+
}
45+
46+
#[derive(GraphQLObject, Debug)]
47+
pub struct GraphQLFeeExcess {
48+
pub fee_magnitude: String,
49+
pub sign: String,
50+
}
51+
52+
#[derive(GraphQLObject, Debug)]
53+
pub struct GraphQLSupplyChange {
54+
pub amount_magnitude: String,
55+
pub sign: String,
56+
}
57+
58+
impl TryFrom<JobState> for GraphQLPendingSnarkWork {
59+
type Error = ConversionError;
60+
61+
fn try_from(value: JobState) -> Result<Self, Self::Error> {
62+
let mut work_bundle = Vec::new();
63+
64+
for job in value.job.into_iter() {
65+
work_bundle.push(GraphQLWorkDescription::try_from(job)?);
66+
}
67+
68+
Ok(Self { work_bundle })
69+
}
70+
}
71+
72+
impl TryFrom<AvailableJobMessage> for GraphQLWorkDescription {
73+
type Error = ConversionError;
74+
75+
fn try_from(value: AvailableJobMessage) -> Result<Self, Self::Error> {
76+
match value {
77+
ParallelScanAvailableJob::Base(base) => GraphQLWorkDescription::try_from(base),
78+
ParallelScanAvailableJob::Merge { left, .. } => {
79+
GraphQLWorkDescription::try_from(left.0 .0)
80+
}
81+
}
82+
}
83+
}
84+
85+
impl TryFrom<MinaBaseFeeExcessStableV1> for GraphQLFeeExcesses {
86+
type Error = ConversionError;
87+
88+
fn try_from(value: MinaBaseFeeExcessStableV1) -> Result<Self, Self::Error> {
89+
Ok(Self {
90+
fee_token_left: value.0.token.to_string(),
91+
fee_excess_left: GraphQLFeeExcess {
92+
fee_magnitude: value.0.amount.magnitude.to_string(),
93+
sign: value.0.amount.sgn.to_string(),
94+
},
95+
fee_token_right: value.1.token.to_string(),
96+
fee_excess_right: GraphQLFeeExcess {
97+
fee_magnitude: value.1.amount.magnitude.to_string(),
98+
sign: value.1.amount.sgn.to_string(),
99+
},
100+
})
101+
}
102+
}
103+
104+
impl TryFrom<MinaStateBlockchainStateValueStableV2SignedAmount> for GraphQLSupplyChange {
105+
type Error = ConversionError;
106+
107+
fn try_from(
108+
value: MinaStateBlockchainStateValueStableV2SignedAmount,
109+
) -> Result<Self, Self::Error> {
110+
Ok(Self {
111+
amount_magnitude: value.magnitude.to_string(),
112+
sign: value.sgn.to_string(),
113+
})
114+
}
115+
}
116+
117+
impl TryFrom<TransactionSnarkScanStateTransactionWithWitnessStableV2> for GraphQLWorkDescription {
118+
type Error = ConversionError;
119+
120+
fn try_from(
121+
value: TransactionSnarkScanStateTransactionWithWitnessStableV2,
122+
) -> Result<Self, Self::Error> {
123+
Ok(Self {
124+
source_first_pass_ledger_hash: value.statement.source.first_pass_ledger.to_string(),
125+
target_first_pass_ledger_hash: value.statement.target.first_pass_ledger.to_string(),
126+
source_second_pass_ledger_hash: value.statement.source.second_pass_ledger.to_string(),
127+
target_second_pass_ledger_hash: value.statement.target.second_pass_ledger.to_string(),
128+
fee_excess: GraphQLFeeExcesses::try_from(value.statement.fee_excess.clone())?,
129+
supply_change: GraphQLSupplyChange::try_from(value.statement.supply_increase.clone())?,
130+
supply_increase: value.statement.supply_increase.magnitude.to_string(),
131+
work_id: 0,
132+
})
133+
}
134+
}
135+
136+
impl TryFrom<TransactionSnarkStableV2> for GraphQLWorkDescription {
137+
type Error = ConversionError;
138+
139+
fn try_from(value: TransactionSnarkStableV2) -> Result<Self, Self::Error> {
140+
Ok(Self {
141+
source_first_pass_ledger_hash: value.statement.source.first_pass_ledger.to_string(),
142+
target_first_pass_ledger_hash: value.statement.target.first_pass_ledger.to_string(),
143+
source_second_pass_ledger_hash: value.statement.source.second_pass_ledger.to_string(),
144+
target_second_pass_ledger_hash: value.statement.target.second_pass_ledger.to_string(),
145+
fee_excess: GraphQLFeeExcesses::try_from(value.statement.fee_excess.clone())?,
146+
supply_change: GraphQLSupplyChange::try_from(value.statement.supply_increase.clone())?,
147+
supply_increase: value.statement.supply_increase.magnitude.to_string(),
148+
work_id: 0,
149+
})
150+
}
151+
}

node/src/action_kind.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,9 @@ pub enum ActionKind {
503503
RpcScanStateSummaryGetSuccess,
504504
RpcScanStateSummaryLedgerGetInit,
505505
RpcSnarkPoolAvailableJobsGet,
506+
RpcSnarkPoolCompletedJobsGet,
506507
RpcSnarkPoolJobGet,
508+
RpcSnarkPoolPendingJobsGet,
507509
RpcSnarkerConfigGet,
508510
RpcSnarkerJobCommit,
509511
RpcSnarkerJobSpec,
@@ -542,7 +544,9 @@ pub enum ActionKind {
542544
RpcEffectfulReadinessCheck,
543545
RpcEffectfulScanStateSummaryGetSuccess,
544546
RpcEffectfulSnarkPoolAvailableJobsGet,
547+
RpcEffectfulSnarkPoolCompletedJobsGet,
545548
RpcEffectfulSnarkPoolJobGet,
549+
RpcEffectfulSnarkPoolPendingJobsGet,
546550
RpcEffectfulSnarkerConfigGet,
547551
RpcEffectfulSnarkerJobCommit,
548552
RpcEffectfulSnarkerJobSpec,
@@ -724,7 +728,7 @@ pub enum ActionKind {
724728
}
725729

726730
impl ActionKind {
727-
pub const COUNT: u16 = 614;
731+
pub const COUNT: u16 = 618;
728732
}
729733

730734
impl std::fmt::Display for ActionKind {
@@ -1070,6 +1074,8 @@ impl ActionKindGet for RpcAction {
10701074
Self::ScanStateSummaryGetSuccess { .. } => ActionKind::RpcScanStateSummaryGetSuccess,
10711075
Self::SnarkPoolAvailableJobsGet { .. } => ActionKind::RpcSnarkPoolAvailableJobsGet,
10721076
Self::SnarkPoolJobGet { .. } => ActionKind::RpcSnarkPoolJobGet,
1077+
Self::SnarkPoolCompletedJobsGet { .. } => ActionKind::RpcSnarkPoolCompletedJobsGet,
1078+
Self::SnarkPoolPendingJobsGet { .. } => ActionKind::RpcSnarkPoolPendingJobsGet,
10731079
Self::SnarkerConfigGet { .. } => ActionKind::RpcSnarkerConfigGet,
10741080
Self::SnarkerJobCommit { .. } => ActionKind::RpcSnarkerJobCommit,
10751081
Self::SnarkerJobSpec { .. } => ActionKind::RpcSnarkerJobSpec,
@@ -1135,6 +1141,10 @@ impl ActionKindGet for RpcEffectfulAction {
11351141
ActionKind::RpcEffectfulSnarkPoolAvailableJobsGet
11361142
}
11371143
Self::SnarkPoolJobGet { .. } => ActionKind::RpcEffectfulSnarkPoolJobGet,
1144+
Self::SnarkPoolCompletedJobsGet { .. } => {
1145+
ActionKind::RpcEffectfulSnarkPoolCompletedJobsGet
1146+
}
1147+
Self::SnarkPoolPendingJobsGet { .. } => ActionKind::RpcEffectfulSnarkPoolPendingJobsGet,
11381148
Self::SnarkerConfigGet { .. } => ActionKind::RpcEffectfulSnarkerConfigGet,
11391149
Self::SnarkerJobCommit { .. } => ActionKind::RpcEffectfulSnarkerJobCommit,
11401150
Self::SnarkerJobSpec { .. } => ActionKind::RpcEffectfulSnarkerJobSpec,

node/src/event_source/event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ impl std::fmt::Display for Event {
5151
RpcRequest::SnarkPoolJobGet { job_id } => {
5252
write!(f, "SnarkPoolJobGet, {job_id}")
5353
}
54+
RpcRequest::SnarkPoolCompletedJobsGet => write!(f, "SnarkPoolCompletedJobsGet"),
55+
RpcRequest::SnarkPoolPendingJobsGet => write!(f, "SnarkPoolPendingJobsGet"),
5456
RpcRequest::SnarkerConfig => write!(f, "SnarkerConfig"),
5557
RpcRequest::SnarkerJobCommit { job_id } => {
5658
write!(f, "SnarkerJobCommit, {job_id}")

node/src/event_source/event_source_effects.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ pub fn event_source_effects<S: Service>(store: &mut Store<S>, action: EventSourc
340340
RpcRequest::SnarkPoolJobGet { job_id } => {
341341
store.dispatch(RpcAction::SnarkPoolJobGet { rpc_id, job_id });
342342
}
343+
RpcRequest::SnarkPoolCompletedJobsGet => {
344+
store.dispatch(RpcAction::SnarkPoolCompletedJobsGet { rpc_id });
345+
}
346+
RpcRequest::SnarkPoolPendingJobsGet => {
347+
store.dispatch(RpcAction::SnarkPoolPendingJobsGet { rpc_id });
348+
}
343349
RpcRequest::SnarkerConfig => {
344350
store.dispatch(RpcAction::SnarkerConfigGet { rpc_id });
345351
}

node/src/rpc/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use mina_p2p_messages::v2::{
1414
MinaBaseTransactionStatusStableV2, MinaBaseUserCommandStableV2,
1515
MinaBaseZkappCommandTStableV1WireStableV1, MinaTransactionTransactionStableV2,
1616
SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse, StateHash, TransactionHash,
17+
TransactionSnarkWorkTStableV2,
1718
};
1819
use openmina_core::block::{AppliedBlock, ArcBlockWithHash};
1920
use openmina_core::consensus::ConsensusConstants;
@@ -50,7 +51,7 @@ use crate::p2p::connection::incoming::P2pConnectionIncomingInitOpts;
5051
use crate::p2p::connection::outgoing::P2pConnectionOutgoingInitOpts;
5152
use crate::p2p::PeerId;
5253
use crate::service::Queues;
53-
use crate::snark_pool::{JobCommitment, JobSummary};
54+
use crate::snark_pool::{JobCommitment, JobState, JobSummary};
5455
use crate::stats::actions::{ActionStatsForBlock, ActionStatsSnapshot};
5556
use crate::stats::block_producer::{
5657
BlockProductionAttempt, BlockProductionAttemptWonSlot, VrfEvaluatorStats,
@@ -72,6 +73,8 @@ pub enum RpcRequest {
7273
ScanStateSummaryGet(RpcScanStateSummaryGetQuery),
7374
SnarkPoolGet,
7475
SnarkPoolJobGet { job_id: SnarkJobId },
76+
SnarkPoolCompletedJobsGet,
77+
SnarkPoolPendingJobsGet,
7578
SnarkerConfig,
7679
SnarkerJobCommit { job_id: SnarkJobId },
7780
SnarkerJobSpec { job_id: SnarkJobId },
@@ -362,6 +365,8 @@ pub type RpcPeersGetResponse = Vec<RpcPeerInfo>;
362365
pub type RpcP2pConnectionOutgoingResponse = Result<(), String>;
363366
pub type RpcScanStateSummaryGetResponse = Result<RpcScanStateSummary, String>;
364367
pub type RpcSnarkPoolGetResponse = Vec<RpcSnarkPoolJobSummary>;
368+
pub type RpcSnarkPoolCompletedJobsResponse = Vec<TransactionSnarkWorkTStableV2>;
369+
pub type RpcSnarkPoolPendingJobsGetResponse = Vec<JobState>;
365370
pub type RpcSnarkPoolJobGetResponse = Option<RpcSnarkPoolJobFull>;
366371
pub type RpcSnarkerConfigGetResponse = Option<RpcSnarkerConfig>;
367372
pub type RpcTransactionPoolResponse = Vec<ValidCommandWithHash>;

0 commit comments

Comments
 (0)