Skip to content

Commit

Permalink
feat(json_rpc): new method to fetch stake entries ordered by rank for…
Browse files Browse the repository at this point in the history
… a given capability
  • Loading branch information
guidiaz committed Jan 13, 2025
1 parent a7777f7 commit 15d0e82
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
4 changes: 3 additions & 1 deletion data_structures/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use serde::{Deserialize, Serialize};

#[repr(u8)]
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Capability {
/// The base block mining and superblock voting capability
#[default]
Mining = 0,
/// The universal HTTP GET / HTTP POST / WIP-0019 RNG capability
Witnessing = 1,
Expand Down
18 changes: 15 additions & 3 deletions node/src/actors/chain_manager/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ use crate::{
GetDataRequestInfo, GetHighestCheckpointBeacon, GetMemoryTransaction, GetMempool,
GetMempoolResult, GetNodeStats, GetProtocolInfo, GetReputation, GetReputationResult,
GetSignalingInfo, GetState, GetSuperBlockVotes, GetSupplyInfo, GetUtxoInfo,
IsConfirmedBlock, PeersBeacons, QueryStake, ReputationStats, Rewind, SendLastBeacon,
SendProtocolVersions, SessionUnitResult, SetEpochConstants, SetLastBeacon,
SetPeersLimits, SignalingInfo, SnapshotExport, SnapshotImport, TryMineBlock,
IsConfirmedBlock, PeersBeacons, QueryStakePowers, QueryStakes, ReputationStats, Rewind,
SendLastBeacon, SendProtocolVersions, SessionUnitResult, SetEpochConstants,
SetLastBeacon, SetPeersLimits, SignalingInfo, SnapshotExport, SnapshotImport,
TryMineBlock,
},
sessions_manager::SessionsManager,
},
Expand Down Expand Up @@ -1464,6 +1465,17 @@ impl Handler<QueryStakes> for ChainManager {
}
}

impl Handler<QueryStakePowers> for ChainManager {
type Result = <QueryStakePowers as Message>::Result;

fn handle(&mut self, msg: QueryStakePowers, _ctx: &mut Self::Context) -> Self::Result {
self.chain_state
.stakes
.by_rank(msg.capability, self.current_epoch.unwrap())
.collect()
}
}

impl Handler<BuildDrt> for ChainManager {
type Result = ResponseActFuture<Self, Result<DRTransaction, failure::Error>>;

Expand Down
45 changes: 44 additions & 1 deletion node/src/actors/json_rpc/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use crate::{
GetHighestCheckpointBeacon, GetItemBlock, GetItemSuperblock, GetItemTransaction,
GetKnownPeers, GetMemoryTransaction, GetMempool, GetNodeStats, GetProtocolInfo,
GetReputation, GetSignalingInfo, GetState, GetSupplyInfo, GetUtxoInfo, InitializePeers,
IsConfirmedBlock, QueryStakes, QueryStakesFilter, Rewind,
IsConfirmedBlock, QueryStakePowers, QueryStakes, QueryStakesFilter, Rewind,
SnapshotExport, SnapshotImport, StakeAuthorization,
},
peers_manager::PeersManager,
Expand Down Expand Up @@ -145,6 +145,9 @@ pub fn attach_regular_methods<H>(
server.add_actix_method(system, "queryStakes", |params: Params| {
Box::pin(query_stakes(params.parse()))
});
server.add_actix_method(system, "ranks", |params: Params| {
Box::pin(query_ranks(params.parse()))
});
}

/// Attach the sensitive JSON-RPC methods to a multi-transport server.
Expand Down Expand Up @@ -2239,6 +2242,46 @@ pub async fn query_stakes(params: Result<Option<QueryStakesParams>, Error>) -> J
.await
}

/// Format of the output of getTransaction
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
pub struct QueryRanksRecord {
/// Current power
pub power: u64,
/// Validator's stringified pkh
pub validator: String,
/// Withdrawer's stringified pkh
pub withdrawer: String,
}

/// Query the amount of nanowits staked by an address.
pub async fn query_ranks(params: Result<(Capability,), Error>) -> JsonRpcResult {
let capability = match params {
Ok(x) => x.0,
Err(_) => Capability::Mining,
};
ChainManager::from_registry()
.send(QueryStakePowers { capability })
.map(|res| match res {
Ok(candidates) => {
let candidates: Vec<QueryRanksRecord> = candidates
.iter()
.map(|(key, power)| QueryRanksRecord {
power: *power,
validator: key.validator.to_string(),
withdrawer: key.withdrawer.to_string(),
})
.collect();
let candidates = serde_json::to_value(candidates);
candidates.map_err(internal_error)
}
Err(e) => {
let err = internal_error_s(e);
Err(err)
}
})
.await
}

#[cfg(test)]
mod mock_actix {
use actix::{MailboxError, Message};
Expand Down
11 changes: 11 additions & 0 deletions node/src/actors/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,17 @@ impl Message for StakeAuthorization {
type Result = Result<String, failure::Error>;
}

/// Message for querying stakes
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct QueryStakePowers {
/// capability being searched for
pub capability: Capability,
}

impl Message for QueryStakePowers {
type Result = Vec<(StakeKey<PublicKeyHash>, Power)>;
}

/// Stake key for quering stakes
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum QueryStakesFilter {
Expand Down

0 comments on commit 15d0e82

Please sign in to comment.