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,
commitment::{BlockCommitment, BlockCommitmentCache},
contact_info::ContactInfo,
gen_keys::GenKeys,
packet::PACKET_DATA_SIZE,
storage_stage::StorageState,
validator::ValidatorExit,
@ -13,7 +14,9 @@ use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc;
use solana_client::rpc_request::{RpcEpochInfo, RpcVoteAccountInfo, RpcVoteAccountStatus};
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_sdk::{
account::Account,
@ -23,9 +26,11 @@ use solana_sdk::{
fee_calculator::FeeCalculator,
hash::Hash,
inflation::Inflation,
instruction::InstructionError,
pubkey::Pubkey,
signature::Signature,
transaction::{self, Transaction},
signature::{KeypairUtil, Signature},
system_transaction,
transaction::{self, Transaction, TransactionError},
};
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{
@ -54,8 +59,9 @@ impl Default for JsonRpcConfig {
pub struct JsonRpcRequestProcessor {
bank_forks: Arc<RwLock<BankForks>>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
storage_state: StorageState,
blocktree: Arc<Blocktree>,
config: JsonRpcConfig,
storage_state: StorageState,
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
}
@ -75,17 +81,19 @@ impl JsonRpcRequestProcessor {
}
pub fn new(
storage_state: StorageState,
config: JsonRpcConfig,
bank_forks: Arc<RwLock<BankForks>>,
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
blocktree: Arc<Blocktree>,
storage_state: StorageState,
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
) -> Self {
JsonRpcRequestProcessor {
config,
bank_forks,
block_commitment_cache,
blocktree,
storage_state,
config,
validator_exit: validator_exit.clone(),
}
}
@ -258,6 +266,21 @@ impl JsonRpcRequestProcessor {
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> {
@ -479,6 +502,16 @@ pub trait RpcSol {
#[rpc(meta, name = "setLogFilter")]
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;
@ -929,6 +962,50 @@ impl RpcSol for RpcSolImpl {
solana_logger::setup_with_filter(&filter);
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)]
@ -939,11 +1016,12 @@ pub mod tests {
genesis_utils::{create_genesis_config, GenesisConfigInfo},
};
use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
use solana_ledger::blocktree::get_tmp_ledger_path;
use solana_sdk::{
fee_calculator::DEFAULT_BURN_PERCENT,
hash::{hash, Hash},
instruction::InstructionError,
signature::{Keypair, KeypairUtil},
signature::Keypair,
system_transaction,
transaction::TransactionError,
};
@ -980,6 +1058,8 @@ pub mod tests {
.or_insert(commitment_slot1.clone());
let block_commitment_cache =
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 exit = Arc::new(AtomicBool::new(false));
@ -993,10 +1073,11 @@ pub mod tests {
let _ = bank.process_transaction(&tx);
let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(),
bank_forks,
block_commitment_cache.clone(),
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
)));
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 = bank_forks.read().unwrap().working_bank();
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(
StorageState::default(),
JsonRpcConfig::default(),
bank_forks,
block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
);
thread::spawn(move || {
@ -1453,6 +1537,8 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit);
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 rpc = RpcSolImpl;
@ -1460,10 +1546,11 @@ pub mod tests {
let meta = Meta {
request_processor: {
let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
JsonRpcConfig::default(),
new_bank_forks().0,
block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
);
Arc::new(RwLock::new(request_processor))
@ -1551,11 +1638,14 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit);
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(
StorageState::default(),
JsonRpcConfig::default(),
new_bank_forks().0,
block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
);
assert_eq!(request_processor.validator_exit(), Ok(false));
@ -1567,13 +1657,16 @@ pub mod tests {
let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit);
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();
config.enable_validator_exit = true;
let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
config,
new_bank_forks().0,
block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
);
assert_eq!(request_processor.validator_exit(), Ok(true));
@ -1616,14 +1709,17 @@ pub mod tests {
.or_insert(commitment_slot1.clone());
let block_commitment_cache =
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();
config.enable_validator_exit = true;
let request_processor = JsonRpcRequestProcessor::new(
StorageState::default(),
config,
new_bank_forks().0,
block_commitment_cache,
Arc::new(blocktree),
StorageState::default(),
&validator_exit,
);
assert_eq!(

View File

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

View File

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