add bootstrap account rpc call

This commit is contained in:
musitdev 2023-09-11 18:27:21 +02:00
parent 5a118404c6
commit e0ebfc6ca5
3 changed files with 71 additions and 18 deletions

View File

@ -9,6 +9,15 @@
"params": []
}
'
curl http://localhost:3000 -X POST -H "Content-Type: application/json" -d '
{
"jsonrpc": "2.0",
"id" : 1,
"method": "bootstrap_accounts",
"params": []
}
'
*/
//TODO: add stake verify that it' not already desactivated.
@ -144,7 +153,7 @@ async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Re
account: vec![],
owner: vec![
solana_sdk::stake::program::ID.to_string(),
//solana_sdk::vote::program::ID.to_string(),
solana_sdk::vote::program::ID.to_string(),
],
filters: vec![],
},
@ -195,21 +204,34 @@ async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Re
loop {
tokio::select! {
_ = request_rx.recv() => {
tokio::task::spawn_blocking({
log::info!("RPC start save_stakes");
let current_stakes = stakestore.get_cloned_stake_map();
let move_epoch = current_epoch.clone();
move || {
let current_stake = crate::leader_schedule::build_current_stakes(&current_stakes, &move_epoch, RPC_URL.to_string(), CommitmentConfig::confirmed());
log::info!("RPC save_stakes generation done");
if let Err(err) = crate::leader_schedule::save_schedule_on_file("stakes", &current_stake) {
log::error!("Error during current stakes saving:{err}");
}
log::info!("RPC save_stakes END");
Some(req) = request_rx.recv() => {
match req {
crate::rpc::Requests::SaveStakes => {
tokio::task::spawn_blocking({
log::info!("RPC start save_stakes");
let current_stakes = stakestore.get_cloned_stake_map();
let move_epoch = current_epoch.clone();
move || {
let current_stake = crate::leader_schedule::build_current_stakes(&current_stakes, &move_epoch, RPC_URL.to_string(), CommitmentConfig::confirmed());
log::info!("RPC save_stakes generation done");
if let Err(err) = crate::leader_schedule::save_schedule_on_file("stakes", &current_stake) {
log::error!("Error during current stakes saving:{err}");
}
log::info!("RPC save_stakes END");
}
});
}
});
crate::rpc::Requests::BootstrapAccounts(tx) => {
log::info!("RPC start save_stakes");
let current_stakes = stakestore.get_cloned_stake_map();
if let Err(err) = tx.send((current_stakes, current_slot.confirmed_slot)){
println!("Channel error during sending bacl request status error:{err:?}");
}
log::info!("RPC bootstrap account send");
}
}
},
//log interval
_ = log_interval.tick() => {
@ -557,7 +579,7 @@ async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Re
//Ok(())
}
#[derive(Default, Debug)]
#[derive(Default, Debug, Clone)]
struct CurrentSlot {
processed_slot: u64,
confirmed_slot: u64,

View File

@ -1,9 +1,14 @@
use crate::stakestore::StakeMap;
use crate::stakestore::StoredStake;
use crate::Slot;
use jsonrpsee_core::error::Error as JsonRpcError;
use std::collections::HashMap;
//use jsonrpsee_http_server::{HttpServerBuilder, HttpServerHandle, RpcModule};
use jsonrpsee_server::{RpcModule, Server, ServerHandle};
use std::net::SocketAddr;
use thiserror::Error;
use tokio::sync::mpsc::Sender;
use tokio::sync::oneshot;
const RPC_ADDRESS: &str = "0.0.0.0:3000";
@ -20,6 +25,7 @@ pub enum RpcError {
pub enum Requests {
SaveStakes,
BootstrapAccounts(tokio::sync::oneshot::Sender<(StakeMap, Slot)>),
}
pub(crate) async fn run_server(request_tx: Sender<Requests>) -> Result<ServerHandle, RpcError> {
@ -35,7 +41,31 @@ pub(crate) async fn run_server(request_tx: Sender<Requests>) -> Result<ServerHan
.send(Requests::SaveStakes)
.await
.map(|_| "Get save_stakes status successfully".to_string())
.unwrap_or_else(|_| "error during request execution".to_string())
.unwrap_or_else(|_| "error during save_stakes request execution".to_string())
})?;
module.register_async_method("bootstrap_accounts", |_params, request_tx| async move {
log::trace!("RPC bootstrap_accounts");
let (tx, rx) = oneshot::channel();
if let Err(err) = request_tx.send(Requests::BootstrapAccounts(tx)).await {
return serde_json::Value::String(format!("error during query processing:{err}",));
}
rx.await
.map_err(|err| format!("error during bootstrap query processing:{err}"))
.and_then(|(accounts, slot)| {
println!("RPC end request status");
//replace pubkey with String. Json only allow distionary key with string.
let ret: HashMap<String, StoredStake> = accounts
.into_iter()
.map(|(pk, acc)| (pk.to_string(), acc))
.collect();
serde_json::to_value((slot, ret)).map_err(|err| {
format!(
"error during json serialisation:{}",
JsonRpcError::ParseError(err)
)
})
})
.unwrap_or_else(|err| serde_json::Value::String(err.to_string()))
})?;
let server_handle = server.start(module);
Ok(server_handle)

View File

@ -2,6 +2,7 @@ use crate::AccountPretty;
use crate::Slot;
use anyhow::bail;
use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
use solana_sdk::account::Account;
use solana_sdk::epoch_info::EpochInfo;
use solana_sdk::pubkey::Pubkey;
@ -63,7 +64,7 @@ fn stake_map_insert_stake(
};
}
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct StoredStake {
pub pubkey: Pubkey,
pub stake: Delegation,
@ -200,7 +201,7 @@ pub fn read_stake_from_account_data(mut data: &[u8]) -> anyhow::Result<Option<De
log::warn!("Stake account with empty data. Can't read stake.");
bail!("Error: read Stake account with empty data");
}
match StakeState::deserialize(&mut data)? {
match BorshDeserialize::deserialize(&mut data)? {
StakeState::Stake(_, stake) => Ok(Some(stake.delegation)),
StakeState::Initialized(_) => Ok(None),
other => {