Merge pull request #233 from blockworks-foundation/methods

implement rpc methods with a todo!() clause
This commit is contained in:
Aniket Prajapati 2023-11-06 21:48:18 +05:30 committed by GitHub
commit 45392943ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 362 additions and 101 deletions

View File

@ -21,10 +21,17 @@ use solana_lite_rpc_history::history::History;
use solana_rpc_client::nonblocking::rpc_client::RpcClient;
use solana_rpc_client_api::{
config::{
RpcBlockConfig, RpcContextConfig, RpcEncodingConfigWrapper, RpcRequestAirdropConfig,
RpcSignatureStatusConfig,
RpcBlockConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter, RpcBlocksConfigWrapper,
RpcContextConfig, RpcEncodingConfigWrapper, RpcEpochConfig, RpcGetVoteAccountsConfig,
RpcProgramAccountsConfig, RpcRequestAirdropConfig, RpcSignatureStatusConfig,
RpcSignatureSubscribeConfig, RpcSignaturesForAddressConfig, RpcTransactionLogsConfig,
RpcTransactionLogsFilter,
},
response::{
Response as RpcResponse, RpcBlockhash, RpcConfirmedTransactionStatusWithSignature,
RpcContactInfo, RpcLeaderSchedule, RpcPerfSample, RpcPrioritizationFee, RpcResponseContext,
RpcVersionInfo, RpcVoteAccountStatus,
},
response::{Response as RpcResponse, RpcBlockhash, RpcResponseContext, RpcVersionInfo},
};
use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, slot_history::Slot};
use solana_transaction_status::{TransactionStatus, UiConfirmedBlock};
@ -117,37 +124,65 @@ impl LiteBridge {
#[jsonrpsee::core::async_trait]
impl LiteRpcServer for LiteBridge {
async fn send_transaction(
async fn get_block(
&self,
tx: String,
send_transaction_config: Option<SendTransactionConfig>,
) -> crate::rpc::Result<String> {
RPC_SEND_TX.inc();
let SendTransactionConfig {
encoding,
max_retries,
} = send_transaction_config.unwrap_or_default();
let raw_tx = match encoding.decode(tx) {
Ok(raw_tx) => raw_tx,
Err(err) => {
return Err(jsonrpsee::core::Error::Custom(err.to_string()));
slot: u64,
config: Option<RpcEncodingConfigWrapper<RpcBlockConfig>>,
) -> crate::rpc::Result<Option<UiConfirmedBlock>> {
let config = config.map_or(RpcBlockConfig::default(), |x| x.convert_to_current());
let block = self.history.block_storage.get(slot, config).await;
if block.is_ok() {
// TO DO Convert to UIConfirmed Block
Err(jsonrpsee::core::Error::HttpNotImplemented)
} else {
Ok(None)
}
};
match self
.transaction_service
.send_transaction(raw_tx, max_retries)
.await
{
Ok(sig) => {
TXS_IN_CHANNEL.inc();
Ok(sig)
}
Err(e) => Err(jsonrpsee::core::Error::Custom(e.to_string())),
async fn get_blocks(
&self,
_start_slot: Slot,
_config: Option<RpcBlocksConfigWrapper>,
_commitment: Option<CommitmentConfig>,
) -> crate::rpc::Result<Vec<Slot>> {
todo!()
}
async fn get_signatures_for_address(
&self,
_address: String,
_config: Option<RpcSignaturesForAddressConfig>,
) -> crate::rpc::Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
todo!()
}
async fn get_cluster_nodes(&self) -> crate::rpc::Result<Vec<RpcContactInfo>> {
todo!()
}
async fn get_slot(&self, config: Option<RpcContextConfig>) -> crate::rpc::Result<Slot> {
let commitment_config = config
.map(|config| config.commitment.unwrap_or_default())
.unwrap_or_default();
let BlockInformation { slot, .. } = self
.data_cache
.block_information_store
.get_latest_block(commitment_config)
.await;
Ok(slot)
}
async fn get_block_height(&self, _config: Option<RpcContextConfig>) -> crate::rpc::Result<u64> {
todo!()
}
async fn get_block_time(&self, _block: u64) -> crate::rpc::Result<u64> {
todo!()
}
async fn get_first_available_block(&self) -> crate::rpc::Result<u64> {
todo!()
}
async fn get_latest_blockhash(
@ -210,6 +245,50 @@ impl LiteRpcServer for LiteBridge {
})
}
async fn get_epoch_info(
&self,
config: Option<RpcContextConfig>,
) -> crate::rpc::Result<EpochInfo> {
let commitment_config = config
.map(|config| config.commitment.unwrap_or_default())
.unwrap_or_default();
let block_info = self
.data_cache
.block_information_store
.get_latest_block_info(commitment_config)
.await;
//TODO manage transaction_count of epoch info. Currently None.
let epoch_info = self
.data_cache
.get_current_epoch(commitment_config)
.await
.into_epoch_info(block_info.block_height, None);
Ok(epoch_info)
}
async fn get_leader_schedule(
&self,
_slot: Option<Slot>,
_config: Option<RpcEncodingConfigWrapper<RpcEpochConfig>>,
) -> crate::rpc::Result<Option<RpcLeaderSchedule>> {
todo!()
}
async fn get_vote_accounts(
&self,
_config: Option<RpcGetVoteAccountsConfig>,
) -> crate::rpc::Result<RpcVoteAccountStatus> {
todo!()
}
async fn get_recent_performance_samples(
&self,
_limit: Option<usize>,
) -> crate::rpc::Result<Vec<RpcPerfSample>> {
todo!()
}
async fn get_signature_statuses(
&self,
sigs: Vec<String>,
@ -236,6 +315,46 @@ impl LiteRpcServer for LiteBridge {
})
}
async fn get_recent_prioritization_fees(
&self,
_pubkey_strs: Option<Vec<String>>,
) -> crate::rpc::Result<Vec<RpcPrioritizationFee>> {
todo!()
}
async fn send_transaction(
&self,
tx: String,
send_transaction_config: Option<SendTransactionConfig>,
) -> crate::rpc::Result<String> {
RPC_SEND_TX.inc();
let SendTransactionConfig {
encoding,
max_retries,
} = send_transaction_config.unwrap_or_default();
let raw_tx = match encoding.decode(tx) {
Ok(raw_tx) => raw_tx,
Err(err) => {
return Err(jsonrpsee::core::Error::Custom(err.to_string()));
}
};
match self
.transaction_service
.send_transaction(raw_tx, max_retries)
.await
{
Ok(sig) => {
TXS_IN_CHANNEL.inc();
Ok(sig)
}
Err(e) => Err(jsonrpsee::core::Error::Custom(e.to_string())),
}
}
fn get_version(&self) -> crate::rpc::Result<RpcVersionInfo> {
RPC_GET_VERSION.inc();
@ -290,24 +409,43 @@ impl LiteRpcServer for LiteBridge {
Ok(airdrop_sig)
}
async fn get_slot(&self, config: Option<RpcContextConfig>) -> crate::rpc::Result<Slot> {
let commitment_config = config
.map(|config| config.commitment.unwrap_or_default())
.unwrap_or_default();
let BlockInformation { slot, .. } = self
.data_cache
.block_information_store
.get_latest_block(commitment_config)
.await;
Ok(slot)
async fn program_subscribe(
&self,
_pending: PendingSubscriptionSink,
_pubkey_str: String,
_config: Option<RpcProgramAccountsConfig>,
) -> SubscriptionResult {
todo!()
}
async fn slot_subscribe(&self, _pending: PendingSubscriptionSink) -> SubscriptionResult {
todo!()
}
async fn block_subscribe(
&self,
_pending: PendingSubscriptionSink,
_filter: RpcBlockSubscribeFilter,
_config: Option<RpcBlockSubscribeConfig>,
) -> SubscriptionResult {
todo!()
}
async fn logs_subscribe(
&self,
_pending: PendingSubscriptionSink,
_filter: RpcTransactionLogsFilter,
_config: Option<RpcTransactionLogsConfig>,
) -> SubscriptionResult {
todo!()
}
// WARN: enable_received_notification: bool is ignored
async fn signature_subscribe(
&self,
pending: PendingSubscriptionSink,
signature: String,
commitment_config: CommitmentConfig,
config: RpcSignatureSubscribeConfig,
) -> SubscriptionResult {
RPC_SIGNATURE_SUBSCRIBE.inc();
let sink = pending.accept().await?;
@ -315,47 +453,21 @@ impl LiteRpcServer for LiteBridge {
let jsonrpsee_sink = JsonRpseeSubscriptionHandlerSink::new(sink);
self.data_cache.tx_subs.signature_subscribe(
signature,
commitment_config,
config.commitment.unwrap_or_default(),
Arc::new(jsonrpsee_sink),
);
Ok(())
}
async fn get_block(
async fn slot_updates_subscribe(
&self,
slot: u64,
config: Option<RpcEncodingConfigWrapper<RpcBlockConfig>>,
) -> crate::rpc::Result<Option<UiConfirmedBlock>> {
let config = config.map_or(RpcBlockConfig::default(), |x| x.convert_to_current());
let block = self.history.block_storage.get(slot, config).await;
if block.is_ok() {
// TO DO Convert to UIConfirmed Block
Err(jsonrpsee::core::Error::HttpNotImplemented)
} else {
Ok(None)
}
_pending: PendingSubscriptionSink,
) -> SubscriptionResult {
todo!()
}
async fn get_epoch_info(
&self,
config: Option<RpcContextConfig>,
) -> crate::rpc::Result<EpochInfo> {
let commitment_config = config
.map(|config| config.commitment.unwrap_or_default())
.unwrap_or_default();
let block_info = self
.data_cache
.block_information_store
.get_latest_block_info(commitment_config)
.await;
//TODO manage transaction_count of epoch info. Currently None.
let epoch_info = self
.data_cache
.get_current_epoch(commitment_config)
.await
.into_epoch_info(block_info.block_height, None);
Ok(epoch_info)
async fn vote_subscribe(&self, _pending: PendingSubscriptionSink) -> SubscriptionResult {
todo!()
}
}

View File

@ -1,10 +1,18 @@
use jsonrpsee::core::SubscriptionResult;
use jsonrpsee::proc_macros::rpc;
use solana_rpc_client_api::config::{
RpcBlockConfig, RpcContextConfig, RpcEncodingConfigWrapper, RpcRequestAirdropConfig,
RpcSignatureStatusConfig,
RpcBlockConfig, RpcBlockSubscribeConfig, RpcBlockSubscribeFilter, RpcBlocksConfigWrapper,
RpcContextConfig, RpcEncodingConfigWrapper, RpcEpochConfig, RpcGetVoteAccountsConfig,
RpcProgramAccountsConfig, RpcRequestAirdropConfig, RpcSignatureStatusConfig,
RpcSignatureSubscribeConfig, RpcSignaturesForAddressConfig, RpcTransactionLogsConfig,
RpcTransactionLogsFilter,
};
use solana_rpc_client_api::response::{Response as RpcResponse, RpcBlockhash, RpcVersionInfo};
use solana_rpc_client_api::response::{
Response as RpcResponse, RpcBlockhash, RpcConfirmedTransactionStatusWithSignature,
RpcContactInfo, RpcLeaderSchedule, RpcPerfSample, RpcPrioritizationFee, RpcVersionInfo,
RpcVoteAccountStatus,
};
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::epoch_info::EpochInfo;
use solana_sdk::slot_history::Slot;
@ -16,12 +24,63 @@ pub type Result<T> = std::result::Result<T, jsonrpsee::core::Error>;
#[rpc(server)]
pub trait LiteRpc {
#[method(name = "sendTransaction")]
async fn send_transaction(
// ***********************
// History Domain
// ***********************
#[method(name = "getBlock")]
async fn get_block(
&self,
tx: String,
send_transaction_config: Option<SendTransactionConfig>,
) -> Result<String>;
slot: u64,
config: Option<RpcEncodingConfigWrapper<RpcBlockConfig>>,
) -> Result<Option<UiConfirmedBlock>>;
#[method(name = "getBlocks")]
async fn get_blocks(
&self,
start_slot: Slot,
config: Option<RpcBlocksConfigWrapper>,
commitment: Option<CommitmentConfig>,
) -> Result<Vec<Slot>>;
#[method(name = "getSignaturesForAddress")]
async fn get_signatures_for_address(
&self,
address: String,
config: Option<RpcSignaturesForAddressConfig>,
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>>;
// issue: solana_transaction_status::EncodedConfirmedTransactionWithStatusMeta does not implement Clone
//
//#[method(name = "getTransaction")]
//async fn get_transaction(
// &self,
// signature_str: String,
// config: Option<RpcEncodingConfigWrapper<RpcTransactionConfig>>,
//) -> Result<Option<EncodedConfirmedTransactionWithStatusMeta>>;
// ***********************
// Cluster Domain
// ***********************
#[method(name = "getClusterNodes")]
async fn get_cluster_nodes(&self) -> Result<Vec<RpcContactInfo>>;
// ***********************
// Validator Domain
// ***********************
#[method(name = "getSlot")]
async fn get_slot(&self, config: Option<RpcContextConfig>) -> Result<Slot>;
#[method(name = "getBlockHeight")]
async fn get_block_height(&self, config: Option<RpcContextConfig>) -> Result<u64>;
#[method(name = "getBlockTime")]
async fn get_block_time(&self, block: u64) -> Result<u64>;
#[method(name = "getFirstAvailableBlock")]
async fn get_first_available_block(&self) -> Result<u64>;
#[method(name = "getLatestBlockhash")]
async fn get_latest_blockhash(
@ -36,6 +95,44 @@ pub trait LiteRpc {
config: Option<IsBlockHashValidConfig>,
) -> Result<RpcResponse<bool>>;
// BlockCommitmentArray is defined in solana/runtime/src/commitment.rs
//
// pub type BlockCommitmentArray = [u64; MAX_LOCKOUT_HISTORY + 1];
//
// where
// solana_vote_program::vote_state::MAX_LOCKOUT_HISTORY,
//
// Maximum number of votes to keep around, tightly coupled with epoch_schedule::MINIMUM_SLOTS_PER_EPOCH
// pub const MAX_LOCKOUT_HISTORY: usize = 31;
//
// #[method(name = "getBlockCommitment")]
// async fn get_block_commitment(
// &self,
// block: u64,
// ) -> Result<RpcBlockCommitment<BlockCommitmentArray>>;
#[method(name = "getEpochInfo")]
async fn get_epoch_info(&self, config: Option<RpcContextConfig>) -> Result<EpochInfo>;
#[method(name = "getLeaderSchedule")]
async fn get_leader_schedule(
&self,
slot: Option<Slot>,
config: Option<RpcEncodingConfigWrapper<RpcEpochConfig>>,
) -> Result<Option<RpcLeaderSchedule>>;
#[method(name = "getVoteAccounts")]
async fn get_vote_accounts(
&self,
config: Option<RpcGetVoteAccountsConfig>,
) -> Result<RpcVoteAccountStatus>;
#[method(name = "getRecentPerformanceSamples")]
async fn get_recent_performance_samples(
&self,
limit: Option<usize>,
) -> Result<Vec<RpcPerfSample>>;
#[method(name = "getSignatureStatuses")]
async fn get_signature_statuses(
&self,
@ -43,6 +140,27 @@ pub trait LiteRpc {
config: Option<RpcSignatureStatusConfig>,
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>>;
#[method(name = "getRecentPrioritizationFees")]
async fn get_recent_prioritization_fees(
&self,
pubkey_strs: Option<Vec<String>>,
) -> Result<Vec<RpcPrioritizationFee>>;
// ***********************
// Send Transaction Domain
// ***********************
#[method(name = "sendTransaction")]
async fn send_transaction(
&self,
tx: String,
send_transaction_config: Option<SendTransactionConfig>,
) -> Result<String>;
// ***********************
// Deprecated
// ***********************
#[method(name = "getVersion")]
fn get_version(&self) -> Result<RpcVersionInfo>;
@ -54,26 +172,57 @@ pub trait LiteRpc {
config: Option<RpcRequestAirdropConfig>,
) -> Result<String>;
#[method(name = "getSlot")]
async fn get_slot(&self, config: Option<RpcContextConfig>) -> Result<Slot>;
// ***********************
// Direct Subscription Domain
// ***********************
#[subscription(name = "programSubscribe" => "programNotification", unsubscribe="programUnsubscribe", item=RpcResponse<serde_json::Value>)]
async fn program_subscribe(
&self,
pubkey_str: String,
config: Option<RpcProgramAccountsConfig>,
) -> SubscriptionResult;
#[subscription(name = "slotSubscribe" => "slotNotification", unsubscribe="slotUnsubscribe", item=Slot)]
async fn slot_subscribe(&self) -> SubscriptionResult;
#[subscription(name = "blockSubscribe" => "blockNotification", unsubscribe="blockUnsubscribe", item=RpcResponse<UiConfirmedBlock>)]
async fn block_subscribe(
&self,
filter: RpcBlockSubscribeFilter,
config: Option<RpcBlockSubscribeConfig>,
) -> SubscriptionResult;
// [transactionSubscribe](https://github.com/solana-foundation/solana-improvement-documents/pull/69)
//
//#[subscription(name = "transactionSubscribe" => "transactionNotification", unsubscribe="transactionUnsubscribe", item=RpcResponse<RpcConfirmedTransactionStatusWithSignature>)]
//async fn transaction_subscribe(
// &self,
// commitment_config: CommitmentConfig,
//) -> SubscriptionResult;
// ***********************
// Indirect Subscription Domain
// ***********************
#[subscription(name = "logsSubscribe" => "logsNotification", unsubscribe="logsUnsubscribe", item=RpcResponse<RpcLogsResponse>)]
async fn logs_subscribe(
&self,
filter: RpcTransactionLogsFilter,
config: Option<RpcTransactionLogsConfig>,
) -> SubscriptionResult;
// WARN: enable_received_notification: bool is ignored
#[subscription(name = "signatureSubscribe" => "signatureNotification", unsubscribe="signatureUnsubscribe", item=RpcResponse<serde_json::Value>)]
async fn signature_subscribe(
&self,
signature: String,
commitment_config: CommitmentConfig,
config: RpcSignatureSubscribeConfig,
) -> SubscriptionResult;
#[method(name = "getBlock")]
async fn get_block(
&self,
slot: u64,
config: Option<RpcEncodingConfigWrapper<RpcBlockConfig>>,
) -> Result<Option<UiConfirmedBlock>>;
#[subscription(name = "slotUpdatesSubscribe" => "slotUpdatesNotification", unsubscribe="slotUpdatesUnsubscribe", item=SlotUpdate)]
async fn slot_updates_subscribe(&self) -> SubscriptionResult;
#[method(name = "getEpochInfo")]
async fn get_epoch_info(
&self,
config: Option<RpcContextConfig>,
) -> crate::rpc::Result<EpochInfo>;
#[subscription(name = "voteSubscribe" => "voteNotification", unsubscribe="voteUnsubscribe", item=RpcVote)]
async fn vote_subscribe(&self) -> SubscriptionResult;
}

View File

@ -27,7 +27,7 @@ impl RpcTester {
// sleep for 5 seconds
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
// do a simple request to self for getVersion
let Err(err) = rpc_client.get_version().await else {
let Err(err) = rpc_client.get_slot().await else {
RPC_RESPONDING.set(1.0);
continue;
};