Break up RPC API into three categories: minimal, full and admin

This commit is contained in:
Michael Vines
2021-02-26 21:42:09 -08:00
parent 81253c9956
commit 24ab84936e
28 changed files with 1784 additions and 1832 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ use crate::{
max_slots::MaxSlots,
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
poh_recorder::PohRecorder,
rpc::*,
rpc::{rpc_full::*, rpc_minimal::*, *},
rpc_health::*,
send_transaction_service::{LeaderInfo, SendTransactionService},
validator::ValidatorExit,
@ -337,6 +337,7 @@ impl JsonRpcService {
(None, None)
};
let minimal_api = config.minimal_api;
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
config,
snapshot_config.clone(),
@ -392,8 +393,11 @@ impl JsonRpcService {
.name("solana-jsonrpc".to_string())
.spawn(move || {
let mut io = MetaIoHandler::default();
let rpc = RpcSolImpl;
io.extend_with(rpc.to_delegate());
io.extend_with(rpc_minimal::MinimalImpl.to_delegate());
if !minimal_api {
io.extend_with(rpc_full::FullImpl.to_delegate());
}
let request_middleware = RpcRequestMiddleware::new(
ledger_path,

View File

@ -3,7 +3,7 @@ use {
cluster_info::Node,
gossip_service::discover_cluster,
rpc::JsonRpcConfig,
validator::{Validator, ValidatorConfig},
validator::{Validator, ValidatorConfig, ValidatorExit},
},
solana_client::rpc_client::RpcClient,
solana_ledger::{blockstore::create_new_ledger, create_new_tmp_ledger},
@ -28,7 +28,7 @@ use {
fs::remove_dir_all,
net::{IpAddr, Ipv4Addr, SocketAddr},
path::PathBuf,
sync::Arc,
sync::{Arc, RwLock},
thread::sleep,
time::Duration,
},
@ -52,6 +52,7 @@ pub struct TestValidatorGenesis {
no_bpf_jit: bool,
accounts: HashMap<Pubkey, Account>,
programs: Vec<ProgramInfo>,
pub validator_exit: Arc<RwLock<ValidatorExit>>,
}
impl TestValidatorGenesis {
@ -401,6 +402,7 @@ impl TestValidator {
enforce_ulimit_nofile: false,
warp_slot: config.warp_slot,
bpf_jit: !config.no_bpf_jit,
validator_exit: config.validator_exit.clone(),
..ValidatorConfig::default()
};
@ -417,7 +419,8 @@ impl TestValidator {
// Needed to avoid panics in `solana-responder-gossip` in tests that create a number of
// test validators concurrently...
discover_cluster(&gossip, 1).expect("TestValidator startup failed");
discover_cluster(&gossip, 1)
.map_err(|err| format!("TestValidator startup failed: {:?}", err))?;
// This is a hack to delay until the fees are non-zero for test consistency
// (fees from genesis are zero until the first block with a transaction in it is completed
@ -425,19 +428,24 @@ impl TestValidator {
{
let rpc_client =
RpcClient::new_with_commitment(rpc_url.clone(), CommitmentConfig::processed());
let fee_rate_governor = rpc_client
.get_fee_rate_governor()
.expect("get_fee_rate_governor")
.value;
if fee_rate_governor.target_lamports_per_signature > 0 {
while rpc_client
.get_recent_blockhash()
.expect("get_recent_blockhash")
.1
.lamports_per_signature
== 0
{
sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT));
if let Ok(result) = rpc_client.get_fee_rate_governor() {
let fee_rate_governor = result.value;
if fee_rate_governor.target_lamports_per_signature > 0 {
loop {
match rpc_client.get_recent_blockhash() {
Ok((_blockhash, fee_calculator)) => {
if fee_calculator.lamports_per_signature != 0 {
break;
}
}
Err(err) => {
warn!("get_recent_blockhash() failed: {:?}", err);
break;
}
}
sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT));
}
}
}
}
@ -490,6 +498,12 @@ impl TestValidator {
(rpc_client, recent_blockhash, fee_calculator)
}
pub fn join(mut self) {
if let Some(validator) = self.validator.take() {
validator.join();
}
}
}
impl Drop for TestValidator {

View File

@ -188,15 +188,21 @@ impl Default for ValidatorConfig {
#[derive(Default)]
pub struct ValidatorExit {
exited: bool,
exits: Vec<Box<dyn FnOnce() + Send + Sync>>,
}
impl ValidatorExit {
pub fn register_exit(&mut self, exit: Box<dyn FnOnce() + Send + Sync>) {
self.exits.push(exit);
if self.exited {
exit();
} else {
self.exits.push(exit);
}
}
pub fn exit(&mut self) {
self.exited = true;
for exit in self.exits.drain(..) {
exit();
}
@ -219,16 +225,12 @@ struct TransactionHistoryServices {
cache_block_time_service: Option<CacheBlockTimeService>,
}
struct RpcServices {
json_rpc_service: JsonRpcService,
pubsub_service: PubSubService,
optimistically_confirmed_bank_tracker: OptimisticallyConfirmedBankTracker,
}
pub struct Validator {
pub id: Pubkey,
validator_exit: Arc<RwLock<ValidatorExit>>,
rpc_service: Option<RpcServices>,
json_rpc_service: Option<JsonRpcService>,
pubsub_service: Option<PubSubService>,
optimistically_confirmed_bank_tracker: Option<OptimisticallyConfirmedBankTracker>,
transaction_status_service: Option<TransactionStatusService>,
rewards_recorder_service: Option<RewardsRecorderService>,
cache_block_time_service: Option<CacheBlockTimeService>,
@ -475,9 +477,12 @@ impl Validator {
let poh_recorder = Arc::new(Mutex::new(poh_recorder));
let rpc_override_health_check = Arc::new(AtomicBool::new(false));
let (rpc_service, bank_notification_sender) = if let Some((rpc_addr, rpc_pubsub_addr)) =
config.rpc_addrs
{
let (
json_rpc_service,
pubsub_service,
optimistically_confirmed_bank_tracker,
bank_notification_sender,
) = if let Some((rpc_addr, rpc_pubsub_addr)) = config.rpc_addrs {
if ContactInfo::is_valid_address(&node.info.rpc) {
assert!(ContactInfo::is_valid_address(&node.info.rpc_pubsub));
} else {
@ -485,44 +490,46 @@ impl Validator {
}
let (bank_notification_sender, bank_notification_receiver) = unbounded();
(
Some(RpcServices {
json_rpc_service: JsonRpcService::new(
rpc_addr,
config.rpc_config.clone(),
config.snapshot_config.clone(),
bank_forks.clone(),
block_commitment_cache.clone(),
blockstore.clone(),
cluster_info.clone(),
Some(poh_recorder.clone()),
genesis_config.hash(),
ledger_path,
config.validator_exit.clone(),
config.trusted_validators.clone(),
rpc_override_health_check.clone(),
optimistically_confirmed_bank.clone(),
config.send_transaction_retry_ms,
config.send_transaction_leader_forward_count,
max_slots.clone(),
),
pubsub_service: PubSubService::new(
Some(JsonRpcService::new(
rpc_addr,
config.rpc_config.clone(),
config.snapshot_config.clone(),
bank_forks.clone(),
block_commitment_cache.clone(),
blockstore.clone(),
cluster_info.clone(),
Some(poh_recorder.clone()),
genesis_config.hash(),
ledger_path,
config.validator_exit.clone(),
config.trusted_validators.clone(),
rpc_override_health_check.clone(),
optimistically_confirmed_bank.clone(),
config.send_transaction_retry_ms,
config.send_transaction_leader_forward_count,
max_slots.clone(),
)),
if config.rpc_config.minimal_api {
None
} else {
Some(PubSubService::new(
config.pubsub_config.clone(),
&subscriptions,
rpc_pubsub_addr,
&exit,
),
optimistically_confirmed_bank_tracker: OptimisticallyConfirmedBankTracker::new(
bank_notification_receiver,
&exit,
bank_forks.clone(),
optimistically_confirmed_bank,
subscriptions.clone(),
),
}),
))
},
Some(OptimisticallyConfirmedBankTracker::new(
bank_notification_receiver,
&exit,
bank_forks.clone(),
optimistically_confirmed_bank,
subscriptions.clone(),
)),
Some(bank_notification_sender),
)
} else {
(None, None)
(None, None, None, None)
};
if config.dev_halt_at_slot.is_some() {
@ -704,7 +711,9 @@ impl Validator {
id,
gossip_service,
serve_repair_service,
rpc_service,
json_rpc_service,
pubsub_service,
optimistically_confirmed_bank_tracker,
transaction_status_service,
rewards_recorder_service,
cache_block_time_service,
@ -758,18 +767,23 @@ impl Validator {
pub fn join(self) {
self.poh_service.join().expect("poh_service");
drop(self.poh_recorder);
if let Some(RpcServices {
json_rpc_service,
pubsub_service,
optimistically_confirmed_bank_tracker,
}) = self.rpc_service
{
if let Some(json_rpc_service) = self.json_rpc_service {
json_rpc_service.join().expect("rpc_service");
}
if let Some(pubsub_service) = self.pubsub_service {
pubsub_service.join().expect("pubsub_service");
}
if let Some(optimistically_confirmed_bank_tracker) =
self.optimistically_confirmed_bank_tracker
{
optimistically_confirmed_bank_tracker
.join()
.expect("optimistically_confirmed_bank_tracker");
}
if let Some(transaction_status_service) = self.transaction_status_service {
transaction_status_service
.join()