Stub out `getBlocksSince` and `getBlock` methods (#6853)

* Add getBlocksSince rpc method, and initial stub of getBlock method

* Return test transactions from getBlock method

* clippy

* Add comment on get_block method
This commit is contained in:
Tyera Eulberg 2019-11-11 13:18:34 -05:00 committed by GitHub
parent 596d30661a
commit cc6e1ea200
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 31 deletions

View File

@ -4,6 +4,7 @@ use crate::{
cluster_info::ClusterInfo, cluster_info::ClusterInfo,
commitment::{BlockCommitment, BlockCommitmentCache}, commitment::{BlockCommitment, BlockCommitmentCache},
contact_info::ContactInfo, contact_info::ContactInfo,
gen_keys::GenKeys,
packet::PACKET_DATA_SIZE, packet::PACKET_DATA_SIZE,
storage_stage::StorageState, storage_stage::StorageState,
validator::ValidatorExit, validator::ValidatorExit,
@ -13,7 +14,9 @@ use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use solana_client::rpc_request::{RpcEpochInfo, RpcVoteAccountInfo, RpcVoteAccountStatus}; use solana_client::rpc_request::{RpcEpochInfo, RpcVoteAccountInfo, RpcVoteAccountStatus};
use solana_drone::drone::request_airdrop_transaction; use solana_drone::drone::request_airdrop_transaction;
use solana_ledger::bank_forks::BankForks; use solana_ledger::{
bank_forks::BankForks, blocktree::Blocktree, rooted_slot_iterator::RootedSlotIterator,
};
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::{ use solana_sdk::{
account::Account, account::Account,
@ -23,9 +26,11 @@ use solana_sdk::{
fee_calculator::FeeCalculator, fee_calculator::FeeCalculator,
hash::Hash, hash::Hash,
inflation::Inflation, inflation::Inflation,
instruction::InstructionError,
pubkey::Pubkey, pubkey::Pubkey,
signature::Signature, signature::{KeypairUtil, Signature},
transaction::{self, Transaction}, system_transaction,
transaction::{self, Transaction, TransactionError},
}; };
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY}; use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{ use std::{
@ -54,8 +59,9 @@ impl Default for JsonRpcConfig {
pub struct JsonRpcRequestProcessor { pub struct JsonRpcRequestProcessor {
bank_forks: Arc<RwLock<BankForks>>, bank_forks: Arc<RwLock<BankForks>>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>, block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
storage_state: StorageState, blocktree: Arc<Blocktree>,
config: JsonRpcConfig, config: JsonRpcConfig,
storage_state: StorageState,
validator_exit: Arc<RwLock<Option<ValidatorExit>>>, validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
} }
@ -75,17 +81,19 @@ impl JsonRpcRequestProcessor {
} }
pub fn new( pub fn new(
storage_state: StorageState,
config: JsonRpcConfig, config: JsonRpcConfig,
bank_forks: Arc<RwLock<BankForks>>, bank_forks: Arc<RwLock<BankForks>>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>, block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
blocktree: Arc<Blocktree>,
storage_state: StorageState,
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>, validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
) -> Self { ) -> Self {
JsonRpcRequestProcessor { JsonRpcRequestProcessor {
config,
bank_forks, bank_forks,
block_commitment_cache, block_commitment_cache,
blocktree,
storage_state, storage_state,
config,
validator_exit: validator_exit.clone(), validator_exit: validator_exit.clone(),
} }
} }
@ -258,6 +266,21 @@ impl JsonRpcRequestProcessor {
Ok(false) Ok(false)
} }
} }
pub fn get_blocks_since(&self, slot: Slot) -> Result<Vec<Slot>> {
Ok(RootedSlotIterator::new(slot, &self.blocktree)
.map_err(|err| Error::invalid_params(format!("Slot {:?}: {:?}", slot, err)))?
.map(|(slot, _)| slot)
.collect())
}
// The `get_block` method is not fully implemented. It currenlty returns a batch of test transaction
// tuples (Transaction, transaction::Result) to demonstrate message format and
// TransactionErrors. Transaction count == slot, and transaction keys are derived
// deterministically to allow testers to track the pubkeys across slots.
pub fn get_block(&self, slot: Slot) -> Result<Vec<(Transaction, transaction::Result<()>)>> {
Ok(make_test_transactions(slot))
}
} }
fn get_tpu_addr(cluster_info: &Arc<RwLock<ClusterInfo>>) -> Result<SocketAddr> { fn get_tpu_addr(cluster_info: &Arc<RwLock<ClusterInfo>>) -> Result<SocketAddr> {
@ -479,6 +502,16 @@ pub trait RpcSol {
#[rpc(meta, name = "setLogFilter")] #[rpc(meta, name = "setLogFilter")]
fn set_log_filter(&self, _meta: Self::Metadata, filter: String) -> Result<()>; fn set_log_filter(&self, _meta: Self::Metadata, filter: String) -> Result<()>;
#[rpc(meta, name = "getBlocksSince")]
fn get_blocks_since(&self, meta: Self::Metadata, slot: Slot) -> Result<Vec<Slot>>;
#[rpc(meta, name = "getBlock")]
fn get_block(
&self,
meta: Self::Metadata,
slot: Slot,
) -> Result<Vec<(Transaction, transaction::Result<()>)>>;
} }
pub struct RpcSolImpl; pub struct RpcSolImpl;
@ -929,6 +962,50 @@ impl RpcSol for RpcSolImpl {
solana_logger::setup_with_filter(&filter); solana_logger::setup_with_filter(&filter);
Ok(()) Ok(())
} }
fn get_blocks_since(&self, meta: Self::Metadata, slot: Slot) -> Result<Vec<Slot>> {
meta.request_processor
.read()
.unwrap()
.get_blocks_since(slot)
}
fn get_block(
&self,
meta: Self::Metadata,
slot: Slot,
) -> Result<Vec<(Transaction, transaction::Result<()>)>> {
meta.request_processor.read().unwrap().get_block(slot)
}
}
fn make_test_transactions(count: u64) -> Vec<(Transaction, transaction::Result<()>)> {
let seed = [42u8; 32];
let keys = GenKeys::new(seed).gen_n_keypairs(count + 1);
let mut transactions: Vec<(Transaction, transaction::Result<()>)> = Vec::new();
for x in 0..count {
let tx = system_transaction::transfer(
&keys[x as usize],
&keys[(x + 1) as usize].pubkey(),
123,
Hash::default(),
);
let status = if x % 3 == 0 {
Ok(())
} else if x % 3 == 1 {
Err(TransactionError::InstructionError(
0,
InstructionError::InsufficientFunds,
))
} else {
Err(TransactionError::InstructionError(
0,
InstructionError::CustomError(3),
))
};
transactions.push((tx, status))
}
transactions
} }
#[cfg(test)] #[cfg(test)]
@ -939,11 +1016,12 @@ pub mod tests {
genesis_utils::{create_genesis_config, GenesisConfigInfo}, genesis_utils::{create_genesis_config, GenesisConfigInfo},
}; };
use jsonrpc_core::{MetaIoHandler, Output, Response, Value}; use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
use solana_ledger::blocktree::get_tmp_ledger_path;
use solana_sdk::{ use solana_sdk::{
fee_calculator::DEFAULT_BURN_PERCENT, fee_calculator::DEFAULT_BURN_PERCENT,
hash::{hash, Hash}, hash::{hash, Hash},
instruction::InstructionError, instruction::InstructionError,
signature::{Keypair, KeypairUtil}, signature::Keypair,
system_transaction, system_transaction,
transaction::TransactionError, transaction::TransactionError,
}; };
@ -980,6 +1058,8 @@ pub mod tests {
.or_insert(commitment_slot1.clone()); .or_insert(commitment_slot1.clone());
let block_commitment_cache = let block_commitment_cache =
Arc::new(RwLock::new(BlockCommitmentCache::new(block_commitment, 42))); Arc::new(RwLock::new(BlockCommitmentCache::new(block_commitment, 42)));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let leader_pubkey = *bank.collector_id(); let leader_pubkey = *bank.collector_id();
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
@ -993,10 +1073,11 @@ pub mod tests {
let _ = bank.process_transaction(&tx); let _ = bank.process_transaction(&tx);
let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new( let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(), JsonRpcConfig::default(),
bank_forks, bank_forks,
block_commitment_cache.clone(), block_commitment_cache.clone(),
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
))); )));
let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair( let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair(
@ -1038,11 +1119,14 @@ pub mod tests {
let (bank_forks, alice) = new_bank_forks(); let (bank_forks, alice) = new_bank_forks();
let bank = bank_forks.read().unwrap().working_bank(); let bank = bank_forks.read().unwrap().working_bank();
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let request_processor = JsonRpcRequestProcessor::new( let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(), JsonRpcConfig::default(),
bank_forks, bank_forks,
block_commitment_cache, block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
); );
thread::spawn(move || { thread::spawn(move || {
@ -1453,6 +1537,8 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit); let validator_exit = create_validator_exit(&exit);
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let mut io = MetaIoHandler::default(); let mut io = MetaIoHandler::default();
let rpc = RpcSolImpl; let rpc = RpcSolImpl;
@ -1460,10 +1546,11 @@ pub mod tests {
let meta = Meta { let meta = Meta {
request_processor: { request_processor: {
let request_processor = JsonRpcRequestProcessor::new( let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(), JsonRpcConfig::default(),
new_bank_forks().0, new_bank_forks().0,
block_commitment_cache, block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
); );
Arc::new(RwLock::new(request_processor)) Arc::new(RwLock::new(request_processor))
@ -1551,11 +1638,14 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit); let validator_exit = create_validator_exit(&exit);
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let request_processor = JsonRpcRequestProcessor::new( let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(), JsonRpcConfig::default(),
new_bank_forks().0, new_bank_forks().0,
block_commitment_cache, block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
); );
assert_eq!(request_processor.validator_exit(), Ok(false)); assert_eq!(request_processor.validator_exit(), Ok(false));
@ -1567,13 +1657,16 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false)); let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit); let validator_exit = create_validator_exit(&exit);
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let mut config = JsonRpcConfig::default(); let mut config = JsonRpcConfig::default();
config.enable_validator_exit = true; config.enable_validator_exit = true;
let request_processor = JsonRpcRequestProcessor::new( let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
config, config,
new_bank_forks().0, new_bank_forks().0,
block_commitment_cache, block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
); );
assert_eq!(request_processor.validator_exit(), Ok(true)); assert_eq!(request_processor.validator_exit(), Ok(true));
@ -1616,14 +1709,17 @@ pub mod tests {
.or_insert(commitment_slot1.clone()); .or_insert(commitment_slot1.clone());
let block_commitment_cache = let block_commitment_cache =
Arc::new(RwLock::new(BlockCommitmentCache::new(block_commitment, 42))); Arc::new(RwLock::new(BlockCommitmentCache::new(block_commitment, 42)));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let mut config = JsonRpcConfig::default(); let mut config = JsonRpcConfig::default();
config.enable_validator_exit = true; config.enable_validator_exit = true;
let request_processor = JsonRpcRequestProcessor::new( let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
config, config,
new_bank_forks().0, new_bank_forks().0,
block_commitment_cache, block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit, &validator_exit,
); );
assert_eq!( assert_eq!(

View File

@ -9,13 +9,12 @@ use jsonrpc_http_server::{
hyper, AccessControlAllowOrigin, CloseHandle, DomainsValidation, RequestMiddleware, hyper, AccessControlAllowOrigin, CloseHandle, DomainsValidation, RequestMiddleware,
RequestMiddlewareAction, ServerBuilder, RequestMiddlewareAction, ServerBuilder,
}; };
use solana_ledger::bank_forks::BankForks; use solana_ledger::{bank_forks::BankForks, blocktree::Blocktree};
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
use std::{ use std::{
net::SocketAddr, net::SocketAddr,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::mpsc::channel, sync::{mpsc::channel, Arc, RwLock},
sync::{Arc, RwLock},
thread::{self, Builder, JoinHandle}, thread::{self, Builder, JoinHandle},
}; };
use tokio::prelude::Future; use tokio::prelude::Future;
@ -86,24 +85,27 @@ impl RequestMiddleware for RpcRequestMiddleware {
} }
impl JsonRpcService { impl JsonRpcService {
#[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
cluster_info: &Arc<RwLock<ClusterInfo>>,
rpc_addr: SocketAddr, rpc_addr: SocketAddr,
storage_state: StorageState,
config: JsonRpcConfig, config: JsonRpcConfig,
bank_forks: Arc<RwLock<BankForks>>, bank_forks: Arc<RwLock<BankForks>>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>, block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
ledger_path: &Path, blocktree: Arc<Blocktree>,
cluster_info: &Arc<RwLock<ClusterInfo>>,
genesis_hash: Hash, genesis_hash: Hash,
ledger_path: &Path,
storage_state: StorageState,
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>, validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
) -> Self { ) -> Self {
info!("rpc bound to {:?}", rpc_addr); info!("rpc bound to {:?}", rpc_addr);
info!("rpc configuration: {:?}", config); info!("rpc configuration: {:?}", config);
let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new( let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new(
storage_state,
config, config,
bank_forks, bank_forks,
block_commitment_cache, block_commitment_cache,
blocktree,
storage_state,
validator_exit, validator_exit,
))); )));
let request_processor_ = request_processor.clone(); let request_processor_ = request_processor.clone();
@ -174,9 +176,12 @@ impl Service for JsonRpcService {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::contact_info::ContactInfo; use crate::{
use crate::genesis_utils::{create_genesis_config, GenesisConfigInfo}; contact_info::ContactInfo,
use crate::rpc::tests::create_validator_exit; genesis_utils::{create_genesis_config, GenesisConfigInfo},
rpc::tests::create_validator_exit,
};
use solana_ledger::blocktree::get_tmp_ledger_path;
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::signature::KeypairUtil; use solana_sdk::signature::KeypairUtil;
use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::net::{IpAddr, Ipv4Addr, SocketAddr};
@ -201,15 +206,18 @@ mod tests {
); );
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank.slot(), bank))); let bank_forks = Arc::new(RwLock::new(BankForks::new(bank.slot(), bank)));
let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default())); let block_commitment_cache = Arc::new(RwLock::new(BlockCommitmentCache::default()));
let ledger_path = get_tmp_ledger_path!();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let mut rpc_service = JsonRpcService::new( let mut rpc_service = JsonRpcService::new(
&cluster_info,
rpc_addr, rpc_addr,
StorageState::default(),
JsonRpcConfig::default(), JsonRpcConfig::default(),
bank_forks, bank_forks,
block_commitment_cache, block_commitment_cache,
&PathBuf::from("farf"), Arc::new(blocktree),
&cluster_info,
Hash::default(), Hash::default(),
&PathBuf::from("farf"),
StorageState::default(),
&validator_exit, &validator_exit,
); );
let thread = rpc_service.thread_hdl.thread(); let thread = rpc_service.thread_hdl.thread();

