Use generic types instead of trait objects in tx pool (#3308)

Tx pool takes some parameters as trait objects. It's not an idiomatic Rust code, in this particular case we should use generic types. Trait object makes sense when we accept in runtime different concrete types which implement the trait as a value of the same field. It's not the case here. Trait objects come with a price - instead of method dispatch in compile time we have to accept runtime dispatch. My guess we did it to not clutter the code with type parameters, which is understandable but still suboptimal.
This commit is contained in:
hashmap 2020-04-30 17:41:49 +02:00 committed by GitHub
parent 061bf3d08f
commit 9e51e86538
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 239 additions and 104 deletions

View file

@ -17,12 +17,13 @@
use crate::chain::{Chain, SyncState}; use crate::chain::{Chain, SyncState};
use crate::core::core::hash::Hash; use crate::core::core::hash::Hash;
use crate::core::core::transaction::Transaction; use crate::core::core::transaction::Transaction;
use crate::core::core::verifier_cache::VerifierCache;
use crate::handlers::blocks_api::{BlockHandler, HeaderHandler}; use crate::handlers::blocks_api::{BlockHandler, HeaderHandler};
use crate::handlers::chain_api::{ChainHandler, KernelHandler, OutputHandler}; use crate::handlers::chain_api::{ChainHandler, KernelHandler, OutputHandler};
use crate::handlers::pool_api::PoolHandler; use crate::handlers::pool_api::PoolHandler;
use crate::handlers::transactions_api::TxHashSetHandler; use crate::handlers::transactions_api::TxHashSetHandler;
use crate::handlers::version_api::VersionHandler; use crate::handlers::version_api::VersionHandler;
use crate::pool::{self, PoolEntry}; use crate::pool::{self, BlockChain, PoolAdapter, PoolEntry};
use crate::rest::*; use crate::rest::*;
use crate::types::{ use crate::types::{
BlockHeaderPrintable, BlockPrintable, LocatedTxKernel, OutputListing, OutputPrintable, Tip, BlockHeaderPrintable, BlockPrintable, LocatedTxKernel, OutputListing, OutputPrintable, Tip,
@ -38,13 +39,23 @@ use std::sync::Weak;
/// Methods in this API are intended to be 'single use'. /// Methods in this API are intended to be 'single use'.
/// ///
pub struct Foreign { pub struct Foreign<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub chain: Weak<Chain>, pub chain: Weak<Chain>,
pub tx_pool: Weak<RwLock<pool::TransactionPool>>, pub tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
pub sync_state: Weak<SyncState>, pub sync_state: Weak<SyncState>,
} }
impl Foreign { impl<B, P, V> Foreign<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
/// Create a new API instance with the chain, transaction pool, peers and `sync_state`. All subsequent /// Create a new API instance with the chain, transaction pool, peers and `sync_state`. All subsequent
/// API calls will operate on this instance of node API. /// API calls will operate on this instance of node API.
/// ///
@ -60,7 +71,7 @@ impl Foreign {
pub fn new( pub fn new(
chain: Weak<Chain>, chain: Weak<Chain>,
tx_pool: Weak<RwLock<pool::TransactionPool>>, tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
sync_state: Weak<SyncState>, sync_state: Weak<SyncState>,
) -> Self { ) -> Self {
Foreign { Foreign {

View file

@ -16,8 +16,10 @@
use crate::core::core::hash::Hash; use crate::core::core::hash::Hash;
use crate::core::core::transaction::Transaction; use crate::core::core::transaction::Transaction;
use crate::core::core::verifier_cache::VerifierCache;
use crate::foreign::Foreign; use crate::foreign::Foreign;
use crate::pool::PoolEntry; use crate::pool::PoolEntry;
use crate::pool::{BlockChain, PoolAdapter};
use crate::rest::ErrorKind; use crate::rest::ErrorKind;
use crate::types::{ use crate::types::{
BlockHeaderPrintable, BlockPrintable, LocatedTxKernel, OutputListing, OutputPrintable, Tip, BlockHeaderPrintable, BlockPrintable, LocatedTxKernel, OutputListing, OutputPrintable, Tip,
@ -738,7 +740,12 @@ pub trait ForeignRpc: Sync + Send {
fn push_transaction(&self, tx: Transaction, fluff: Option<bool>) -> Result<(), ErrorKind>; fn push_transaction(&self, tx: Transaction, fluff: Option<bool>) -> Result<(), ErrorKind>;
} }
impl ForeignRpc for Foreign { impl<B, P, V> ForeignRpc for Foreign<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
fn get_header( fn get_header(
&self, &self,
height: Option<u64>, height: Option<u64>,

View file

@ -42,12 +42,14 @@ use crate::auth::{
}; };
use crate::chain; use crate::chain;
use crate::chain::{Chain, SyncState}; use crate::chain::{Chain, SyncState};
use crate::core::core::verifier_cache::VerifierCache;
use crate::foreign::Foreign; use crate::foreign::Foreign;
use crate::foreign_rpc::ForeignRpc; use crate::foreign_rpc::ForeignRpc;
use crate::owner::Owner; use crate::owner::Owner;
use crate::owner_rpc::OwnerRpc; use crate::owner_rpc::OwnerRpc;
use crate::p2p; use crate::p2p;
use crate::pool; use crate::pool;
use crate::pool::{BlockChain, PoolAdapter};
use crate::rest::{ApiServer, Error, TLSConfig}; use crate::rest::{ApiServer, Error, TLSConfig};
use crate::router::ResponseFuture; use crate::router::ResponseFuture;
use crate::router::{Router, RouterError}; use crate::router::{Router, RouterError};
@ -62,16 +64,21 @@ use std::sync::{Arc, Weak};
/// Listener version, providing same API but listening for requests on a /// Listener version, providing same API but listening for requests on a
/// port and wrapping the calls /// port and wrapping the calls
pub fn node_apis( pub fn node_apis<B, P, V>(
addr: &str, addr: &str,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
peers: Arc<p2p::Peers>, peers: Arc<p2p::Peers>,
sync_state: Arc<chain::SyncState>, sync_state: Arc<chain::SyncState>,
api_secret: Option<String>, api_secret: Option<String>,
foreign_api_secret: Option<String>, foreign_api_secret: Option<String>,
tls_config: Option<TLSConfig>, tls_config: Option<TLSConfig>,
) -> Result<(), Error> { ) -> Result<(), Error>
where
B: BlockChain + 'static,
P: PoolAdapter + 'static,
V: VerifierCache + 'static,
{
// Manually build router when getting rid of v1 // Manually build router when getting rid of v1
//let mut router = Router::new(); //let mut router = Router::new();
let mut router = build_router( let mut router = build_router(
@ -190,17 +197,27 @@ impl crate::router::Handler for OwnerAPIHandlerV2 {
} }
/// V2 API Handler/Wrapper for foreign functions /// V2 API Handler/Wrapper for foreign functions
pub struct ForeignAPIHandlerV2 { pub struct ForeignAPIHandlerV2<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub chain: Weak<Chain>, pub chain: Weak<Chain>,
pub tx_pool: Weak<RwLock<pool::TransactionPool>>, pub tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
pub sync_state: Weak<SyncState>, pub sync_state: Weak<SyncState>,
} }
impl ForeignAPIHandlerV2 { impl<B, P, V> ForeignAPIHandlerV2<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
/// Create a new foreign API handler for GET methods /// Create a new foreign API handler for GET methods
pub fn new( pub fn new(
chain: Weak<Chain>, chain: Weak<Chain>,
tx_pool: Weak<RwLock<pool::TransactionPool>>, tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
sync_state: Weak<SyncState>, sync_state: Weak<SyncState>,
) -> Self { ) -> Self {
ForeignAPIHandlerV2 { ForeignAPIHandlerV2 {
@ -211,7 +228,12 @@ impl ForeignAPIHandlerV2 {
} }
} }
impl crate::router::Handler for ForeignAPIHandlerV2 { impl<B, P, V> crate::router::Handler for ForeignAPIHandlerV2<B, P, V>
where
B: BlockChain + 'static,
P: PoolAdapter + 'static,
V: VerifierCache + 'static,
{
fn post(&self, req: Request<Body>) -> ResponseFuture { fn post(&self, req: Request<Body>) -> ResponseFuture {
let api = Foreign::new( let api = Foreign::new(
self.chain.clone(), self.chain.clone(),
@ -309,12 +331,17 @@ fn response<T: Into<Body>>(status: StatusCode, text: T) -> Response<Body> {
since = "4.0.0", since = "4.0.0",
note = "The V1 Node API will be removed in grin 5.0.0. Please migrate to the V2 API as soon as possible." note = "The V1 Node API will be removed in grin 5.0.0. Please migrate to the V2 API as soon as possible."
)] )]
pub fn build_router( pub fn build_router<B, P, V>(
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
peers: Arc<p2p::Peers>, peers: Arc<p2p::Peers>,
sync_state: Arc<chain::SyncState>, sync_state: Arc<chain::SyncState>,
) -> Result<Router, RouterError> { ) -> Result<Router, RouterError>
where
B: BlockChain + 'static,
P: PoolAdapter + 'static,
V: VerifierCache + 'static,
{
let route_list = vec![ let route_list = vec![
"get blocks".to_string(), "get blocks".to_string(),
"get headers".to_string(), "get headers".to_string(),

View file

@ -14,9 +14,10 @@
use super::utils::w; use super::utils::w;
use crate::core::core::hash::Hashed; use crate::core::core::hash::Hashed;
use crate::core::core::verifier_cache::VerifierCache;
use crate::core::core::Transaction; use crate::core::core::Transaction;
use crate::core::ser::{self, ProtocolVersion}; use crate::core::ser::{self, ProtocolVersion};
use crate::pool::{self, PoolEntry}; use crate::pool::{self, BlockChain, PoolAdapter, PoolEntry};
use crate::rest::*; use crate::rest::*;
use crate::router::{Handler, ResponseFuture}; use crate::router::{Handler, ResponseFuture};
use crate::types::*; use crate::types::*;
@ -29,11 +30,21 @@ use std::sync::Weak;
/// Get basic information about the transaction pool. /// Get basic information about the transaction pool.
/// GET /v1/pool /// GET /v1/pool
pub struct PoolInfoHandler { pub struct PoolInfoHandler<B, P, V>
pub tx_pool: Weak<RwLock<pool::TransactionPool>>, where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
} }
impl Handler for PoolInfoHandler { impl<B, P, V> Handler for PoolInfoHandler<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
fn get(&self, _req: Request<Body>) -> ResponseFuture { fn get(&self, _req: Request<Body>) -> ResponseFuture {
let pool_arc = w_fut!(&self.tx_pool); let pool_arc = w_fut!(&self.tx_pool);
let pool = pool_arc.read(); let pool = pool_arc.read();
@ -44,11 +55,21 @@ impl Handler for PoolInfoHandler {
} }
} }
pub struct PoolHandler { pub struct PoolHandler<B, P, V>
pub tx_pool: Weak<RwLock<pool::TransactionPool>>, where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
} }
impl PoolHandler { impl<B, P, V> PoolHandler<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub fn get_pool_size(&self) -> Result<usize, Error> { pub fn get_pool_size(&self) -> Result<usize, Error> {
let pool_arc = w(&self.tx_pool)?; let pool_arc = w(&self.tx_pool)?;
let pool = pool_arc.read(); let pool = pool_arc.read();
@ -96,14 +117,24 @@ struct TxWrapper {
/// Push new transaction to our local transaction pool. /// Push new transaction to our local transaction pool.
/// POST /v1/pool/push_tx /// POST /v1/pool/push_tx
pub struct PoolPushHandler { pub struct PoolPushHandler<B, P, V>
pub tx_pool: Weak<RwLock<pool::TransactionPool>>, where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
pub tx_pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
} }
async fn update_pool( async fn update_pool<B, P, V>(
pool: Weak<RwLock<pool::TransactionPool>>, pool: Weak<RwLock<pool::TransactionPool<B, P, V>>>,
req: Request<Body>, req: Request<Body>,
) -> Result<(), Error> { ) -> Result<(), Error>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
let pool = w(&pool)?; let pool = w(&pool)?;
let params = QueryParams::from(req.uri().query()); let params = QueryParams::from(req.uri().query());
let fluff = params.get("fluff").is_some(); let fluff = params.get("fluff").is_some();
@ -138,7 +169,12 @@ async fn update_pool(
Ok(()) Ok(())
} }
impl Handler for PoolPushHandler { impl<B, P, V> Handler for PoolPushHandler<B, P, V>
where
B: BlockChain + 'static,
P: PoolAdapter + 'static,
V: VerifierCache + 'static,
{
fn post(&self, req: Request<Body>) -> ResponseFuture { fn post(&self, req: Request<Body>) -> ResponseFuture {
let pool = self.tx_pool.clone(); let pool = self.tx_pool.clone();
Box::pin(async move { Box::pin(async move {

View file

@ -30,21 +30,25 @@ use std::cmp::Reverse;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::sync::Arc; use std::sync::Arc;
pub struct Pool { pub struct Pool<B, V>
where
B: BlockChain,
V: VerifierCache,
{
/// Entries in the pool (tx + info + timer) in simple insertion order. /// Entries in the pool (tx + info + timer) in simple insertion order.
pub entries: Vec<PoolEntry>, pub entries: Vec<PoolEntry>,
/// The blockchain /// The blockchain
pub blockchain: Arc<dyn BlockChain>, pub blockchain: Arc<B>,
pub verifier_cache: Arc<RwLock<dyn VerifierCache>>, pub verifier_cache: Arc<RwLock<V>>,
pub name: String, pub name: String,
} }
impl Pool { impl<B, V> Pool<B, V>
pub fn new( where
chain: Arc<dyn BlockChain>, B: BlockChain,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, V: VerifierCache + 'static,
name: String, {
) -> Pool { pub fn new(chain: Arc<B>, verifier_cache: Arc<RwLock<V>>, name: String) -> Self {
Pool { Pool {
entries: vec![], entries: vec![],
blockchain: chain, blockchain: chain,

View file

@ -31,30 +31,40 @@ use std::collections::VecDeque;
use std::sync::Arc; use std::sync::Arc;
/// Transaction pool implementation. /// Transaction pool implementation.
pub struct TransactionPool { pub struct TransactionPool<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache,
{
/// Pool Config /// Pool Config
pub config: PoolConfig, pub config: PoolConfig,
/// Our transaction pool. /// Our transaction pool.
pub txpool: Pool, pub txpool: Pool<B, V>,
/// Our Dandelion "stempool". /// Our Dandelion "stempool".
pub stempool: Pool, pub stempool: Pool<B, V>,
/// Cache of previous txs in case of a re-org. /// Cache of previous txs in case of a re-org.
pub reorg_cache: Arc<RwLock<VecDeque<PoolEntry>>>, pub reorg_cache: Arc<RwLock<VecDeque<PoolEntry>>>,
/// The blockchain /// The blockchain
pub blockchain: Arc<dyn BlockChain>, pub blockchain: Arc<B>,
pub verifier_cache: Arc<RwLock<dyn VerifierCache>>, pub verifier_cache: Arc<RwLock<V>>,
/// The pool adapter /// The pool adapter
pub adapter: Arc<dyn PoolAdapter>, pub adapter: Arc<P>,
} }
impl TransactionPool { impl<B, P, V> TransactionPool<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
/// Create a new transaction pool /// Create a new transaction pool
pub fn new( pub fn new(
config: PoolConfig, config: PoolConfig,
chain: Arc<dyn BlockChain>, chain: Arc<B>,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: Arc<RwLock<V>>,
adapter: Arc<dyn PoolAdapter>, adapter: Arc<P>,
) -> TransactionPool { ) -> Self {
TransactionPool { TransactionPool {
config, config,
txpool: Pool::new(chain.clone(), verifier_cache.clone(), "txpool".to_string()), txpool: Pool::new(chain.clone(), verifier_cache.clone(), "txpool".to_string()),

View file

@ -148,10 +148,14 @@ impl BlockChain for ChainAdapter {
} }
} }
pub fn test_setup( pub fn test_setup<B, V>(
chain: Arc<dyn BlockChain>, chain: Arc<B>,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: Arc<RwLock<V>>,
) -> TransactionPool { ) -> TransactionPool<B, NoopAdapter, V>
where
B: BlockChain,
V: VerifierCache + 'static,
{
TransactionPool::new( TransactionPool::new(
PoolConfig { PoolConfig {
accept_fee_base: 0, accept_fee_base: 0,

View file

@ -36,7 +36,7 @@ use crate::core::pow::Difficulty;
use crate::core::{core, global}; use crate::core::{core, global};
use crate::p2p; use crate::p2p;
use crate::p2p::types::PeerInfo; use crate::p2p::types::PeerInfo;
use crate::pool; use crate::pool::{self, BlockChain, PoolAdapter};
use crate::util::OneTime; use crate::util::OneTime;
use chrono::prelude::*; use chrono::prelude::*;
use chrono::Duration; use chrono::Duration;
@ -45,17 +45,27 @@ use rand::prelude::*;
/// Implementation of the NetAdapter for the . Gets notified when new /// Implementation of the NetAdapter for the . Gets notified when new
/// blocks and transactions are received and forwards to the chain and pool /// blocks and transactions are received and forwards to the chain and pool
/// implementations. /// implementations.
pub struct NetToChainAdapter { pub struct NetToChainAdapter<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
chain: Weak<chain::Chain>, chain: Weak<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: Arc<RwLock<V>>,
peers: OneTime<Weak<p2p::Peers>>, peers: OneTime<Weak<p2p::Peers>>,
config: ServerConfig, config: ServerConfig,
hooks: Vec<Box<dyn NetEvents + Send + Sync>>, hooks: Vec<Box<dyn NetEvents + Send + Sync>>,
} }
impl p2p::ChainAdapter for NetToChainAdapter { impl<B, P, V> p2p::ChainAdapter for NetToChainAdapter<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
fn total_difficulty(&self) -> Result<Difficulty, chain::Error> { fn total_difficulty(&self) -> Result<Difficulty, chain::Error> {
Ok(self.chain().head()?.total_difficulty) Ok(self.chain().head()?.total_difficulty)
} }
@ -464,16 +474,21 @@ impl p2p::ChainAdapter for NetToChainAdapter {
} }
} }
impl NetToChainAdapter { impl<B, P, V> NetToChainAdapter<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
/// Construct a new NetToChainAdapter instance /// Construct a new NetToChainAdapter instance
pub fn new( pub fn new(
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: Arc<RwLock<V>>,
config: ServerConfig, config: ServerConfig,
hooks: Vec<Box<dyn NetEvents + Send + Sync>>, hooks: Vec<Box<dyn NetEvents + Send + Sync>>,
) -> NetToChainAdapter { ) -> Self {
NetToChainAdapter { NetToChainAdapter {
sync_state, sync_state,
chain: Arc::downgrade(&chain), chain: Arc::downgrade(&chain),
@ -699,13 +714,23 @@ impl NetToChainAdapter {
/// Implementation of the ChainAdapter for the network. Gets notified when the /// Implementation of the ChainAdapter for the network. Gets notified when the
/// accepted a new block, asking the pool to update its state and /// accepted a new block, asking the pool to update its state and
/// the network to broadcast the block /// the network to broadcast the block
pub struct ChainToPoolAndNetAdapter { pub struct ChainToPoolAndNetAdapter<B, P, V>
tx_pool: Arc<RwLock<pool::TransactionPool>>, where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
peers: OneTime<Weak<p2p::Peers>>, peers: OneTime<Weak<p2p::Peers>>,
hooks: Vec<Box<dyn ChainEvents + Send + Sync>>, hooks: Vec<Box<dyn ChainEvents + Send + Sync>>,
} }
impl ChainAdapter for ChainToPoolAndNetAdapter { impl<B, P, V> ChainAdapter for ChainToPoolAndNetAdapter<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
fn block_accepted(&self, b: &core::Block, status: BlockStatus, opts: Options) { fn block_accepted(&self, b: &core::Block, status: BlockStatus, opts: Options) {
// not broadcasting blocks received through sync // not broadcasting blocks received through sync
if !opts.contains(chain::Options::SYNC) { if !opts.contains(chain::Options::SYNC) {
@ -749,12 +774,17 @@ impl ChainAdapter for ChainToPoolAndNetAdapter {
} }
} }
impl ChainToPoolAndNetAdapter { impl<B, P, V> ChainToPoolAndNetAdapter<B, P, V>
where
B: BlockChain,
P: PoolAdapter,
V: VerifierCache + 'static,
{
/// Construct a ChainToPoolAndNetAdapter instance. /// Construct a ChainToPoolAndNetAdapter instance.
pub fn new( pub fn new(
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: Arc<RwLock<pool::TransactionPool<B, P, V>>>,
hooks: Vec<Box<dyn ChainEvents + Send + Sync>>, hooks: Vec<Box<dyn ChainEvents + Send + Sync>>,
) -> ChainToPoolAndNetAdapter { ) -> Self {
ChainToPoolAndNetAdapter { ChainToPoolAndNetAdapter {
tx_pool, tx_pool,
peers: OneTime::new(), peers: OneTime::new(),

View file

@ -22,8 +22,9 @@ use crate::common::adapters::DandelionAdapter;
use crate::core::core::hash::Hashed; use crate::core::core::hash::Hashed;
use crate::core::core::transaction; use crate::core::core::transaction;
use crate::core::core::verifier_cache::VerifierCache; use crate::core::core::verifier_cache::VerifierCache;
use crate::pool::{DandelionConfig, Pool, PoolEntry, PoolError, TransactionPool, TxSource}; use crate::pool::{BlockChain, DandelionConfig, Pool, PoolEntry, PoolError, TxSource};
use crate::util::{RwLock, StopState}; use crate::util::StopState;
use crate::{ServerTxPool, ServerVerifierCache};
/// A process to monitor transactions in the stempool. /// A process to monitor transactions in the stempool.
/// With Dandelion, transaction can be broadcasted in stem or fluff phase. /// With Dandelion, transaction can be broadcasted in stem or fluff phase.
@ -35,9 +36,9 @@ use crate::util::{RwLock, StopState};
/// sending only to the peer relay. /// sending only to the peer relay.
pub fn monitor_transactions( pub fn monitor_transactions(
dandelion_config: DandelionConfig, dandelion_config: DandelionConfig,
tx_pool: Arc<RwLock<TransactionPool>>, tx_pool: ServerTxPool,
adapter: Arc<dyn DandelionAdapter>, adapter: Arc<dyn DandelionAdapter>,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
stop_state: Arc<StopState>, stop_state: Arc<StopState>,
) -> std::io::Result<thread::JoinHandle<()>> { ) -> std::io::Result<thread::JoinHandle<()>> {
debug!("Started Dandelion transaction monitor."); debug!("Started Dandelion transaction monitor.");
@ -90,7 +91,11 @@ pub fn monitor_transactions(
// Query the pool for transactions older than the cutoff. // Query the pool for transactions older than the cutoff.
// Used for both periodic fluffing and handling expired embargo timer. // Used for both periodic fluffing and handling expired embargo timer.
fn select_txs_cutoff(pool: &Pool, cutoff_secs: u16) -> Vec<PoolEntry> { fn select_txs_cutoff<B, V>(pool: &Pool<B, V>, cutoff_secs: u16) -> Vec<PoolEntry>
where
B: BlockChain,
V: VerifierCache,
{
let cutoff = Utc::now().timestamp() - cutoff_secs as i64; let cutoff = Utc::now().timestamp() - cutoff_secs as i64;
pool.entries pool.entries
.iter() .iter()
@ -101,9 +106,9 @@ fn select_txs_cutoff(pool: &Pool, cutoff_secs: u16) -> Vec<PoolEntry> {
fn process_fluff_phase( fn process_fluff_phase(
dandelion_config: &DandelionConfig, dandelion_config: &DandelionConfig,
tx_pool: &Arc<RwLock<TransactionPool>>, tx_pool: &ServerTxPool,
adapter: &Arc<dyn DandelionAdapter>, adapter: &Arc<dyn DandelionAdapter>,
verifier_cache: &Arc<RwLock<dyn VerifierCache>>, verifier_cache: &ServerVerifierCache,
) -> Result<(), PoolError> { ) -> Result<(), PoolError> {
// Take a write lock on the txpool for the duration of this processing. // Take a write lock on the txpool for the duration of this processing.
let mut tx_pool = tx_pool.write(); let mut tx_pool = tx_pool.write();
@ -153,7 +158,7 @@ fn process_fluff_phase(
fn process_expired_entries( fn process_expired_entries(
dandelion_config: &DandelionConfig, dandelion_config: &DandelionConfig,
tx_pool: &Arc<RwLock<TransactionPool>>, tx_pool: &ServerTxPool,
) -> Result<(), PoolError> { ) -> Result<(), PoolError> {
// Take a write lock on the txpool for the duration of this processing. // Take a write lock on the txpool for the duration of this processing.
let mut tx_pool = tx_pool.write(); let mut tx_pool = tx_pool.write();

View file

@ -41,7 +41,7 @@ use crate::common::stats::{
}; };
use crate::common::types::{Error, ServerConfig, StratumServerConfig}; use crate::common::types::{Error, ServerConfig, StratumServerConfig};
use crate::core::core::hash::Hashed; use crate::core::core::hash::Hashed;
use crate::core::core::verifier_cache::{LruVerifierCache, VerifierCache}; use crate::core::core::verifier_cache::LruVerifierCache;
use crate::core::ser::ProtocolVersion; use crate::core::ser::ProtocolVersion;
use crate::core::{consensus, genesis, global, pow}; use crate::core::{consensus, genesis, global, pow};
use crate::grin::{dandelion_monitor, seed, sync}; use crate::grin::{dandelion_monitor, seed, sync};
@ -54,6 +54,12 @@ use crate::util::file::get_first_line;
use crate::util::{RwLock, StopState}; use crate::util::{RwLock, StopState};
use grin_util::logger::LogEntry; use grin_util::logger::LogEntry;
/// Arcified thread-safe TransactionPool with type parameters used by server components
pub type ServerTxPool =
Arc<RwLock<pool::TransactionPool<PoolToChainAdapter, PoolToNetAdapter, LruVerifierCache>>>;
/// Arcified thread-safe LruVerifierCache
pub type ServerVerifierCache = Arc<RwLock<LruVerifierCache>>;
/// Grin server holding internal structures. /// Grin server holding internal structures.
pub struct Server { pub struct Server {
/// server config /// server config
@ -63,10 +69,10 @@ pub struct Server {
/// data store access /// data store access
pub chain: Arc<chain::Chain>, pub chain: Arc<chain::Chain>,
/// in-memory transaction pool /// in-memory transaction pool
pub tx_pool: Arc<RwLock<pool::TransactionPool>>, pub tx_pool: ServerTxPool,
/// Shared cache for verification results when /// Shared cache for verification results when
/// verifying rangeproof and kernel signatures. /// verifying rangeproof and kernel signatures.
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
/// Whether we're currently syncing /// Whether we're currently syncing
pub sync_state: Arc<SyncState>, pub sync_state: Arc<SyncState>,
/// To be passed around to collect stats and info /// To be passed around to collect stats and info

View file

@ -41,4 +41,4 @@ mod mining;
pub use crate::common::stats::{DiffBlock, PeerStats, ServerStats, StratumStats, WorkerStats}; pub use crate::common::stats::{DiffBlock, PeerStats, ServerStats, StratumStats, WorkerStats};
pub use crate::common::types::{ServerConfig, StratumServerConfig}; pub use crate::common::types::{ServerConfig, StratumServerConfig};
pub use crate::grin::server::Server; pub use crate::grin::server::{Server, ServerTxPool, ServerVerifierCache};

View file

@ -15,7 +15,6 @@
//! Build a block to mine: gathers transactions from the pool, assembles //! Build a block to mine: gathers transactions from the pool, assembles
//! them into a block and returns it. //! them into a block and returns it.
use crate::util::RwLock;
use chrono::prelude::{DateTime, NaiveDateTime, Utc}; use chrono::prelude::{DateTime, NaiveDateTime, Utc};
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use serde_json::{json, Value}; use serde_json::{json, Value};
@ -26,13 +25,12 @@ use std::time::Duration;
use crate::api; use crate::api;
use crate::chain; use crate::chain;
use crate::common::types::Error; use crate::common::types::Error;
use crate::core::core::verifier_cache::VerifierCache;
use crate::core::core::{Output, TxKernel}; use crate::core::core::{Output, TxKernel};
use crate::core::libtx::secp_ser; use crate::core::libtx::secp_ser;
use crate::core::libtx::ProofBuilder; use crate::core::libtx::ProofBuilder;
use crate::core::{consensus, core, global}; use crate::core::{consensus, core, global};
use crate::keychain::{ExtKeychain, Identifier, Keychain}; use crate::keychain::{ExtKeychain, Identifier, Keychain};
use crate::pool; use crate::{ServerTxPool, ServerVerifierCache};
/// Fees in block to use for coinbase amount calculation /// Fees in block to use for coinbase amount calculation
/// (Duplicated from Grin wallet project) /// (Duplicated from Grin wallet project)
@ -71,8 +69,8 @@ pub struct CbData {
// Warning: This call does not return until/unless a new block can be built // Warning: This call does not return until/unless a new block can be built
pub fn get_block( pub fn get_block(
chain: &Arc<chain::Chain>, chain: &Arc<chain::Chain>,
tx_pool: &Arc<RwLock<pool::TransactionPool>>, tx_pool: &ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
key_id: Option<Identifier>, key_id: Option<Identifier>,
wallet_listener_url: Option<String>, wallet_listener_url: Option<String>,
) -> (core::Block, BlockFees) { ) -> (core::Block, BlockFees) {
@ -133,8 +131,8 @@ pub fn get_block(
/// transactions from the pool. /// transactions from the pool.
fn build_block( fn build_block(
chain: &Arc<chain::Chain>, chain: &Arc<chain::Chain>,
tx_pool: &Arc<RwLock<pool::TransactionPool>>, tx_pool: &ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
key_id: Option<Identifier>, key_id: Option<Identifier>,
wallet_listener_url: Option<String>, wallet_listener_url: Option<String>,
) -> Result<(core::Block, BlockFees), Error> { ) -> Result<(core::Block, BlockFees), Error> {

View file

@ -36,13 +36,12 @@ use crate::chain::{self, SyncState};
use crate::common::stats::{StratumStats, WorkerStats}; use crate::common::stats::{StratumStats, WorkerStats};
use crate::common::types::StratumServerConfig; use crate::common::types::StratumServerConfig;
use crate::core::core::hash::Hashed; use crate::core::core::hash::Hashed;
use crate::core::core::verifier_cache::VerifierCache;
use crate::core::core::Block; use crate::core::core::Block;
use crate::core::{pow, ser}; use crate::core::{pow, ser};
use crate::keychain; use crate::keychain;
use crate::mining::mine_block; use crate::mining::mine_block;
use crate::pool;
use crate::util::ToHex; use crate::util::ToHex;
use crate::{ServerTxPool, ServerVerifierCache};
type Tx = mpsc::UnboundedSender<String>; type Tx = mpsc::UnboundedSender<String>;
@ -523,8 +522,8 @@ impl Handler {
pub fn run( pub fn run(
&self, &self,
config: &StratumServerConfig, config: &StratumServerConfig,
tx_pool: &Arc<RwLock<pool::TransactionPool>>, tx_pool: &ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
) { ) {
debug!("Run main loop"); debug!("Run main loop");
let mut deadline: i64 = 0; let mut deadline: i64 = 0;
@ -803,8 +802,8 @@ pub struct StratumServer {
id: String, id: String,
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, pub tx_pool: ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
stratum_stats: Arc<RwLock<StratumStats>>, stratum_stats: Arc<RwLock<StratumStats>>,
} }
@ -814,8 +813,8 @@ impl StratumServer {
pub fn new( pub fn new(
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
stratum_stats: Arc<RwLock<StratumStats>>, stratum_stats: Arc<RwLock<StratumStats>>,
) -> StratumServer { ) -> StratumServer {
StratumServer { StratumServer {

View file

@ -17,19 +17,17 @@
//! header with its proof-of-work. Any valid mined blocks are submitted to the //! header with its proof-of-work. Any valid mined blocks are submitted to the
//! network. //! network.
use crate::util::RwLock;
use chrono::prelude::Utc; use chrono::prelude::Utc;
use std::sync::Arc; use std::sync::Arc;
use crate::chain; use crate::chain;
use crate::common::types::StratumServerConfig; use crate::common::types::StratumServerConfig;
use crate::core::core::hash::{Hash, Hashed}; use crate::core::core::hash::{Hash, Hashed};
use crate::core::core::verifier_cache::VerifierCache;
use crate::core::core::{Block, BlockHeader}; use crate::core::core::{Block, BlockHeader};
use crate::core::global; use crate::core::global;
use crate::mining::mine_block; use crate::mining::mine_block;
use crate::pool;
use crate::util::StopState; use crate::util::StopState;
use crate::{ServerTxPool, ServerVerifierCache};
use grin_chain::SyncState; use grin_chain::SyncState;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -37,8 +35,8 @@ use std::time::Duration;
pub struct Miner { pub struct Miner {
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
stop_state: Arc<StopState>, stop_state: Arc<StopState>,
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
// Just to hold the port we're on, so this miner can be identified // Just to hold the port we're on, so this miner can be identified
@ -47,13 +45,13 @@ pub struct Miner {
} }
impl Miner { impl Miner {
/// Creates a new Miner. Needs references to the chain state and its // Creates a new Miner. Needs references to the chain state and its
/// storage. /// storage.
pub fn new( pub fn new(
config: StratumServerConfig, config: StratumServerConfig,
chain: Arc<chain::Chain>, chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>, tx_pool: ServerTxPool,
verifier_cache: Arc<RwLock<dyn VerifierCache>>, verifier_cache: ServerVerifierCache,
stop_state: Arc<StopState>, stop_state: Arc<StopState>,
sync_state: Arc<SyncState>, sync_state: Arc<SyncState>,
) -> Miner { ) -> Miner {