@ -17,6 +17,7 @@ To interact with a Solana node inside a JavaScript application, use the [solana-
|
|||||||
* [confirmTransaction](jsonrpc-api.md#confirmtransaction)
|
* [confirmTransaction](jsonrpc-api.md#confirmtransaction)
|
||||||
* [getAccountInfo](jsonrpc-api.md#getaccountinfo)
|
* [getAccountInfo](jsonrpc-api.md#getaccountinfo)
|
||||||
* [getBalance](jsonrpc-api.md#getbalance)
|
* [getBalance](jsonrpc-api.md#getbalance)
|
||||||
|
* [getBlockConfidence](jsonrpc-api.md#getblockconfidence)
|
||||||
* [getClusterNodes](jsonrpc-api.md#getclusternodes)
|
* [getClusterNodes](jsonrpc-api.md#getclusternodes)
|
||||||
* [getEpochInfo](jsonrpc-api.md#getepochinfo)
|
* [getEpochInfo](jsonrpc-api.md#getepochinfo)
|
||||||
* [getGenesisBlockhash](jsonrpc-api.md#getgenesisblockhash)
|
* [getGenesisBlockhash](jsonrpc-api.md#getgenesisblockhash)
|
||||||
@ -149,6 +150,34 @@ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0", "id":1, "
|
|||||||
{"jsonrpc":"2.0","result":0,"id":1}
|
{"jsonrpc":"2.0","result":0,"id":1}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### getBlockConfidence
|
||||||
|
|
||||||
|
Returns confidence for particular block
|
||||||
|
|
||||||
|
#### Parameters:
|
||||||
|
|
||||||
|
* `u64` - block, identified by Slot
|
||||||
|
|
||||||
|
#### Results:
|
||||||
|
|
||||||
|
The result field will be an array with two fields:
|
||||||
|
|
||||||
|
* Confidence
|
||||||
|
* `null` - Unknown block
|
||||||
|
* `object` - BankConfidence
|
||||||
|
* `array` - confidence, array of u64 integers logging the amount of cluster stake in lamports that has voted on the block at each depth from 0 to `MAX_LOCKOUT_HISTORY`
|
||||||
|
* 'integer' - total active stake, in lamports, of the current epoch
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
// Request
|
||||||
|
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getBlockConfidence","params":[5]}' http://localhost:8899
|
||||||
|
|
||||||
|
// Result
|
||||||
|
{"jsonrpc":"2.0","result":[{"confidence":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32]},42],"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
### getClusterNodes
|
### getClusterNodes
|
||||||
|
|
||||||
Returns information about all the nodes participating in the cluster
|
Returns information about all the nodes participating in the cluster
|
||||||
@ -808,4 +837,3 @@ Unsubscribe from signature confirmation notification
|
|||||||
// Result
|
// Result
|
||||||
{"jsonrpc": "2.0","result": true,"id": 1}
|
{"jsonrpc": "2.0","result": true,"id": 1}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use std::sync::{Arc, RwLock};
|
|||||||
use std::thread::{self, Builder, JoinHandle};
|
use std::thread::{self, Builder, JoinHandle};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct BankConfidence {
|
pub struct BankConfidence {
|
||||||
confidence: [u64; MAX_LOCKOUT_HISTORY],
|
confidence: [u64; MAX_LOCKOUT_HISTORY],
|
||||||
}
|
}
|
||||||
@ -25,25 +25,33 @@ impl BankConfidence {
|
|||||||
assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY);
|
assert!(confirmation_count > 0 && confirmation_count <= MAX_LOCKOUT_HISTORY);
|
||||||
self.confidence[confirmation_count - 1]
|
self.confidence[confirmation_count - 1]
|
||||||
}
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn new(confidence: [u64; MAX_LOCKOUT_HISTORY]) -> Self {
|
||||||
|
Self { confidence }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ForkConfidenceCache {
|
pub struct ForkConfidenceCache {
|
||||||
bank_confidence: HashMap<u64, BankConfidence>,
|
bank_confidence: HashMap<u64, BankConfidence>,
|
||||||
_total_stake: u64,
|
total_stake: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForkConfidenceCache {
|
impl ForkConfidenceCache {
|
||||||
pub fn new(bank_confidence: HashMap<u64, BankConfidence>, total_stake: u64) -> Self {
|
pub fn new(bank_confidence: HashMap<u64, BankConfidence>, total_stake: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bank_confidence,
|
bank_confidence,
|
||||||
_total_stake: total_stake,
|
total_stake,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fork_confidence(&self, fork: u64) -> Option<&BankConfidence> {
|
pub fn get_fork_confidence(&self, fork: u64) -> Option<&BankConfidence> {
|
||||||
self.bank_confidence.get(&fork)
|
self.bank_confidence.get(&fork)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn total_stake(&self) -> u64 {
|
||||||
|
self.total_stake
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ConfidenceAggregationData {
|
pub struct ConfidenceAggregationData {
|
||||||
|
302
core/src/rpc.rs
302
core/src/rpc.rs
@ -1,30 +1,37 @@
|
|||||||
//! The `rpc` module implements the Solana RPC interface.
|
//! The `rpc` module implements the Solana RPC interface.
|
||||||
|
|
||||||
use crate::bank_forks::BankForks;
|
use crate::{
|
||||||
use crate::cluster_info::ClusterInfo;
|
bank_forks::BankForks,
|
||||||
use crate::contact_info::ContactInfo;
|
cluster_info::ClusterInfo,
|
||||||
use crate::packet::PACKET_DATA_SIZE;
|
confidence::{BankConfidence, ForkConfidenceCache},
|
||||||
use crate::storage_stage::StorageState;
|
contact_info::ContactInfo,
|
||||||
use crate::validator::ValidatorExit;
|
packet::PACKET_DATA_SIZE,
|
||||||
use crate::version::VERSION;
|
storage_stage::StorageState,
|
||||||
|
validator::ValidatorExit,
|
||||||
|
version::VERSION,
|
||||||
|
};
|
||||||
use bincode::{deserialize, serialize};
|
use bincode::{deserialize, serialize};
|
||||||
use jsonrpc_core::{Error, Metadata, Result};
|
use jsonrpc_core::{Error, Metadata, Result};
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
use solana_client::rpc_request::RpcEpochInfo;
|
use solana_client::rpc_request::RpcEpochInfo;
|
||||||
use solana_drone::drone::request_airdrop_transaction;
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{
|
||||||
use solana_sdk::fee_calculator::FeeCalculator;
|
account::Account,
|
||||||
use solana_sdk::hash::Hash;
|
fee_calculator::FeeCalculator,
|
||||||
use solana_sdk::inflation::Inflation;
|
hash::Hash,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
inflation::Inflation,
|
||||||
use solana_sdk::signature::Signature;
|
pubkey::Pubkey,
|
||||||
use solana_sdk::transaction::{self, Transaction};
|
signature::Signature,
|
||||||
|
transaction::{self, Transaction},
|
||||||
|
};
|
||||||
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
use solana_vote_api::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
use std::{
|
||||||
use std::sync::{Arc, RwLock};
|
net::{SocketAddr, UdpSocket},
|
||||||
use std::thread::sleep;
|
sync::{Arc, RwLock},
|
||||||
use std::time::{Duration, Instant};
|
thread::sleep,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct JsonRpcConfig {
|
pub struct JsonRpcConfig {
|
||||||
@ -44,6 +51,7 @@ impl Default for JsonRpcConfig {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct JsonRpcRequestProcessor {
|
pub struct JsonRpcRequestProcessor {
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
|
fork_confidence_cache: Arc<RwLock<ForkConfidenceCache>>,
|
||||||
storage_state: StorageState,
|
storage_state: StorageState,
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
|
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
|
||||||
@ -58,10 +66,12 @@ impl JsonRpcRequestProcessor {
|
|||||||
storage_state: StorageState,
|
storage_state: StorageState,
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
|
fork_confidence_cache: Arc<RwLock<ForkConfidenceCache>>,
|
||||||
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
|
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
JsonRpcRequestProcessor {
|
JsonRpcRequestProcessor {
|
||||||
bank_forks,
|
bank_forks,
|
||||||
|
fork_confidence_cache,
|
||||||
storage_state,
|
storage_state,
|
||||||
config,
|
config,
|
||||||
validator_exit: validator_exit.clone(),
|
validator_exit: validator_exit.clone(),
|
||||||
@ -100,6 +110,14 @@ impl JsonRpcRequestProcessor {
|
|||||||
(blockhash.to_string(), fee_calculator)
|
(blockhash.to_string(), fee_calculator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_block_confidence(&self, block: u64) -> (Option<BankConfidence>, u64) {
|
||||||
|
let r_fork_confidence = self.fork_confidence_cache.read().unwrap();
|
||||||
|
(
|
||||||
|
r_fork_confidence.get_fork_confidence(block).cloned(),
|
||||||
|
r_fork_confidence.total_stake(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_signature_status(&self, signature: Signature) -> Option<transaction::Result<()>> {
|
pub fn get_signature_status(&self, signature: Signature) -> Option<transaction::Result<()>> {
|
||||||
self.get_signature_confirmation_status(signature)
|
self.get_signature_confirmation_status(signature)
|
||||||
.map(|x| x.1)
|
.map(|x| x.1)
|
||||||
@ -307,6 +325,13 @@ pub trait RpcSol {
|
|||||||
#[rpc(meta, name = "getEpochInfo")]
|
#[rpc(meta, name = "getEpochInfo")]
|
||||||
fn get_epoch_info(&self, _: Self::Metadata) -> Result<RpcEpochInfo>;
|
fn get_epoch_info(&self, _: Self::Metadata) -> Result<RpcEpochInfo>;
|
||||||
|
|
||||||
|
#[rpc(meta, name = "getBlockConfidence")]
|
||||||
|
fn get_block_confidence(
|
||||||
|
&self,
|
||||||
|
_: Self::Metadata,
|
||||||
|
_: u64,
|
||||||
|
) -> Result<(Option<BankConfidence>, u64)>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getGenesisBlockhash")]
|
#[rpc(meta, name = "getGenesisBlockhash")]
|
||||||
fn get_genesis_blockhash(&self, _: Self::Metadata) -> Result<String>;
|
fn get_genesis_blockhash(&self, _: Self::Metadata) -> Result<String>;
|
||||||
|
|
||||||
@ -487,6 +512,18 @@ impl RpcSol for RpcSolImpl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_block_confidence(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
block: u64,
|
||||||
|
) -> Result<(Option<BankConfidence>, u64)> {
|
||||||
|
Ok(meta
|
||||||
|
.request_processor
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get_block_confidence(block))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_genesis_blockhash(&self, meta: Self::Metadata) -> Result<String> {
|
fn get_genesis_blockhash(&self, meta: Self::Metadata) -> Result<String> {
|
||||||
debug!("get_genesis_blockhash rpc request received");
|
debug!("get_genesis_blockhash rpc request received");
|
||||||
Ok(meta.genesis_blockhash.to_string())
|
Ok(meta.genesis_blockhash.to_string())
|
||||||
@ -708,25 +745,49 @@ impl RpcSol for RpcSolImpl {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::contact_info::ContactInfo;
|
use crate::{
|
||||||
use crate::genesis_utils::{create_genesis_block, GenesisBlockInfo};
|
contact_info::ContactInfo,
|
||||||
|
genesis_utils::{create_genesis_block, GenesisBlockInfo},
|
||||||
|
};
|
||||||
use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
|
use jsonrpc_core::{MetaIoHandler, Output, Response, Value};
|
||||||
use solana_sdk::fee_calculator::DEFAULT_BURN_PERCENT;
|
use solana_sdk::{
|
||||||
use solana_sdk::hash::{hash, Hash};
|
fee_calculator::DEFAULT_BURN_PERCENT,
|
||||||
use solana_sdk::instruction::InstructionError;
|
hash::{hash, Hash},
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
instruction::InstructionError,
|
||||||
use solana_sdk::system_transaction;
|
signature::{Keypair, KeypairUtil},
|
||||||
use solana_sdk::transaction::TransactionError;
|
system_transaction,
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
transaction::TransactionError,
|
||||||
use std::thread;
|
};
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
const TEST_MINT_LAMPORTS: u64 = 10_000;
|
const TEST_MINT_LAMPORTS: u64 = 10_000;
|
||||||
|
|
||||||
fn start_rpc_handler_with_tx(
|
struct RpcHandler {
|
||||||
pubkey: &Pubkey,
|
io: MetaIoHandler<Meta>,
|
||||||
) -> (MetaIoHandler<Meta>, Meta, Arc<Bank>, Hash, Keypair, Pubkey) {
|
meta: Meta,
|
||||||
|
bank: Arc<Bank>,
|
||||||
|
blockhash: Hash,
|
||||||
|
alice: Keypair,
|
||||||
|
leader_pubkey: Pubkey,
|
||||||
|
fork_confidence_cache: Arc<RwLock<ForkConfidenceCache>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_rpc_handler_with_tx(pubkey: &Pubkey) -> RpcHandler {
|
||||||
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 confidence_slot0 = BankConfidence::new([8; MAX_LOCKOUT_HISTORY]);
|
||||||
|
let confidence_slot1 = BankConfidence::new([9; MAX_LOCKOUT_HISTORY]);
|
||||||
|
let mut bank_confidence: HashMap<u64, BankConfidence> = HashMap::new();
|
||||||
|
bank_confidence.entry(0).or_insert(confidence_slot0.clone());
|
||||||
|
bank_confidence.entry(1).or_insert(confidence_slot1.clone());
|
||||||
|
let fork_confidence_cache =
|
||||||
|
Arc::new(RwLock::new(ForkConfidenceCache::new(bank_confidence, 42)));
|
||||||
|
|
||||||
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));
|
||||||
let validator_exit = create_validator_exit(&exit);
|
let validator_exit = create_validator_exit(&exit);
|
||||||
@ -742,6 +803,7 @@ pub mod tests {
|
|||||||
StorageState::default(),
|
StorageState::default(),
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
bank_forks,
|
bank_forks,
|
||||||
|
fork_confidence_cache.clone(),
|
||||||
&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(
|
||||||
@ -764,7 +826,15 @@ pub mod tests {
|
|||||||
cluster_info,
|
cluster_info,
|
||||||
genesis_blockhash: Hash::default(),
|
genesis_blockhash: Hash::default(),
|
||||||
};
|
};
|
||||||
(io, meta, bank, blockhash, alice, leader_pubkey)
|
RpcHandler {
|
||||||
|
io,
|
||||||
|
meta,
|
||||||
|
bank,
|
||||||
|
blockhash,
|
||||||
|
alice,
|
||||||
|
leader_pubkey,
|
||||||
|
fork_confidence_cache,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -774,10 +844,12 @@ pub mod tests {
|
|||||||
let validator_exit = create_validator_exit(&exit);
|
let validator_exit = create_validator_exit(&exit);
|
||||||
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 fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
let request_processor = JsonRpcRequestProcessor::new(
|
let request_processor = JsonRpcRequestProcessor::new(
|
||||||
StorageState::default(),
|
StorageState::default(),
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
bank_forks,
|
bank_forks,
|
||||||
|
fork_confidence_cache,
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
);
|
);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
@ -793,8 +865,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_balance() {
|
fn test_rpc_get_balance() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(
|
let req = format!(
|
||||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["{}"]}}"#,
|
r#"{{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["{}"]}}"#,
|
||||||
@ -812,8 +883,12 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_cluster_nodes() {
|
fn test_rpc_get_cluster_nodes() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
io,
|
||||||
|
meta,
|
||||||
|
leader_pubkey,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getClusterNodes"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getClusterNodes"}}"#);
|
||||||
let res = io.handle_request_sync(&req, meta);
|
let res = io.handle_request_sync(&req, meta);
|
||||||
@ -833,8 +908,12 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_slot_leader() {
|
fn test_rpc_get_slot_leader() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
io,
|
||||||
|
meta,
|
||||||
|
leader_pubkey,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getSlotLeader"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getSlotLeader"}}"#);
|
||||||
let res = io.handle_request_sync(&req, meta);
|
let res = io.handle_request_sync(&req, meta);
|
||||||
@ -849,8 +928,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_tx_count() {
|
fn test_rpc_get_tx_count() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getTransactionCount"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getTransactionCount"}}"#);
|
||||||
let res = io.handle_request_sync(&req, meta);
|
let res = io.handle_request_sync(&req, meta);
|
||||||
@ -865,8 +943,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_total_supply() {
|
fn test_rpc_get_total_supply() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getTotalSupply"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getTotalSupply"}}"#);
|
||||||
let rep = io.handle_request_sync(&req, meta);
|
let rep = io.handle_request_sync(&req, meta);
|
||||||
@ -892,8 +969,7 @@ pub mod tests {
|
|||||||
fn test_rpc_get_minimum_balance_for_rent_exemption() {
|
fn test_rpc_get_minimum_balance_for_rent_exemption() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let data_len = 50;
|
let data_len = 50;
|
||||||
let (io, meta, bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(
|
let req = format!(
|
||||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getMinimumBalanceForRentExemption","params":[{}]}}"#,
|
r#"{{"jsonrpc":"2.0","id":1,"method":"getMinimumBalanceForRentExemption","params":[{}]}}"#,
|
||||||
@ -924,8 +1000,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_inflation() {
|
fn test_rpc_get_inflation() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getInflation"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getInflation"}}"#);
|
||||||
let rep = io.handle_request_sync(&req, meta);
|
let rep = io.handle_request_sync(&req, meta);
|
||||||
@ -946,8 +1021,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_account_info() {
|
fn test_rpc_get_account_info() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
let req = format!(
|
let req = format!(
|
||||||
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}"]}}"#,
|
r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}"]}}"#,
|
||||||
@ -975,8 +1049,13 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_program_accounts() {
|
fn test_rpc_get_program_accounts() {
|
||||||
let bob = Keypair::new();
|
let bob = Keypair::new();
|
||||||
let (io, meta, bank, blockhash, _alice, _leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob.pubkey());
|
io,
|
||||||
|
meta,
|
||||||
|
bank,
|
||||||
|
blockhash,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob.pubkey());
|
||||||
|
|
||||||
let new_program_id = Pubkey::new_rand();
|
let new_program_id = Pubkey::new_rand();
|
||||||
let tx = system_transaction::assign(&bob, blockhash, &new_program_id);
|
let tx = system_transaction::assign(&bob, blockhash, &new_program_id);
|
||||||
@ -1011,8 +1090,13 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_confirm_tx() {
|
fn test_rpc_confirm_tx() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, blockhash, alice, _leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
io,
|
||||||
|
meta,
|
||||||
|
blockhash,
|
||||||
|
alice,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
|
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
|
||||||
|
|
||||||
let req = format!(
|
let req = format!(
|
||||||
@ -1031,8 +1115,13 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_signature_status() {
|
fn test_rpc_get_signature_status() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, blockhash, alice, _leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
io,
|
||||||
|
meta,
|
||||||
|
blockhash,
|
||||||
|
alice,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
|
let tx = system_transaction::transfer(&alice, &bob_pubkey, 20, blockhash);
|
||||||
|
|
||||||
let req = format!(
|
let req = format!(
|
||||||
@ -1096,8 +1185,12 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_recent_blockhash() {
|
fn test_rpc_get_recent_blockhash() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, blockhash, _alice, _leader_pubkey) =
|
let RpcHandler {
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
io,
|
||||||
|
meta,
|
||||||
|
blockhash,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getRecentBlockhash"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getRecentBlockhash"}}"#);
|
||||||
let res = io.handle_request_sync(&req, meta);
|
let res = io.handle_request_sync(&req, meta);
|
||||||
@ -1123,8 +1216,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_fail_request_airdrop() {
|
fn test_rpc_fail_request_airdrop() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, _bank, _blockhash, _alice, _leader_pubkey) =
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
start_rpc_handler_with_tx(&bob_pubkey);
|
|
||||||
|
|
||||||
// Expect internal error because no drone is available
|
// Expect internal error because no drone is available
|
||||||
let req = format!(
|
let req = format!(
|
||||||
@ -1145,6 +1237,7 @@ pub mod tests {
|
|||||||
fn test_rpc_send_bad_tx() {
|
fn test_rpc_send_bad_tx() {
|
||||||
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 fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
|
|
||||||
let mut io = MetaIoHandler::default();
|
let mut io = MetaIoHandler::default();
|
||||||
let rpc = RpcSolImpl;
|
let rpc = RpcSolImpl;
|
||||||
@ -1155,6 +1248,7 @@ pub mod tests {
|
|||||||
StorageState::default(),
|
StorageState::default(),
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
new_bank_forks().0,
|
new_bank_forks().0,
|
||||||
|
fork_confidence_cache,
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
);
|
);
|
||||||
Arc::new(RwLock::new(request_processor))
|
Arc::new(RwLock::new(request_processor))
|
||||||
@ -1241,10 +1335,12 @@ pub mod tests {
|
|||||||
fn test_rpc_request_processor_config_default_trait_validator_exit_fails() {
|
fn test_rpc_request_processor_config_default_trait_validator_exit_fails() {
|
||||||
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 fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
let request_processor = JsonRpcRequestProcessor::new(
|
let request_processor = JsonRpcRequestProcessor::new(
|
||||||
StorageState::default(),
|
StorageState::default(),
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
new_bank_forks().0,
|
new_bank_forks().0,
|
||||||
|
fork_confidence_cache,
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
);
|
);
|
||||||
assert_eq!(request_processor.validator_exit(), Ok(false));
|
assert_eq!(request_processor.validator_exit(), Ok(false));
|
||||||
@ -1255,12 +1351,14 @@ pub mod tests {
|
|||||||
fn test_rpc_request_processor_allow_validator_exit_config() {
|
fn test_rpc_request_processor_allow_validator_exit_config() {
|
||||||
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 fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
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(),
|
StorageState::default(),
|
||||||
config,
|
config,
|
||||||
new_bank_forks().0,
|
new_bank_forks().0,
|
||||||
|
fork_confidence_cache,
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
);
|
);
|
||||||
assert_eq!(request_processor.validator_exit(), Ok(true));
|
assert_eq!(request_processor.validator_exit(), Ok(true));
|
||||||
@ -1270,7 +1368,7 @@ pub mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_rpc_get_version() {
|
fn test_rpc_get_version() {
|
||||||
let bob_pubkey = Pubkey::new_rand();
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
let (io, meta, ..) = start_rpc_handler_with_tx(&bob_pubkey);
|
let RpcHandler { io, meta, .. } = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getVersion"}}"#);
|
let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getVersion"}}"#);
|
||||||
let res = io.handle_request_sync(&req, meta);
|
let res = io.handle_request_sync(&req, meta);
|
||||||
@ -1287,4 +1385,90 @@ pub mod tests {
|
|||||||
.expect("actual response deserialization");
|
.expect("actual response deserialization");
|
||||||
assert_eq!(expected, result);
|
assert_eq!(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rpc_processor_get_block_confidence() {
|
||||||
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
|
let validator_exit = create_validator_exit(&exit);
|
||||||
|
let confidence_slot0 = BankConfidence::new([8; MAX_LOCKOUT_HISTORY]);
|
||||||
|
let confidence_slot1 = BankConfidence::new([9; MAX_LOCKOUT_HISTORY]);
|
||||||
|
let mut bank_confidence: HashMap<u64, BankConfidence> = HashMap::new();
|
||||||
|
bank_confidence.entry(0).or_insert(confidence_slot0.clone());
|
||||||
|
bank_confidence.entry(1).or_insert(confidence_slot1.clone());
|
||||||
|
let fork_confidence_cache =
|
||||||
|
Arc::new(RwLock::new(ForkConfidenceCache::new(bank_confidence, 42)));
|
||||||
|
|
||||||
|
let mut config = JsonRpcConfig::default();
|
||||||
|
config.enable_validator_exit = true;
|
||||||
|
let request_processor = JsonRpcRequestProcessor::new(
|
||||||
|
StorageState::default(),
|
||||||
|
config,
|
||||||
|
new_bank_forks().0,
|
||||||
|
fork_confidence_cache,
|
||||||
|
&validator_exit,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
request_processor.get_block_confidence(0),
|
||||||
|
(Some(confidence_slot0), 42)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
request_processor.get_block_confidence(1),
|
||||||
|
(Some(confidence_slot1), 42)
|
||||||
|
);
|
||||||
|
assert_eq!(request_processor.get_block_confidence(2), (None, 42));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rpc_get_block_confidence() {
|
||||||
|
let bob_pubkey = Pubkey::new_rand();
|
||||||
|
let RpcHandler {
|
||||||
|
io,
|
||||||
|
meta,
|
||||||
|
fork_confidence_cache,
|
||||||
|
..
|
||||||
|
} = start_rpc_handler_with_tx(&bob_pubkey);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getBlockConfidence","params":[0]}}"#);
|
||||||
|
let res = io.handle_request_sync(&req, meta.clone());
|
||||||
|
let result: Response = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let (confidence, total_staked): (Option<BankConfidence>, u64) =
|
||||||
|
if let Response::Single(res) = result {
|
||||||
|
if let Output::Success(res) = res {
|
||||||
|
serde_json::from_value(res.result).unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Expected success");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Expected single response");
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
confidence,
|
||||||
|
fork_confidence_cache
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get_fork_confidence(0)
|
||||||
|
.cloned()
|
||||||
|
);
|
||||||
|
assert_eq!(total_staked, 42);
|
||||||
|
|
||||||
|
let req =
|
||||||
|
format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getBlockConfidence","params":[2]}}"#);
|
||||||
|
let res = io.handle_request_sync(&req, meta);
|
||||||
|
let result: Response = serde_json::from_str(&res.expect("actual response"))
|
||||||
|
.expect("actual response deserialization");
|
||||||
|
let (confidence, total_staked): (Option<BankConfidence>, u64) =
|
||||||
|
if let Response::Single(res) = result {
|
||||||
|
if let Output::Success(res) = res {
|
||||||
|
serde_json::from_value(res.result).unwrap()
|
||||||
|
} else {
|
||||||
|
panic!("Expected success");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Expected single response");
|
||||||
|
};
|
||||||
|
assert_eq!(confidence, None);
|
||||||
|
assert_eq!(total_staked, 42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
//! The `rpc_service` module implements the Solana JSON RPC service.
|
//! The `rpc_service` module implements the Solana JSON RPC service.
|
||||||
|
|
||||||
use crate::bank_forks::BankForks;
|
use crate::{
|
||||||
use crate::cluster_info::ClusterInfo;
|
bank_forks::BankForks, cluster_info::ClusterInfo, confidence::ForkConfidenceCache, rpc::*,
|
||||||
use crate::rpc::*;
|
service::Service, storage_stage::StorageState, validator::ValidatorExit,
|
||||||
use crate::service::Service;
|
};
|
||||||
use crate::storage_stage::StorageState;
|
|
||||||
use crate::validator::ValidatorExit;
|
|
||||||
use jsonrpc_core::MetaIoHandler;
|
use jsonrpc_core::MetaIoHandler;
|
||||||
use jsonrpc_http_server::CloseHandle;
|
|
||||||
use jsonrpc_http_server::{
|
use jsonrpc_http_server::{
|
||||||
hyper, AccessControlAllowOrigin, DomainsValidation, RequestMiddleware, RequestMiddlewareAction,
|
hyper, AccessControlAllowOrigin, CloseHandle, DomainsValidation, RequestMiddleware,
|
||||||
ServerBuilder,
|
RequestMiddlewareAction, ServerBuilder,
|
||||||
};
|
};
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::hash::Hash;
|
||||||
use std::net::SocketAddr;
|
use std::{
|
||||||
use std::path::{Path, PathBuf};
|
net::SocketAddr,
|
||||||
use std::sync::mpsc::channel;
|
path::{Path, PathBuf},
|
||||||
use std::sync::{Arc, RwLock};
|
sync::mpsc::channel,
|
||||||
use std::thread::{self, Builder, JoinHandle};
|
sync::{Arc, RwLock},
|
||||||
|
thread::{self, Builder, JoinHandle},
|
||||||
|
};
|
||||||
use tokio::prelude::Future;
|
use tokio::prelude::Future;
|
||||||
|
|
||||||
pub struct JsonRpcService {
|
pub struct JsonRpcService {
|
||||||
@ -91,6 +90,7 @@ impl JsonRpcService {
|
|||||||
storage_state: StorageState,
|
storage_state: StorageState,
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
|
fork_confidence_cache: Arc<RwLock<ForkConfidenceCache>>,
|
||||||
ledger_path: &Path,
|
ledger_path: &Path,
|
||||||
genesis_blockhash: Hash,
|
genesis_blockhash: Hash,
|
||||||
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
|
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
|
||||||
@ -101,6 +101,7 @@ impl JsonRpcService {
|
|||||||
storage_state,
|
storage_state,
|
||||||
config,
|
config,
|
||||||
bank_forks,
|
bank_forks,
|
||||||
|
fork_confidence_cache,
|
||||||
validator_exit,
|
validator_exit,
|
||||||
)));
|
)));
|
||||||
let request_processor_ = request_processor.clone();
|
let request_processor_ = request_processor.clone();
|
||||||
@ -197,12 +198,14 @@ mod tests {
|
|||||||
solana_netutil::find_available_port_in_range((10000, 65535)).unwrap(),
|
solana_netutil::find_available_port_in_range((10000, 65535)).unwrap(),
|
||||||
);
|
);
|
||||||
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 fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
let mut rpc_service = JsonRpcService::new(
|
let mut rpc_service = JsonRpcService::new(
|
||||||
&cluster_info,
|
&cluster_info,
|
||||||
rpc_addr,
|
rpc_addr,
|
||||||
StorageState::default(),
|
StorageState::default(),
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
bank_forks,
|
bank_forks,
|
||||||
|
fork_confidence_cache,
|
||||||
&PathBuf::from("farf"),
|
&PathBuf::from("farf"),
|
||||||
Hash::default(),
|
Hash::default(),
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
|
@ -158,6 +158,7 @@ impl Validator {
|
|||||||
let bank_info = &bank_forks_info[0];
|
let bank_info = &bank_forks_info[0];
|
||||||
let bank = bank_forks[bank_info.bank_slot].clone();
|
let bank = bank_forks[bank_info.bank_slot].clone();
|
||||||
let bank_forks = Arc::new(RwLock::new(bank_forks));
|
let bank_forks = Arc::new(RwLock::new(bank_forks));
|
||||||
|
let fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
||||||
|
|
||||||
let mut validator_exit = ValidatorExit::default();
|
let mut validator_exit = ValidatorExit::default();
|
||||||
let exit_ = exit.clone();
|
let exit_ = exit.clone();
|
||||||
@ -185,6 +186,7 @@ impl Validator {
|
|||||||
storage_state.clone(),
|
storage_state.clone(),
|
||||||
config.rpc_config.clone(),
|
config.rpc_config.clone(),
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
|
fork_confidence_cache.clone(),
|
||||||
ledger_path,
|
ledger_path,
|
||||||
genesis_blockhash,
|
genesis_blockhash,
|
||||||
&validator_exit,
|
&validator_exit,
|
||||||
@ -298,7 +300,6 @@ impl Validator {
|
|||||||
Some(voting_keypair)
|
Some(voting_keypair)
|
||||||
};
|
};
|
||||||
|
|
||||||
let fork_confidence_cache = Arc::new(RwLock::new(ForkConfidenceCache::default()));
|
|
||||||
let tvu = Tvu::new(
|
let tvu = Tvu::new(
|
||||||
vote_account,
|
vote_account,
|
||||||
voting_keypair,
|
voting_keypair,
|
||||||
|
Reference in New Issue
Block a user