View File

@ -199,18 +199,21 @@ impl Validator {
bank.slots_per_segment(), bank.slots_per_segment(),
); );
let blocktree = Arc::new(blocktree);
let rpc_service = if node.info.rpc.port() == 0 { let rpc_service = if node.info.rpc.port() == 0 {
None None
} else { } else {
Some(JsonRpcService::new( Some(JsonRpcService::new(
&cluster_info,
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), node.info.rpc.port()), SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), node.info.rpc.port()),
storage_state.clone(),
config.rpc_config.clone(), config.rpc_config.clone(),
bank_forks.clone(), bank_forks.clone(),
block_commitment_cache.clone(), block_commitment_cache.clone(),
ledger_path, blocktree.clone(),
&cluster_info,
genesis_hash, genesis_hash,
ledger_path,
storage_state.clone(),
&validator_exit, &validator_exit,
)) ))
}; };
@ -244,8 +247,6 @@ impl Validator {
std::thread::park(); std::thread::park();
} }
let blocktree = Arc::new(blocktree);
let poh_config = Arc::new(poh_config); let poh_config = Arc::new(poh_config);
let (mut poh_recorder, entry_receiver) = PohRecorder::new_with_clear_signal( let (mut poh_recorder, entry_receiver) = PohRecorder::new_with_clear_signal(
bank.tick_height(), bank.tick_height(),