Skip to content

Commit d592c3a

Browse files
author
Adrian Nagy
committed
feat(grapqhl): Expand accounts with delegators + cleaned up account loading
1 parent 34b5d78 commit d592c3a

File tree

19 files changed

+259
-92
lines changed

19 files changed

+259
-92
lines changed

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ pub mod transition_frontier;
99

1010
use node::rpc::{
1111
RpcBestChainResponse, RpcBlockProducerStatsGetResponse, RpcConsensusConstantsGetResponse,
12-
RpcConsensusTimeGetResponse, RpcDiscoveryBoostrapStatsResponse, RpcDiscoveryRoutingTableResponse,
13-
RpcGenesisBlockResponse, RpcGetBlockResponse, RpcHealthCheckResponse, RpcHeartbeatGetResponse,
14-
RpcLedgerAccountsResponse, RpcLedgerSlimAccountsResponse, RpcMessageProgressResponse,
15-
RpcPeersGetResponse, RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse,
16-
RpcReadinessCheckResponse, RpcRequest, RpcSnarkPoolCompletedJobsResponse,
17-
RpcSnarkPoolPendingJobsGetResponse, RpcStateGetError, RpcStatusGetResponse,
18-
RpcTransactionInjectResponse, RpcTransactionPoolResponse, RpcTransactionStatusGetResponse,
19-
RpcTransitionFrontierUserCommandsResponse, RpcLedgerStatusGetResponse,
12+
RpcConsensusTimeGetResponse, RpcDiscoveryBoostrapStatsResponse,
13+
RpcDiscoveryRoutingTableResponse, RpcGenesisBlockResponse, RpcGetBlockResponse,
14+
RpcHealthCheckResponse, RpcHeartbeatGetResponse, RpcLedgerAccountDelegatorsGetResponse,
15+
RpcLedgerAccountsResponse, RpcLedgerSlimAccountsResponse, RpcLedgerStatusGetResponse,
16+
RpcMessageProgressResponse, RpcPeersGetResponse, RpcPooledUserCommandsResponse,
17+
RpcPooledZkappCommandsResponse, RpcReadinessCheckResponse, RpcRequest,
18+
RpcSnarkPoolCompletedJobsResponse, RpcSnarkPoolPendingJobsGetResponse, RpcStateGetError,
19+
RpcStatusGetResponse, RpcTransactionInjectResponse, RpcTransactionPoolResponse,
20+
RpcTransactionStatusGetResponse, RpcTransitionFrontierUserCommandsResponse,
2021
};
2122
use serde::{Deserialize, Serialize};
2223

@@ -327,6 +328,10 @@ impl node::rpc_effectful::RpcService for NodeService {
327328
rpc_service_impl!(respond_genesis_block, RpcGenesisBlockResponse);
328329
rpc_service_impl!(respond_consensus_time_get, RpcConsensusTimeGetResponse);
329330
rpc_service_impl!(respond_ledger_status_get, RpcLedgerStatusGetResponse);
331+
rpc_service_impl!(
332+
respond_ledger_account_delegators_get,
333+
RpcLedgerAccountDelegatorsGetResponse
334+
);
330335
}
331336

332337
#[cfg(test)]

node/native/src/graphql/account.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,32 +153,32 @@ impl GraphQLAccount {
153153
// A delegate always has the default token id
154154
let delegate_id = AccountId::new_with_default_token(delegate_key.clone());
155155
// Use the loader to fetch the delegate account
156-
let delegate_result =
157-
context
158-
.account_loader
159-
.try_load(delegate_id)
160-
.await
161-
.map_err(|e| {
162-
juniper::FieldError::new(
163-
format!("Failed to load delegate account: {}", e),
164-
juniper::Value::null(),
165-
)
166-
})?;
167-
168-
// Handle the result
169-
match delegate_result {
170-
Ok(account) => Ok(Some(Box::new(account))),
171-
Err(e) => Err(juniper::FieldError::new(
172-
format!("Error loading delegate account: {}", e),
173-
juniper::Value::null(),
174-
)),
175-
}
156+
Ok(context.load_account(delegate_id).await.map(Box::new))
176157
} else {
177158
// No delegate
178159
Ok(None)
179160
}
180161
}
181162

