Create solana-rpc crate and move subscriptions (#17320)

* Move non_circulating_supply to runtime

* Add solana-rpc crate and move max_slots

* Move subscriptions to solana-rpc

* Single use statements
This commit is contained in:
Tyera Eulberg 2021-05-19 00:54:28 -06:00 committed by GitHub
parent a3c0833a1c
commit 827355a6b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 459 additions and 354 deletions

33
Cargo.lock generated
View File

@ -4302,8 +4302,6 @@ dependencies = [
"jsonrpc-core-client",
"jsonrpc-derive",
"jsonrpc-http-server",
"jsonrpc-pubsub",
"jsonrpc-ws-server",
"libc",
"log 0.4.11",
"lru",
@ -4342,6 +4340,7 @@ dependencies = [
"solana-perf",
"solana-program-test",
"solana-rayon-threadlimit",
"solana-rpc",
"solana-runtime",
"solana-sdk",
"solana-stake-program",
@ -5032,6 +5031,35 @@ dependencies = [
"uriparse",
]
[[package]]
name = "solana-rpc"
version = "1.7.0"
dependencies = [
"bs58",
"crossbeam-channel 0.4.4",
"jsonrpc-core",
"jsonrpc-core-client",
"jsonrpc-derive",
"jsonrpc-pubsub",
"jsonrpc-ws-server",
"log 0.4.11",
"serde",
"serde_derive",
"serde_json",
"serial_test",
"solana-account-decoder",
"solana-client",
"solana-ledger",
"solana-measure",
"solana-metrics",
"solana-runtime",
"solana-sdk",
"solana-stake-program",
"solana-vote-program",
"spl-token",
"tokio 1.1.1",
]
[[package]]
name = "solana-runtime"
version = "1.7.0"
@ -5420,6 +5448,7 @@ dependencies = [
"solana-metrics",
"solana-net-utils",
"solana-perf",
"solana-rpc",
"solana-runtime",
"solana-sdk",
"solana-version",

View File

@ -33,8 +33,6 @@ jsonrpc-core = "17.0.0"
jsonrpc-core-client = { version = "17.0.0", features = ["ipc", "ws"] }
jsonrpc-derive = "17.0.0"
jsonrpc-http-server = "17.0.0"
jsonrpc-pubsub = "17.0.0"
jsonrpc-ws-server = "17.0.0"
libc = "0.2.81"
log = "0.4.11"
lru = "0.6.1"
@ -65,6 +63,7 @@ solana-measure = { path = "../measure", version = "=1.7.0" }
solana-net-utils = { path = "../net-utils", version = "=1.7.0" }
solana-perf = { path = "../perf", version = "=1.7.0" }
solana-program-test = { path = "../program-test", version = "=1.7.0" }
solana-rpc = { path = "../rpc", version = "=1.7.0" }
solana-runtime = { path = "../runtime", version = "=1.7.0" }
solana-sdk = { path = "../sdk", version = "=1.7.0" }
solana-frozen-abi = { path = "../frozen-abi", version = "=1.7.0" }

View File

@ -6,7 +6,6 @@ extern crate test;
use log::*;
use solana_core::cluster_info::{ClusterInfo, Node};
use solana_core::contact_info::ContactInfo;
use solana_core::max_slots::MaxSlots;
use solana_core::retransmit_stage::retransmitter;
use solana_ledger::entry::Entry;
use solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo};
@ -14,6 +13,7 @@ use solana_ledger::leader_schedule_cache::LeaderScheduleCache;
use solana_ledger::shred::Shredder;
use solana_measure::measure::Measure;
use solana_perf::packet::{Packet, Packets};
use solana_rpc::max_slots::MaxSlots;
use solana_runtime::bank::Bank;
use solana_runtime::bank_forks::BankForks;
use solana_sdk::hash::Hash;

View File

@ -3,11 +3,9 @@ use crate::{
crds::Cursor,
crds_value::CrdsValueLabel,
optimistic_confirmation_verifier::OptimisticConfirmationVerifier,
optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
poh_recorder::PohRecorder,
replay_stage::DUPLICATE_THRESHOLD,
result::{Error, Result},
rpc_subscriptions::RpcSubscriptions,
sigverify,
verified_vote_packets::VerifiedVotePackets,
vote_stake_tracker::VoteStakeTracker,
@ -20,6 +18,10 @@ use log::*;
use solana_ledger::blockstore::Blockstore;
use solana_metrics::inc_new_counter_debug;
use solana_perf::packet::{self, Packets};
use solana_rpc::{
optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
bank::Bank,
bank_forks::BankForks,
@ -824,8 +826,8 @@ impl ClusterInfoVoteListener {
#[cfg(test)]
mod tests {
use super::*;
use crate::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank;
use solana_perf::packet;
use solana_rpc::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank;
use solana_runtime::{
bank::Bank,
commitment::BlockCommitmentCache,

View File

@ -1,6 +1,7 @@
use crate::{consensus::Stake, rpc_subscriptions::RpcSubscriptions};
use crate::consensus::Stake;
use solana_measure::measure::Measure;
use solana_metrics::datapoint_info;
use solana_rpc::rpc_subscriptions::RpcSubscriptions;
use solana_runtime::{
bank::Bank,
commitment::{BlockCommitment, BlockCommitmentCache, CommitmentSlots, VOTE_THRESHOLD_SIZE},

View File

@ -1,7 +1,7 @@
use crate::{max_slots::MaxSlots, rpc_subscriptions::RpcSubscriptions};
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
use solana_ledger::blockstore::{Blockstore, CompletedDataSetInfo};
use solana_ledger::entry::Entry;
use solana_rpc::{max_slots::MaxSlots, rpc_subscriptions::RpcSubscriptions};
use solana_sdk::signature::Signature;
use std::{
sync::{

View File

@ -16,7 +16,6 @@ pub mod cluster_info_vote_listener;
pub mod commitment_service;
pub mod completed_data_sets_service;
mod deprecated;
pub mod max_slots;
pub mod sample_performance_service;
pub mod shred_fetch_stage;
#[macro_use]
@ -44,9 +43,7 @@ pub mod gossip_service;
pub mod heaviest_subtree_fork_choice;
pub mod latest_validator_votes_for_frozen_banks;
pub mod ledger_cleanup_service;
pub mod non_circulating_supply;
pub mod optimistic_confirmation_verifier;
pub mod optimistically_confirmed_bank_tracker;
pub mod outstanding_requests;
pub mod packet_hasher;
pub mod ping_pong;
@ -63,12 +60,8 @@ mod result;
pub mod retransmit_stage;
pub mod rewards_recorder_service;
pub mod rpc;
pub mod rpc_completed_slots_service;
pub mod rpc_health;
pub mod rpc_pubsub;
pub mod rpc_pubsub_service;
pub mod rpc_service;
pub mod rpc_subscriptions;
pub mod send_transaction_service;
pub mod serve_repair;
pub mod serve_repair_service;

View File

@ -16,13 +16,11 @@ use crate::{
fork_choice::{ForkChoice, SelectVoteAndResetForkResult},
heaviest_subtree_fork_choice::HeaviestSubtreeForkChoice,
latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks,
optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
poh_recorder::{PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
progress_map::{DuplicateStats, ForkProgress, ProgressMap, PropagatedStats},
repair_service::DuplicateSlotsResetReceiver,
result::Result,
rewards_recorder_service::RewardsRecorderSender,
rpc_subscriptions::RpcSubscriptions,
unfrozen_gossip_verified_vote_hashes::UnfrozenGossipVerifiedVoteHashes,
window_service::DuplicateSlotReceiver,
};
@ -36,6 +34,10 @@ use solana_ledger::{
};
use solana_measure::measure::Measure;
use solana_metrics::inc_new_counter_info;
use solana_rpc::{
optimistically_confirmed_bank_tracker::{BankNotification, BankNotificationSender},
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
accounts_background_service::AbsRequestSender, bank::Bank, bank_forks::BankForks,
commitment::BlockCommitmentCache, vote_sender_types::ReplayVoteSender,
@ -2475,7 +2477,6 @@ pub(crate) mod tests {
consensus::test::{initialize_state, VoteSimulator},
consensus::Tower,
crds::Cursor,
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
progress_map::ValidatorStakeInfo,
replay_stage::ReplayStage,
transaction_status_service::TransactionStatusService,
@ -2493,6 +2494,7 @@ pub(crate) mod tests {
SIZE_OF_COMMON_SHRED_HEADER, SIZE_OF_DATA_SHRED_HEADER, SIZE_OF_DATA_SHRED_PAYLOAD,
},
};
use solana_rpc::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank;
use solana_runtime::{
accounts_background_service::AbsRequestSender,
commitment::BlockCommitment,

View File

@ -8,12 +8,9 @@ use crate::{
cluster_slots_service::ClusterSlotsService,
completed_data_sets_service::CompletedDataSetsSender,
contact_info::ContactInfo,
max_slots::MaxSlots,
repair_service::DuplicateSlotsResetSender,
repair_service::RepairInfo,
result::{Error, Result},
rpc_completed_slots_service::RpcCompletedSlotsService,
rpc_subscriptions::RpcSubscriptions,
window_service::{should_retransmit_and_persist, WindowService},
};
use crossbeam_channel::{Receiver, Sender};
@ -27,6 +24,10 @@ use solana_ledger::{
use solana_measure::measure::Measure;
use solana_metrics::inc_new_counter_error;
use solana_perf::packet::{Packet, Packets};
use solana_rpc::{
max_slots::MaxSlots, rpc_completed_slots_service::RpcCompletedSlotsService,
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{bank::Bank, bank_forks::BankForks};
use solana_sdk::{clock::Slot, epoch_schedule::EpochSchedule, pubkey::Pubkey, timing::timestamp};
use solana_streamer::streamer::PacketReceiver;

View File

@ -3,9 +3,6 @@
use crate::{
cluster_info::ClusterInfo,
contact_info::ContactInfo,
max_slots::MaxSlots,
non_circulating_supply::calculate_non_circulating_supply,
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc_health::*,
send_transaction_service::{SendTransactionService, TransactionInfo},
validator::ValidatorExit,
@ -14,12 +11,8 @@ use bincode::{config::Options, serialize};
use jsonrpc_core::{types::error, Error, Metadata, Result};
use jsonrpc_derive::rpc;
use solana_account_decoder::{
parse_account_data::AccountAdditionalData,
parse_token::{
get_token_account_mint, spl_token_id_v2_0, spl_token_v2_0_native_mint,
token_amount_to_ui_amount, UiTokenAmount,
},
UiAccount, UiAccountData, UiAccountEncoding, UiDataSliceConfig,
parse_token::{spl_token_id_v2_0, token_amount_to_ui_amount, UiTokenAmount},
UiAccount, UiAccountEncoding, UiDataSliceConfig,
};
use solana_client::{
rpc_cache::LargestAccountsCache,
@ -44,6 +37,10 @@ use solana_ledger::{
};
use solana_metrics::inc_new_counter_info;
use solana_perf::packet::PACKET_DATA_SIZE;
use solana_rpc::{
max_slots::MaxSlots, optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
parsed_token_accounts::*,
};
use solana_runtime::{
accounts::AccountAddressFilter,
accounts_index::{AccountIndex, AccountSecondaryIndexes, IndexKey},
@ -51,6 +48,7 @@ use solana_runtime::{
bank_forks::{BankForks, SnapshotConfig},
commitment::{BlockCommitmentArray, BlockCommitmentCache, CommitmentSlots},
inline_spl_token_v2_0::{SPL_TOKEN_ACCOUNT_MINT_OFFSET, SPL_TOKEN_ACCOUNT_OWNER_OFFSET},
non_circulating_supply::calculate_non_circulating_supply,
snapshot_utils::get_highest_snapshot_archive_path,
};
use solana_sdk::{
@ -1991,62 +1989,6 @@ fn get_spl_token_mint_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
}
}
pub(crate) fn get_parsed_token_account(
bank: Arc<Bank>,
pubkey: &Pubkey,
account: AccountSharedData,
) -> UiAccount {
let additional_data = get_token_account_mint(&account.data())
.and_then(|mint_pubkey| get_mint_owner_and_decimals(&bank, &mint_pubkey).ok())
.map(|(_, decimals)| AccountAdditionalData {
spl_token_decimals: Some(decimals),
});
UiAccount::encode(
pubkey,
account,
UiAccountEncoding::JsonParsed,
additional_data,
None,
)
}
pub(crate) fn get_parsed_token_accounts<I>(
bank: Arc<Bank>,
keyed_accounts: I,
) -> impl Iterator<Item = RpcKeyedAccount>
where
I: Iterator<Item = (Pubkey, AccountSharedData)>,
{
let mut mint_decimals: HashMap<Pubkey, u8> = HashMap::new();
keyed_accounts.filter_map(move |(pubkey, account)| {
let additional_data = get_token_account_mint(&account.data()).map(|mint_pubkey| {
let spl_token_decimals = mint_decimals.get(&mint_pubkey).cloned().or_else(|| {
let (_, decimals) = get_mint_owner_and_decimals(&bank, &mint_pubkey).ok()?;
mint_decimals.insert(mint_pubkey, decimals);
Some(decimals)
});
AccountAdditionalData { spl_token_decimals }
});
let maybe_encoded_account = UiAccount::encode(
&pubkey,
account,
UiAccountEncoding::JsonParsed,
additional_data,
None,
);
if let UiAccountData::Json(_) = &maybe_encoded_account.data {
Some(RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: maybe_encoded_account,
})
} else {
None
}
})
}
/// Analyze a passed Pubkey that may be a Token program id or Mint address to determine the program
/// id and optional Mint
fn get_token_program_id_and_mint(
@ -2075,28 +2017,6 @@ fn get_token_program_id_and_mint(
}
}
/// Analyze a mint Pubkey that may be the native_mint and get the mint-account owner (token
/// program_id) and decimals
fn get_mint_owner_and_decimals(bank: &Arc<Bank>, mint: &Pubkey) -> Result<(Pubkey, u8)> {
if mint == &spl_token_v2_0_native_mint() {
Ok((spl_token_id_v2_0(), spl_token_v2_0::native_mint::DECIMALS))
} else {
let mint_account = bank.get_account(mint).ok_or_else(|| {
Error::invalid_params("Invalid param: could not find mint".to_string())
})?;
let decimals = get_mint_decimals(&mint_account.data())?;
Ok((*mint_account.owner(), decimals))
}
}
fn get_mint_decimals(data: &[u8]) -> Result<u8> {
Mint::unpack(data)
.map_err(|_| {
Error::invalid_params("Invalid param: Token mint could not be unpacked".to_string())
})
.map(|mint| mint.decimals)
}
fn _send_transaction(
meta: JsonRpcRequestProcessor,
transaction: Transaction,
@ -3751,12 +3671,7 @@ pub mod tests {
use super::{rpc_full::*, rpc_minimal::*, *};
use crate::{
contact_info::ContactInfo,
non_circulating_supply::non_circulating_accounts,
optimistically_confirmed_bank_tracker::{
BankNotification, OptimisticallyConfirmedBankTracker,
},
replay_stage::tests::create_test_transactions_and_populate_blockstore,
rpc_subscriptions::RpcSubscriptions,
};
use bincode::deserialize;
use jsonrpc_core::{futures, ErrorCode, MetaIoHandler, Output, Response, Value};
@ -3767,8 +3682,15 @@ pub mod tests {
blockstore_processor::fill_blockstore_slot_with_ticks,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use solana_rpc::{
optimistically_confirmed_bank_tracker::{
BankNotification, OptimisticallyConfirmedBankTracker,
},
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
accounts_background_service::AbsRequestSender, commitment::BlockCommitment,
non_circulating_supply::non_circulating_accounts,
};
use solana_sdk::{
account::Account,

View File

@ -3,8 +3,6 @@
use crate::{
bigtable_upload_service::BigTableUploadService,
cluster_info::ClusterInfo,
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
poh_recorder::PohRecorder,
rpc::{rpc_deprecated_v1_7::*, rpc_full::*, rpc_minimal::*, rpc_obsolete_v1_7::*, *},
rpc_health::*,
@ -20,6 +18,9 @@ use regex::Regex;
use solana_client::rpc_cache::LargestAccountsCache;
use solana_ledger::{blockstore::Blockstore, leader_schedule_cache::LeaderScheduleCache};
use solana_metrics::inc_new_counter_info;
use solana_rpc::{
max_slots::MaxSlots, optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
};
use solana_runtime::{
bank_forks::{BankForks, SnapshotConfig},
commitment::BlockCommitmentCache,
@ -239,7 +240,8 @@ fn process_rest(bank_forks: &Arc<RwLock<BankForks>>, path: &str) -> Option<Strin
let bank = r_bank_forks.root_bank();
let total_supply = bank.capitalization();
let non_circulating_supply =
crate::non_circulating_supply::calculate_non_circulating_supply(&bank).lamports;
solana_runtime::non_circulating_supply::calculate_non_circulating_supply(&bank)
.lamports;
Some(format!(
"{}",
lamports_to_sol(total_supply - non_circulating_supply)

View File

@ -10,14 +10,16 @@ use crate::{
VerifiedVoteSender, VoteTracker,
},
fetch_stage::FetchStage,
optimistically_confirmed_bank_tracker::BankNotificationSender,
poh_recorder::{PohRecorder, WorkingBankEntry},
rpc_subscriptions::RpcSubscriptions,
sigverify::TransactionSigVerifier,
sigverify_stage::SigVerifyStage,
};
use crossbeam_channel::unbounded;
use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusSender};
use solana_rpc::{
optimistically_confirmed_bank_tracker::BankNotificationSender,
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
bank_forks::BankForks,
vote_sender_types::{ReplayVoteReceiver, ReplayVoteSender},

View File

@ -14,13 +14,10 @@ use crate::{
completed_data_sets_service::CompletedDataSetsSender,
consensus::Tower,
ledger_cleanup_service::LedgerCleanupService,
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::BankNotificationSender,
poh_recorder::PohRecorder,
replay_stage::{ReplayStage, ReplayStageConfig},
retransmit_stage::RetransmitStage,
rewards_recorder_service::RewardsRecorderSender,
rpc_subscriptions::RpcSubscriptions,
shred_fetch_stage::ShredFetchStage,
sigverify_shreds::ShredSigVerifier,
sigverify_stage::SigVerifyStage,
@ -32,6 +29,10 @@ use solana_ledger::{
blockstore_processor::TransactionStatusSender,
leader_schedule_cache::LeaderScheduleCache,
};
use solana_rpc::{
max_slots::MaxSlots, optimistically_confirmed_bank_tracker::BankNotificationSender,
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
accounts_background_service::{
AbsRequestHandler, AbsRequestSender, AccountsBackgroundService, SendDroppedBankCallback,
@ -333,7 +334,6 @@ pub mod tests {
use crate::{
banking_stage::create_test_recorder,
cluster_info::{ClusterInfo, Node},
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
};
use serial_test::serial;
use solana_ledger::{
@ -341,6 +341,7 @@ pub mod tests {
create_new_tmp_ledger,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use solana_rpc::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank;
use solana_runtime::bank::Bank;
use std::sync::atomic::Ordering;

View File

@ -12,17 +12,11 @@ use crate::{
consensus::{reconcile_blockstore_roots_with_tower, Tower},
contact_info::ContactInfo,
gossip_service::GossipService,
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::{
OptimisticallyConfirmedBank, OptimisticallyConfirmedBankTracker,
},
poh_recorder::{PohRecorder, GRACE_TICKS_FACTOR, MAX_GRACE_SLOTS},
poh_service::{self, PohService},
rewards_recorder_service::{RewardsRecorderSender, RewardsRecorderService},
rpc::JsonRpcConfig,
rpc_pubsub_service::{PubSubConfig, PubSubService},
rpc_service::JsonRpcService,
rpc_subscriptions::RpcSubscriptions,
sample_performance_service::SamplePerformanceService,
serve_repair::ServeRepair,
serve_repair_service::ServeRepairService,
@ -45,6 +39,14 @@ use solana_ledger::{
};
use solana_measure::measure::Measure;
use solana_metrics::datapoint_info;
use solana_rpc::{
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::{
OptimisticallyConfirmedBank, OptimisticallyConfirmedBankTracker,
},
rpc_pubsub_service::{PubSubConfig, PubSubService},
rpc_subscriptions::RpcSubscriptions,
};
use solana_runtime::{
accounts_index::AccountSecondaryIndexes,
bank::Bank,

View File

@ -1,9 +1,9 @@
use solana_client::{pubsub_client::PubsubClient, rpc_client::RpcClient, rpc_response::SlotInfo};
use solana_core::{
use solana_core::test_validator::TestValidator;
use solana_rpc::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc_pubsub_service::{PubSubConfig, PubSubService},
rpc_subscriptions::RpcSubscriptions,
test_validator::TestValidator,
};
use solana_runtime::{
bank::Bank,

View File

@ -11,7 +11,8 @@ use solana_client::{
rpc_response::{Response, RpcSignatureResult, SlotUpdate},
tpu_client::{TpuClient, TpuClientConfig},
};
use solana_core::{rpc_pubsub::gen_client::Client as PubsubClient, test_validator::TestValidator};
use solana_core::test_validator::TestValidator;
use solana_rpc::rpc_pubsub::gen_client::Client as PubsubClient;
use solana_sdk::{
commitment_config::CommitmentConfig,
hash::Hash,

44
rpc/Cargo.toml Normal file
View File

@ -0,0 +1,44 @@
[package]
name = "solana-rpc"
version = "1.7.0"
description = "Solana RPC"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-rpc"
edition = "2018"
[dependencies]
bs58 = "0.3.1"
crossbeam-channel = "0.4"
jsonrpc-core = "17.0.0"
jsonrpc-core-client = { version = "17.0.0", features = ["ipc", "ws"] }
jsonrpc-derive = "17.0.0"
jsonrpc-pubsub = "17.0.0"
jsonrpc-ws-server = "17.0.0"
log = "0.4.11"
serde = "1.0.122"
serde_derive = "1.0.103"
serde_json = "1.0.56"
solana-account-decoder = { path = "../account-decoder", version = "=1.7.0" }
solana-client = { path = "../client", version = "=1.7.0" }
solana-ledger = { path = "../ledger", version = "=1.7.0" }
solana-measure = { path = "../measure", version = "=1.7.0" }
solana-metrics = { path = "../metrics", version = "=1.7.0" }
solana-runtime = { path = "../runtime", version = "=1.7.0" }
solana-sdk = { path = "../sdk", version = "=1.7.0" }
solana-vote-program = { path = "../programs/vote", version = "=1.7.0" }
spl-token-v2-0 = { package = "spl-token", version = "=3.1.0", features = ["no-entrypoint"] }
[dev-dependencies]
serial_test = "0.4.0"
solana-stake-program = { path = "../programs/stake", version = "=1.7.0" }
tokio = { version = "1", features = ["full"] }
[lib]
crate-type = ["lib"]
name = "solana_rpc"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

21
rpc/src/lib.rs Normal file
View File

@ -0,0 +1,21 @@
#![allow(clippy::integer_arithmetic)]
pub mod max_slots;
pub mod optimistically_confirmed_bank_tracker;
pub mod parsed_token_accounts;
pub mod rpc_completed_slots_service;
pub mod rpc_pubsub;
pub mod rpc_pubsub_service;
pub mod rpc_subscriptions;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate solana_metrics;

View File

@ -2,19 +2,21 @@
//! most recent optimistically confirmed bank for use in rpc services, and triggers gossip
//! subscription notifications
use crate::rpc_subscriptions::RpcSubscriptions;
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
use solana_client::rpc_response::{SlotTransactionStats, SlotUpdate};
use solana_runtime::{bank::Bank, bank_forks::BankForks};
use solana_sdk::{clock::Slot, timing::timestamp};
use std::{
collections::HashSet,
sync::{
atomic::{AtomicBool, Ordering},
Arc, RwLock,
use {
crate::rpc_subscriptions::RpcSubscriptions,
crossbeam_channel::{Receiver, RecvTimeoutError, Sender},
solana_client::rpc_response::{SlotTransactionStats, SlotUpdate},
solana_runtime::{bank::Bank, bank_forks::BankForks},
solana_sdk::{clock::Slot, timing::timestamp},
std::{
collections::HashSet,
sync::{
atomic::{AtomicBool, Ordering},
Arc, RwLock,
},
thread::{self, Builder, JoinHandle},
time::Duration,
},
thread::{self, Builder, JoinHandle},
time::Duration,
};
pub struct OptimisticallyConfirmedBank {
@ -103,7 +105,7 @@ impl OptimisticallyConfirmedBankTracker {
Ok(())
}
pub(crate) fn process_notification(
pub fn process_notification(
notification: BankNotification,
bank_forks: &Arc<RwLock<BankForks>>,
optimistically_confirmed_bank: &Arc<RwLock<OptimisticallyConfirmedBank>>,
@ -190,12 +192,14 @@ impl OptimisticallyConfirmedBankTracker {
#[cfg(test)]
mod tests {
use super::*;
use solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo};
use solana_runtime::{
accounts_background_service::AbsRequestSender, commitment::BlockCommitmentCache,
use {
super::*,
solana_ledger::genesis_utils::{create_genesis_config, GenesisConfigInfo},
solana_runtime::{
accounts_background_service::AbsRequestSender, commitment::BlockCommitmentCache,
},
solana_sdk::pubkey::Pubkey,
};
use solana_sdk::pubkey::Pubkey;
#[test]
fn test_process_notification() {

View File

@ -0,0 +1,94 @@
use {
jsonrpc_core::{Error, Result},
solana_account_decoder::{
parse_account_data::AccountAdditionalData,
parse_token::{get_token_account_mint, spl_token_id_v2_0, spl_token_v2_0_native_mint},
UiAccount, UiAccountData, UiAccountEncoding,
},
solana_client::rpc_response::RpcKeyedAccount,
solana_runtime::bank::Bank,
solana_sdk::{
account::{AccountSharedData, ReadableAccount},
pubkey::Pubkey,
},
spl_token_v2_0::{solana_program::program_pack::Pack, state::Mint},
std::{collections::HashMap, sync::Arc},
};
pub fn get_parsed_token_account(
bank: Arc<Bank>,
pubkey: &Pubkey,
account: AccountSharedData,
) -> UiAccount {
let additional_data = get_token_account_mint(&account.data())
.and_then(|mint_pubkey| get_mint_owner_and_decimals(&bank, &mint_pubkey).ok())
.map(|(_, decimals)| AccountAdditionalData {
spl_token_decimals: Some(decimals),
});
UiAccount::encode(
pubkey,
account,
UiAccountEncoding::JsonParsed,
additional_data,
None,
)
}
pub fn get_parsed_token_accounts<I>(
bank: Arc<Bank>,
keyed_accounts: I,
) -> impl Iterator<Item = RpcKeyedAccount>
where
I: Iterator<Item = (Pubkey, AccountSharedData)>,
{
let mut mint_decimals: HashMap<Pubkey, u8> = HashMap::new();
keyed_accounts.filter_map(move |(pubkey, account)| {
let additional_data = get_token_account_mint(&account.data()).map(|mint_pubkey| {
let spl_token_decimals = mint_decimals.get(&mint_pubkey).cloned().or_else(|| {
let (_, decimals) = get_mint_owner_and_decimals(&bank, &mint_pubkey).ok()?;
mint_decimals.insert(mint_pubkey, decimals);
Some(decimals)
});
AccountAdditionalData { spl_token_decimals }
});
let maybe_encoded_account = UiAccount::encode(
&pubkey,
account,
UiAccountEncoding::JsonParsed,
additional_data,
None,
);
if let UiAccountData::Json(_) = &maybe_encoded_account.data {
Some(RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: maybe_encoded_account,
})
} else {
None
}
})
}
/// Analyze a mint Pubkey that may be the native_mint and get the mint-account owner (token
/// program_id) and decimals
pub fn get_mint_owner_and_decimals(bank: &Arc<Bank>, mint: &Pubkey) -> Result<(Pubkey, u8)> {
if mint == &spl_token_v2_0_native_mint() {
Ok((spl_token_id_v2_0(), spl_token_v2_0::native_mint::DECIMALS))
} else {
let mint_account = bank.get_account(mint).ok_or_else(|| {
Error::invalid_params("Invalid param: could not find mint".to_string())
})?;
let decimals = get_mint_decimals(&mint_account.data())?;
Ok((*mint_account.owner(), decimals))
}
}
fn get_mint_decimals(data: &[u8]) -> Result<u8> {
Mint::unpack(data)
.map_err(|_| {
Error::invalid_params("Invalid param: Token mint could not be unpacked".to_string())
})
.map(|mint| mint.decimals)
}

View File

@ -1,10 +1,12 @@
use crate::rpc_subscriptions::RpcSubscriptions;
use solana_client::rpc_response::SlotUpdate;
use solana_ledger::blockstore::CompletedSlotsReceiver;
use solana_sdk::timing::timestamp;
use std::{
sync::Arc,
thread::{Builder, JoinHandle},
use {
crate::rpc_subscriptions::RpcSubscriptions,
solana_client::rpc_response::SlotUpdate,
solana_ledger::blockstore::CompletedSlotsReceiver,
solana_sdk::timing::timestamp,
std::{
sync::Arc,
thread::{Builder, JoinHandle},
},
};
pub struct RpcCompletedSlotsService;

View File

@ -1,28 +1,30 @@
//! The `pubsub` module implements a threaded subscription service on client RPC request
use crate::rpc_subscriptions::{RpcSubscriptions, RpcVote};
use jsonrpc_core::{Error, ErrorCode, Result};
use jsonrpc_derive::rpc;
use jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId};
use solana_account_decoder::UiAccount;
use solana_client::{
rpc_config::{
RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSignatureSubscribeConfig,
RpcTransactionLogsConfig, RpcTransactionLogsFilter,
},
rpc_response::{
Response as RpcResponse, RpcKeyedAccount, RpcLogsResponse, RpcSignatureResult, SlotInfo,
SlotUpdate,
},
};
#[cfg(test)]
use solana_runtime::bank_forks::BankForks;
use solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature};
#[cfg(test)]
use std::sync::RwLock;
use std::{
str::FromStr,
sync::{atomic, Arc},
use {
crate::rpc_subscriptions::{RpcSubscriptions, RpcVote},
jsonrpc_core::{Error, ErrorCode, Result},
jsonrpc_derive::rpc,
jsonrpc_pubsub::{typed::Subscriber, Session, SubscriptionId},
solana_account_decoder::UiAccount,
solana_client::{
rpc_config::{
RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSignatureSubscribeConfig,
RpcTransactionLogsConfig, RpcTransactionLogsFilter,
},
rpc_response::{
Response as RpcResponse, RpcKeyedAccount, RpcLogsResponse, RpcSignatureResult,
SlotInfo, SlotUpdate,
},
},
solana_sdk::{clock::Slot, pubkey::Pubkey, signature::Signature},
std::{
str::FromStr,
sync::{atomic, Arc},
},
};
const MAX_ACTIVE_SUBSCRIPTIONS: usize = 100_000;
@ -540,46 +542,46 @@ impl RpcSolPubSub for RpcSolPubSubImpl {
#[cfg(test)]
mod tests {
use super::*;
use crate::{
cluster_info_vote_listener::{ClusterInfoVoteListener, VoteTracker},
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc_subscriptions::tests::robust_poll_or_panic,
};
use crossbeam_channel::unbounded;
use jsonrpc_core::{futures::channel::mpsc, Response};
use jsonrpc_pubsub::{PubSubHandler, Session};
use serial_test::serial;
use solana_account_decoder::{parse_account_data::parse_account_data, UiAccountEncoding};
use solana_client::rpc_response::{ProcessedSignatureResult, ReceivedSignatureResult};
use solana_runtime::{
bank::Bank,
bank_forks::BankForks,
commitment::{BlockCommitmentCache, CommitmentSlots},
genesis_utils::{
create_genesis_config, create_genesis_config_with_vote_accounts, GenesisConfigInfo,
ValidatorVoteKeypairs,
use {
super::*,
crate::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc_subscriptions::tests::robust_poll_or_panic,
},
jsonrpc_core::{futures::channel::mpsc, Response},
jsonrpc_pubsub::{PubSubHandler, Session},
serial_test::serial,
solana_account_decoder::{parse_account_data::parse_account_data, UiAccountEncoding},
solana_client::rpc_response::{ProcessedSignatureResult, ReceivedSignatureResult},
solana_runtime::{
bank::Bank,
bank_forks::BankForks,
commitment::{BlockCommitmentCache, CommitmentSlots},
genesis_utils::{
create_genesis_config, create_genesis_config_with_vote_accounts, GenesisConfigInfo,
ValidatorVoteKeypairs,
},
},
solana_sdk::{
account::ReadableAccount,
commitment_config::CommitmentConfig,
hash::Hash,
message::Message,
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction, system_program, system_transaction,
transaction::{self, Transaction},
},
solana_stake_program::{
self, stake_instruction,
stake_state::{Authorized, Lockup, StakeAuthorize, StakeState},
},
solana_vote_program::vote_state::Vote,
std::{
sync::{atomic::AtomicBool, RwLock},
thread::sleep,
time::Duration,
},
};
use solana_sdk::{
account::ReadableAccount,
commitment_config::CommitmentConfig,
hash::Hash,
message::Message,
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction, system_program, system_transaction,
transaction::{self, Transaction},
};
use solana_stake_program::{
self, stake_instruction,
stake_state::{Authorized, Lockup, StakeAuthorize, StakeState},
};
use solana_vote_program::vote_transaction;
use std::{
sync::{atomic::AtomicBool, RwLock},
thread::sleep,
time::Duration,
};
fn process_transaction_and_notify(
@ -1227,9 +1229,7 @@ mod tests {
);
let exit = Arc::new(AtomicBool::new(false));
let bank = Bank::new(&genesis_config);
let bank_forks = BankForks::new(bank);
let bank = bank_forks.get(0).unwrap().clone();
let bank_forks = Arc::new(RwLock::new(bank_forks));
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
// Setup RPC
let mut rpc = RpcSolPubSubImpl::default_with_bank_forks(bank_forks.clone());
@ -1239,52 +1239,22 @@ mod tests {
// Setup Subscriptions
let optimistically_confirmed_bank =
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
let subscriptions = RpcSubscriptions::new_with_vote_subscription(
let subscriptions = Arc::new(RpcSubscriptions::new_with_vote_subscription(
&exit,
bank_forks,
block_commitment_cache,
optimistically_confirmed_bank,
true,
);
rpc.subscriptions = Arc::new(subscriptions);
));
rpc.subscriptions = subscriptions.clone();
rpc.vote_subscribe(session, subscriber);
// Create some voters at genesis
let vote_tracker = VoteTracker::new(&bank);
let (votes_sender, votes_receiver) = unbounded();
let (vote_tracker, validator_voting_keypairs) =
(Arc::new(vote_tracker), validator_voting_keypairs);
let vote_slots = vec![1, 2];
validator_voting_keypairs.iter().for_each(|keypairs| {
let node_keypair = &keypairs.node_keypair;
let vote_keypair = &keypairs.vote_keypair;
let vote_tx = vote_transaction::new_vote_transaction(
vote_slots.clone(),
Hash::default(),
Hash::default(),
node_keypair,
vote_keypair,
vote_keypair,
None,
);
votes_sender.send(vec![vote_tx]).unwrap();
});
// Process votes and check they were notified.
let (verified_vote_sender, _verified_vote_receiver) = unbounded();
let (gossip_verified_vote_hash_sender, _gossip_verified_vote_hash_receiver) = unbounded();
let (_replay_votes_sender, replay_votes_receiver) = unbounded();
ClusterInfoVoteListener::get_and_process_votes_for_tests(
&votes_receiver,
&vote_tracker,
&bank,
&rpc.subscriptions,
&gossip_verified_vote_hash_sender,
&verified_vote_sender,
&replay_votes_receiver,
)
.unwrap();
let vote = Vote {
slots: vec![1, 2],
hash: Hash::default(),
timestamp: None,
};
subscriptions.notify_vote(&vote);
let (response, _) = robust_poll_or_panic(receiver);
assert_eq!(

View File

@ -1,19 +1,21 @@
//! The `pubsub` module implements a threaded subscription service on client RPC request
use crate::{
rpc_pubsub::{RpcSolPubSub, RpcSolPubSubImpl},
rpc_subscriptions::RpcSubscriptions,
};
use jsonrpc_pubsub::{PubSubHandler, Session};
use jsonrpc_ws_server::{RequestContext, ServerBuilder};
use std::{
net::SocketAddr,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
use {
crate::{
rpc_pubsub::{RpcSolPubSub, RpcSolPubSubImpl},
rpc_subscriptions::RpcSubscriptions,
},
jsonrpc_pubsub::{PubSubHandler, Session},
jsonrpc_ws_server::{RequestContext, ServerBuilder},
std::{
net::SocketAddr,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread::{self, sleep, Builder, JoinHandle},
time::Duration,
},
thread::{self, sleep, Builder, JoinHandle},
time::Duration,
};
#[derive(Debug, Clone)]
@ -105,17 +107,19 @@ impl PubSubService {
#[cfg(test)]
mod tests {
use super::*;
use crate::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank;
use solana_runtime::{
bank::Bank,
bank_forks::BankForks,
commitment::BlockCommitmentCache,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use std::{
net::{IpAddr, Ipv4Addr},
sync::RwLock,
use {
super::*,
crate::optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
solana_runtime::{
bank::Bank,
bank_forks::BankForks,
commitment::BlockCommitmentCache,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
},
std::{
net::{IpAddr, Ipv4Addr},
sync::RwLock,
},
};
#[test]

View File

@ -1,52 +1,54 @@
//! The `pubsub` module implements a threaded subscription service on client RPC request
use crate::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
rpc::{get_parsed_token_account, get_parsed_token_accounts},
};
use core::hash::Hash;
use jsonrpc_pubsub::{
typed::{Sink, Subscriber},
SubscriptionId,
};
use serde::Serialize;
use solana_account_decoder::{parse_token::spl_token_id_v2_0, UiAccount, UiAccountEncoding};
use solana_client::{
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSignatureSubscribeConfig},
rpc_filter::RpcFilterType,
rpc_response::{
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcKeyedAccount,
RpcLogsResponse, RpcResponseContext, RpcSignatureResult, SlotInfo, SlotUpdate,
use {
crate::{
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
parsed_token_accounts::{get_parsed_token_account, get_parsed_token_accounts},
},
};
use solana_measure::measure::Measure;
use solana_runtime::{
bank::{
Bank, TransactionLogCollectorConfig, TransactionLogCollectorFilter, TransactionLogInfo,
core::hash::Hash,
jsonrpc_pubsub::{
typed::{Sink, Subscriber},
SubscriptionId,
},
bank_forks::BankForks,
commitment::{BlockCommitmentCache, CommitmentSlots},
};
use solana_sdk::{
account::{AccountSharedData, ReadableAccount},
clock::{Slot, UnixTimestamp},
commitment_config::CommitmentConfig,
pubkey::Pubkey,
signature::Signature,
timing::timestamp,
transaction,
};
use solana_vote_program::vote_state::Vote;
use std::{
collections::{HashMap, HashSet},
iter,
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{Receiver, RecvTimeoutError, SendError, Sender},
serde::Serialize,
solana_account_decoder::{parse_token::spl_token_id_v2_0, UiAccount, UiAccountEncoding},
solana_client::{
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSignatureSubscribeConfig},
rpc_filter::RpcFilterType,
rpc_response::{
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcKeyedAccount,
RpcLogsResponse, RpcResponseContext, RpcSignatureResult, SlotInfo, SlotUpdate,
},
},
solana_measure::measure::Measure,
solana_runtime::{
bank::{
Bank, TransactionLogCollectorConfig, TransactionLogCollectorFilter, TransactionLogInfo,
},
bank_forks::BankForks,
commitment::{BlockCommitmentCache, CommitmentSlots},
},
solana_sdk::{
account::{AccountSharedData, ReadableAccount},
clock::{Slot, UnixTimestamp},
commitment_config::CommitmentConfig,
pubkey::Pubkey,
signature::Signature,
timing::timestamp,
transaction,
},
solana_vote_program::vote_state::Vote,
std::{
collections::{HashMap, HashSet},
iter,
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{Receiver, RecvTimeoutError, SendError, Sender},
},
sync::{Arc, Mutex, RwLock},
thread::{Builder, JoinHandle},
time::Duration,
},
sync::{Arc, Mutex, RwLock},
thread::{Builder, JoinHandle},
time::Duration,
};
const RECEIVE_DELAY_MILLIS: u64 = 100;
@ -1326,27 +1328,29 @@ impl RpcSubscriptions {
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use crate::optimistically_confirmed_bank_tracker::{
BankNotification, OptimisticallyConfirmedBank, OptimisticallyConfirmedBankTracker,
};
use jsonrpc_core::futures::StreamExt;
use jsonrpc_pubsub::typed::Subscriber;
use serial_test::serial;
use solana_runtime::{
commitment::BlockCommitment,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use solana_sdk::{
message::Message,
signature::{Keypair, Signer},
system_instruction, system_program, system_transaction,
transaction::Transaction,
};
use std::{fmt::Debug, sync::mpsc::channel};
use tokio::{
runtime::Runtime,
time::{sleep, timeout},
use {
super::*,
crate::optimistically_confirmed_bank_tracker::{
BankNotification, OptimisticallyConfirmedBank, OptimisticallyConfirmedBankTracker,
},
jsonrpc_core::futures::StreamExt,
jsonrpc_pubsub::typed::Subscriber,
serial_test::serial,
solana_runtime::{
commitment::BlockCommitment,
genesis_utils::{create_genesis_config, GenesisConfigInfo},
},
solana_sdk::{
message::Message,
signature::{Keypair, Signer},
system_instruction, system_program, system_transaction,
transaction::Transaction,
},
std::{fmt::Debug, sync::mpsc::channel},
tokio::{
runtime::Runtime,
time::{sleep, timeout},
},
};
pub(crate) fn robust_poll_or_panic<T: Debug + Send + 'static>(

View File

@ -26,6 +26,7 @@ pub mod loader_utils;
pub mod log_collector;
pub mod message_processor;
mod native_loader;
pub mod non_circulating_supply;
mod read_only_accounts_cache;
pub mod rent_collector;
pub mod secondary_index;

View File

@ -1,10 +1,13 @@
use solana_runtime::{
accounts_index::{AccountIndex, IndexKey},
bank::Bank,
use {
crate::{
accounts_index::{AccountIndex, IndexKey},
bank::Bank,
},
log::*,
solana_sdk::{account::ReadableAccount, pubkey::Pubkey},
solana_stake_program::stake_state::StakeState,
std::{collections::HashSet, sync::Arc},
};
use solana_sdk::{account::ReadableAccount, pubkey::Pubkey};
use solana_stake_program::stake_state::StakeState;
use std::{collections::HashSet, sync::Arc};
pub struct NonCirculatingSupply {
pub lamports: u64,

View File

@ -39,6 +39,7 @@ solana-logger = { path = "../logger", version = "=1.7.0" }
solana-metrics = { path = "../metrics", version = "=1.7.0" }
solana-net-utils = { path = "../net-utils", version = "=1.7.0" }
solana-perf = { path = "../perf", version = "=1.7.0" }
solana-rpc = { path = "../rpc", version = "=1.7.0" }
solana-runtime = { path = "../runtime", version = "=1.7.0" }
solana-sdk = { path = "../sdk", version = "=1.7.0" }
solana-version = { path = "../version", version = "=1.7.0" }

View File

@ -29,7 +29,6 @@ use {
gossip_service::GossipService,
poh_service,
rpc::JsonRpcConfig,
rpc_pubsub_service::PubSubConfig,
tpu::DEFAULT_TPU_COALESCE_MS,
validator::{
is_snapshot_config_invalid, Validator, ValidatorConfig, ValidatorStartProgress,
@ -38,6 +37,7 @@ use {
solana_download_utils::{download_genesis_if_missing, download_snapshot},
solana_ledger::blockstore_db::BlockstoreRecoveryMode,
solana_perf::recycler::enable_recycler_warming,
solana_rpc::rpc_pubsub_service::PubSubConfig,
solana_runtime::{
accounts_index::{
AccountIndex, AccountSecondaryIndexes, AccountSecondaryIndexesIncludeExclude,