163+
pub async fn delegators(&self, context: &Context) -> FieldResult<Vec<GraphQLAccount>> {
164+
if let Some(best_tip) = context.get_or_fetch_best_tip().await {
165+
let staking_ledger_hash = best_tip.staking_epoch_ledger_hash();
166+
167+
let id = self.inner.id();
168+
let delegators = context
169+
.fetch_delegators(staking_ledger_hash.clone(), id.clone())
170+
.await
171+
.unwrap_or_default();
172+
173+
Ok(delegators
174+
.into_iter()
175+
.map(GraphQLAccount::try_from)
176+
.collect::<Result<Vec<_>, _>>()?)
177+
} else {
178+
Ok(vec![])
179+
}
180+
}
181+
182182
fn voting_for(&self) -> &str {
183183
&self.voting_for
184184
}

node/native/src/graphql/block.rs

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -42,47 +42,24 @@ impl GraphQLBlock {
4242

4343
async fn creator_account(&self, context: &Context) -> FieldResult<Box<GraphQLAccount>> {
4444
let account_id = AccountId::new_with_default_token(self.creator_account_key.clone());
45-
let account_result = context
46-
.account_loader
47-
.try_load(account_id)
48-
.await
49-
.map_err(|e| {
50-
juniper::FieldError::new(
51-
format!("Failed to load delegate account: {}", e),
52-
juniper::Value::null(),
53-
)
54-
})?;
55-
56-
// Handle the result
57-
match account_result {
58-
Ok(account) => Ok(Box::new(account)),
59-
Err(e) => Err(juniper::FieldError::new(
60-
format!("Error loading delegate account: {}", e),
45+
if let Some(account) = context.load_account(account_id).await {
46+
Ok(Box::new(account))
47+
} else {
48+
Err(juniper::FieldError::new(
49+
"Failed to load creator account".to_string(),
6150
juniper::Value::null(),
62-
)),
51+
))
6352
}
6453
}
65-
6654
async fn winner_account(&self, context: &Context) -> FieldResult<Box<GraphQLAccount>> {
6755
let account_id = AccountId::new_with_default_token(self.winner_account_key.clone());
68-
let account_result = context
69-
.account_loader
70-
.try_load(account_id)
71-
.await
72-
.map_err(|e| {
73-
juniper::FieldError::new(
74-
format!("Failed to load delegate account: {}", e),
75-
juniper::Value::null(),
76-
)
77-
})?;
78-
79-
// Handle the result
80-
match account_result {
81-
Ok(account) => Ok(Box::new(account)),
82-
Err(e) => Err(juniper::FieldError::new(
83-
format!("Error loading delegate account: {}", e),
56+
if let Some(account) = context.load_account(account_id).await {
57+
Ok(Box::new(account))
58+
} else {
59+
Err(juniper::FieldError::new(
60+
"Failed to load winner account".to_string(),
8461
juniper::Value::null(),
85-
)),
62+
))
8663
}
8764
}
8865

node/native/src/graphql/mod.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use account::{create_account_loader, AccountLoader};
1+
use account::{create_account_loader, AccountLoader, GraphQLAccount};
22
use block::{GraphQLBlock, GraphQLSnarkJob, GraphQLUserCommands};
33
use juniper::{graphql_value, EmptySubscription, FieldError, GraphQLEnum, RootNode};
4-
use ledger::Account;
4+
use ledger::{Account, AccountId};
55
use mina_p2p_messages::v2::{
66
conv, LedgerHash, MinaBaseSignedCommandStableV2, MinaBaseUserCommandStableV2,
77
MinaBaseZkappCommandTStableV1WireStableV1, TokenIdKeyHash, TransactionHash,
@@ -10,12 +10,12 @@ use node::{
1010
account::AccountPublicKey,
1111
ledger::read::LedgerStatus,
1212
rpc::{
13-
AccountQuery, GetBlockQuery, PooledCommandsQuery, RpcGenesisBlockResponse,
14-
RpcGetBlockResponse, RpcPooledUserCommandsResponse, RpcPooledZkappCommandsResponse,
15-
RpcRequest, RpcSnarkPoolCompletedJobsResponse, RpcSnarkPoolPendingJobsGetResponse,
16-
RpcSyncStatsGetResponse, RpcTransactionInjectResponse, RpcTransactionStatusGetResponse,
17-
SyncStatsQuery, RpcStatusGetResponse, RpcNodeStatus, RpcBestChainResponse,
18-
RpcLedgerStatusGetResponse
13+
AccountQuery, GetBlockQuery, PooledCommandsQuery, RpcBestChainResponse,
14+
RpcGenesisBlockResponse, RpcGetBlockResponse, RpcLedgerAccountDelegatorsGetResponse,
15+
RpcLedgerStatusGetResponse, RpcNodeStatus, RpcPooledUserCommandsResponse,
16+
RpcPooledZkappCommandsResponse, RpcRequest, RpcSnarkPoolCompletedJobsResponse,
17+
RpcSnarkPoolPendingJobsGetResponse, RpcStatusGetResponse, RpcSyncStatsGetResponse,
18+
RpcTransactionInjectResponse, RpcTransactionStatusGetResponse, SyncStatsQuery,
1919
},
2020
stats::sync::SyncKind,
2121
BuildEnv,
@@ -162,6 +162,24 @@ impl Context {
162162
.await
163163
.clone()
164164
}
165+
166+
pub(crate) async fn load_account(&self, account_id: AccountId) -> Option<GraphQLAccount> {
167+
self.account_loader.try_load(account_id).await.ok()?.ok()
168+
}
169+
170+
pub async fn fetch_delegators(
171+
&self,
172+
ledger_hash: LedgerHash,
173+
account_id: AccountId,
174+
) -> RpcLedgerAccountDelegatorsGetResponse {
175+
self.rpc_sender
176+
.oneshot_request(RpcRequest::LedgerAccountDelegatorsGet(
177+
ledger_hash.clone(),
178+
account_id.clone(),
179+
))
180+
.await
181+
.flatten()
182+
}
165183
}
166184

167185
#[derive(Clone, Copy, Debug, GraphQLEnum)]

node/src/action_kind.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ pub enum ActionKind {
481481
RpcGlobalStateGet,
482482
RpcHealthCheck,
483483
RpcHeartbeatGet,
484+
RpcLedgerAccountDelegatorsGetInit,
485+
RpcLedgerAccountDelegatorsGetPending,
486+
RpcLedgerAccountDelegatorsGetSuccess,
484487
RpcLedgerAccountsGetInit,
485488
RpcLedgerAccountsGetPending,
486489
RpcLedgerAccountsGetSuccess,
@@ -536,6 +539,7 @@ pub enum ActionKind {
536539
RpcEffectfulGlobalStateGet,
537540
RpcEffectfulHealthCheck,
538541
RpcEffectfulHeartbeatGet,
542+
RpcEffectfulLedgerAccountDelegatorsGetSuccess,
539543
RpcEffectfulLedgerAccountsGetSuccess,
540544
RpcEffectfulLedgerStatusGetSuccess,
541545
RpcEffectfulMessageProgressGet,
@@ -734,7 +738,7 @@ pub enum ActionKind {
734738
}
735739

736740
impl ActionKind {
737-
pub const COUNT: u16 = 624;
741+
pub const COUNT: u16 = 628;
738742
}
739743

740744
impl std::fmt::Display for ActionKind {
@@ -1110,6 +1114,15 @@ impl ActionKindGet for RpcAction {
11101114
Self::LedgerStatusGetInit { .. } => ActionKind::RpcLedgerStatusGetInit,
11111115
Self::LedgerStatusGetPending { .. } => ActionKind::RpcLedgerStatusGetPending,
11121116
Self::LedgerStatusGetSuccess { .. } => ActionKind::RpcLedgerStatusGetSuccess,
1117+
Self::LedgerAccountDelegatorsGetInit { .. } => {
1118+
ActionKind::RpcLedgerAccountDelegatorsGetInit
1119+
}
1120+
Self::LedgerAccountDelegatorsGetPending { .. } => {
1121+
ActionKind::RpcLedgerAccountDelegatorsGetPending
1122+
}
1123+
Self::LedgerAccountDelegatorsGetSuccess { .. } => {
1124+
ActionKind::RpcLedgerAccountDelegatorsGetSuccess
1125+
}
11131126
Self::PooledUserCommands { .. } => ActionKind::RpcPooledUserCommands,
11141127
Self::PooledZkappCommands { .. } => ActionKind::RpcPooledZkappCommands,
11151128
Self::GenesisBlock { .. } => ActionKind::RpcGenesisBlock,
@@ -1188,6 +1201,9 @@ impl ActionKindGet for RpcEffectfulAction {
11881201
Self::GenesisBlock { .. } => ActionKind::RpcEffectfulGenesisBlock,
11891202
Self::ConsensusTimeGet { .. } => ActionKind::RpcEffectfulConsensusTimeGet,
11901203
Self::LedgerStatusGetSuccess { .. } => ActionKind::RpcEffectfulLedgerStatusGetSuccess,
1204+
Self::LedgerAccountDelegatorsGetSuccess { .. } => {
1205+
ActionKind::RpcEffectfulLedgerAccountDelegatorsGetSuccess
1206+
}
11911207
}
11921208
}
11931209
}

node/src/event_source/event.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ impl std::fmt::Display for Event {
8080
RpcRequest::GenesisBlockGet => write!(f, "GenesisBlock"),
8181
RpcRequest::ConsensusTimeGet(..) => write!(f, "ConsensusTimeGet"),
8282
RpcRequest::LedgerStatusGet(..) => write!(f, "LedgerStatusGet"),
83+
RpcRequest::LedgerAccountDelegatorsGet(..) => {
84+
write!(f, "LedgerAccountDelegatorsGet")
85+
}
8386
}
8487
}
8588
Self::ExternalSnarkWorker(event) => {

node/src/event_source/event_source_effects.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,13 @@ pub fn event_source_effects<S: Service>(store: &mut Store<S>, action: EventSourc
415415
ledger_hash,
416416
});
417417
}
418+
RpcRequest::LedgerAccountDelegatorsGet(ledger_hash, account_id) => {
419+
store.dispatch(RpcAction::LedgerAccountDelegatorsGetInit {
420+
rpc_id,
421+
ledger_hash,
422+
account_id,
423+
});
424+
}
418425
},
419426
Event::ExternalSnarkWorker(e) => match e {
420427
ExternalSnarkWorkerEvent::Started => {

node/src/ledger/ledger_manager.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@ impl LedgerRequest {
263263

264264
LedgerReadResponse::GetLedgerStatus(rpc_id, res)
265265
}
266+
LedgerReadRequest::GetAccountDelegators(rpc_id, ledger_hash, account_id) => {
267+
let res = ledger_ctx.get_account_delegators(&ledger_hash, &account_id);
268+
LedgerReadResponse::GetAccountDelegators(rpc_id, res)
269+
}
266270
},
267271
),
268272
LedgerRequest::AccountsSet {

node/src/ledger/ledger_service.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,23 @@ impl LedgerCtx {
522522
Ok(())
523523
}
524524

525+
pub fn get_account_delegators(
526+
&self,
527+
ledger_hash: &LedgerHash,
528+
account_id: &AccountId,
529+
) -> Option<Vec<Account>> {
530+
let (mask, _) = self.mask(ledger_hash)?;
531+
let mut accounts = Vec::new();
532+
533+
mask.iter(|account| {
534+
if account.delegate == Some(account_id.public_key.clone()) {
535+
accounts.push(account.clone());
536+
}
537+
});
538+
539+
Some(accounts)
540+
}
541+
525542
#[allow(clippy::type_complexity)]
526543
pub fn producers_with_delegates<F: FnMut(&CompressedPubKey) -> bool>(
527544
&self,

node/src/ledger/read/ledger_read_reducer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ impl LedgerReadState {
205205
response: resp.clone(),
206206
});
207207
}
208+
(_, LedgerReadResponse::GetAccountDelegators(rpc_id, resp)) => {
209+
dispatcher.push(RpcAction::LedgerAccountDelegatorsGetSuccess {
210+
rpc_id,
211+
response: resp.clone(),
212+
});
213+
}
208214
}
209215
}
210216

0 commit comments

Comments
 (0)