mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 08:51:08 +03:00
Cleanup generics (where not needed) (#1429)
BlockChain does not need to be generic
This commit is contained in:
parent
dd164e153d
commit
a6bd81fdb3
16 changed files with 78 additions and 113 deletions
|
@ -694,14 +694,11 @@ impl Handler for HeaderHandler {
|
|||
}
|
||||
|
||||
// Get basic information about the transaction pool.
|
||||
struct PoolInfoHandler<T> {
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>,
|
||||
struct PoolInfoHandler {
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool>>,
|
||||
}
|
||||
|
||||
impl<T> Handler for PoolInfoHandler<T>
|
||||
where
|
||||
T: pool::BlockChain + Send + Sync,
|
||||
{
|
||||
impl Handler for PoolInfoHandler {
|
||||
fn get(&self, _req: Request<Body>) -> ResponseFuture {
|
||||
let pool_arc = w(&self.tx_pool);
|
||||
let pool = pool_arc.read().unwrap();
|
||||
|
@ -719,14 +716,11 @@ struct TxWrapper {
|
|||
}
|
||||
|
||||
// Push new transaction to our local transaction pool.
|
||||
struct PoolPushHandler<T> {
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>,
|
||||
struct PoolPushHandler {
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool>>,
|
||||
}
|
||||
|
||||
impl<T> PoolPushHandler<T>
|
||||
where
|
||||
T: pool::BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
impl PoolPushHandler {
|
||||
fn update_pool(&self, req: Request<Body>) -> Box<Future<Item = (), Error = Error> + Send> {
|
||||
let params = match req.uri().query() {
|
||||
Some(query_string) => form_urlencoded::parse(query_string.as_bytes())
|
||||
|
@ -779,10 +773,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Handler for PoolPushHandler<T>
|
||||
where
|
||||
T: pool::BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
impl Handler for PoolPushHandler {
|
||||
fn post(&self, req: Request<Body>) -> ResponseFuture {
|
||||
Box::new(
|
||||
self.update_pool(req)
|
||||
|
@ -861,14 +852,12 @@ thread_local!( static ROUTER: RefCell<Option<Router>> = RefCell::new(None) );
|
|||
/// weak references. Note that this likely means a crash if the handlers are
|
||||
/// used after a server shutdown (which should normally never happen,
|
||||
/// except during tests).
|
||||
pub fn start_rest_apis<T>(
|
||||
pub fn start_rest_apis(
|
||||
addr: String,
|
||||
chain: Weak<chain::Chain>,
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>,
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool>>,
|
||||
peers: Weak<p2p::Peers>,
|
||||
) where
|
||||
T: pool::BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
) {
|
||||
let _ = thread::Builder::new()
|
||||
.name("apis".to_string())
|
||||
.spawn(move || {
|
||||
|
@ -912,14 +901,11 @@ where
|
|||
)
|
||||
}
|
||||
|
||||
pub fn build_router<T>(
|
||||
pub fn build_router(
|
||||
chain: Weak<chain::Chain>,
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool<T>>>,
|
||||
tx_pool: Weak<RwLock<pool::TransactionPool>>,
|
||||
peers: Weak<p2p::Peers>,
|
||||
) -> Result<Router, RouterError>
|
||||
where
|
||||
T: pool::BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
) -> Result<Router, RouterError> {
|
||||
let route_list = vec![
|
||||
"get blocks".to_string(),
|
||||
"get chain".to_string(),
|
||||
|
|
|
@ -550,10 +550,12 @@ impl Chain {
|
|||
/// If we're willing to accept that new state, the data stream will be
|
||||
/// read as a zip file, unzipped and the resulting state files should be
|
||||
/// rewound to the provided indexes.
|
||||
pub fn txhashset_write<T>(&self, h: Hash, txhashset_data: File, status: &T) -> Result<(), Error>
|
||||
where
|
||||
T: TxHashsetWriteStatus,
|
||||
{
|
||||
pub fn txhashset_write(
|
||||
&self,
|
||||
h: Hash,
|
||||
txhashset_data: File,
|
||||
status: &TxHashsetWriteStatus,
|
||||
) -> Result<(), Error> {
|
||||
status.on_setup();
|
||||
let head = self.head().unwrap();
|
||||
let header_head = self.get_header_head().unwrap();
|
||||
|
|
|
@ -866,15 +866,12 @@ impl<'a> Extension<'a> {
|
|||
}
|
||||
|
||||
/// Validate the txhashset state against the provided block header.
|
||||
pub fn validate<T>(
|
||||
pub fn validate(
|
||||
&mut self,
|
||||
header: &BlockHeader,
|
||||
skip_rproofs: bool,
|
||||
status: &T,
|
||||
) -> Result<((Commitment, Commitment)), Error>
|
||||
where
|
||||
T: TxHashsetWriteStatus,
|
||||
{
|
||||
status: &TxHashsetWriteStatus,
|
||||
) -> Result<((Commitment, Commitment)), Error> {
|
||||
self.validate_mmrs()?;
|
||||
self.validate_roots(header)?;
|
||||
|
||||
|
@ -952,10 +949,7 @@ impl<'a> Extension<'a> {
|
|||
)
|
||||
}
|
||||
|
||||
fn verify_kernel_signatures<T>(&self, status: &T) -> Result<(), Error>
|
||||
where
|
||||
T: TxHashsetWriteStatus,
|
||||
{
|
||||
fn verify_kernel_signatures(&self, status: &TxHashsetWriteStatus) -> Result<(), Error> {
|
||||
let now = Instant::now();
|
||||
|
||||
let mut kern_count = 0;
|
||||
|
@ -983,10 +977,7 @@ impl<'a> Extension<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_rangeproofs<T>(&self, status: &T) -> Result<(), Error>
|
||||
where
|
||||
T: TxHashsetWriteStatus,
|
||||
{
|
||||
fn verify_rangeproofs(&self, status: &TxHashsetWriteStatus) -> Result<(), Error> {
|
||||
let now = Instant::now();
|
||||
|
||||
let mut commits: Vec<Commitment> = vec![];
|
||||
|
|
|
@ -33,19 +33,16 @@ const MAX_MINEABLE_WEIGHT: usize =
|
|||
// longest chain of dependent transactions that can be included in a block
|
||||
const MAX_TX_CHAIN: usize = 20;
|
||||
|
||||
pub struct Pool<T> {
|
||||
pub struct Pool {
|
||||
/// Entries in the pool (tx + info + timer) in simple insertion order.
|
||||
pub entries: Vec<PoolEntry>,
|
||||
/// The blockchain
|
||||
pub blockchain: Arc<T>,
|
||||
pub blockchain: Arc<BlockChain>,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl<T> Pool<T>
|
||||
where
|
||||
T: BlockChain,
|
||||
{
|
||||
pub fn new(chain: Arc<T>, name: String) -> Pool<T> {
|
||||
impl Pool {
|
||||
pub fn new(chain: Arc<BlockChain>, name: String) -> Pool {
|
||||
Pool {
|
||||
entries: vec![],
|
||||
blockchain: chain.clone(),
|
||||
|
|
|
@ -26,27 +26,26 @@ use pool::Pool;
|
|||
use types::{BlockChain, PoolAdapter, PoolConfig, PoolEntry, PoolEntryState, PoolError, TxSource};
|
||||
|
||||
/// Transaction pool implementation.
|
||||
pub struct TransactionPool<T> {
|
||||
pub struct TransactionPool {
|
||||
/// Pool Config
|
||||
pub config: PoolConfig,
|
||||
|
||||
/// Our transaction pool.
|
||||
pub txpool: Pool<T>,
|
||||
pub txpool: Pool,
|
||||
/// Our Dandelion "stempool".
|
||||
pub stempool: Pool<T>,
|
||||
|
||||
pub stempool: Pool,
|
||||
/// The blockchain
|
||||
pub blockchain: Arc<T>,
|
||||
pub blockchain: Arc<BlockChain>,
|
||||
/// The pool adapter
|
||||
pub adapter: Arc<PoolAdapter>,
|
||||
}
|
||||
|
||||
impl<T> TransactionPool<T>
|
||||
where
|
||||
T: BlockChain,
|
||||
{
|
||||
impl TransactionPool {
|
||||
/// Create a new transaction pool
|
||||
pub fn new(config: PoolConfig, chain: Arc<T>, adapter: Arc<PoolAdapter>) -> TransactionPool<T> {
|
||||
pub fn new(
|
||||
config: PoolConfig,
|
||||
chain: Arc<BlockChain>,
|
||||
adapter: Arc<PoolAdapter>,
|
||||
) -> TransactionPool {
|
||||
TransactionPool {
|
||||
config: config,
|
||||
txpool: Pool::new(chain.clone(), format!("txpool")),
|
||||
|
|
|
@ -187,7 +187,7 @@ impl From<transaction::Error> for PoolError {
|
|||
}
|
||||
|
||||
/// Interface that the pool requires from a blockchain implementation.
|
||||
pub trait BlockChain {
|
||||
pub trait BlockChain: Sync + Send {
|
||||
/// Validate a vec of txs against known chain state at specific block
|
||||
/// after applying the pre_tx to the chain state.
|
||||
fn validate_raw_txs(
|
||||
|
|
|
@ -34,15 +34,13 @@ use keychain::{ExtKeychain, Keychain};
|
|||
use pool::types::{BlockChain, NoopAdapter, PoolConfig, PoolError};
|
||||
use pool::TransactionPool;
|
||||
|
||||
pub fn test_setup(
|
||||
chain: &Arc<CoinbaseMaturityErrorChainAdapter>,
|
||||
) -> TransactionPool<CoinbaseMaturityErrorChainAdapter> {
|
||||
pub fn test_setup(chain: CoinbaseMaturityErrorChainAdapter) -> TransactionPool {
|
||||
TransactionPool::new(
|
||||
PoolConfig {
|
||||
accept_fee_base: 0,
|
||||
max_pool_size: 50,
|
||||
},
|
||||
chain.clone(),
|
||||
Arc::new(chain.clone()),
|
||||
Arc::new(NoopAdapter {}),
|
||||
)
|
||||
}
|
||||
|
@ -89,7 +87,7 @@ fn test_coinbase_maturity() {
|
|||
// Mocking this up with an adapter that will raise an error for coinbase
|
||||
// maturity.
|
||||
let chain = CoinbaseMaturityErrorChainAdapter::new();
|
||||
let pool = RwLock::new(test_setup(&Arc::new(chain.clone())));
|
||||
let pool = RwLock::new(test_setup(chain));
|
||||
|
||||
{
|
||||
let mut write_pool = pool.write().unwrap();
|
||||
|
|
|
@ -105,7 +105,7 @@ impl BlockChain for ChainAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn test_setup(chain: &Arc<ChainAdapter>) -> TransactionPool<ChainAdapter> {
|
||||
pub fn test_setup(chain: &Arc<ChainAdapter>) -> TransactionPool {
|
||||
TransactionPool::new(
|
||||
PoolConfig {
|
||||
accept_fee_base: 0,
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct NetToChainAdapter {
|
|||
sync_state: Arc<SyncState>,
|
||||
archive_mode: bool,
|
||||
chain: Weak<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
peers: OneTime<Weak<p2p::Peers>>,
|
||||
config: ServerConfig,
|
||||
}
|
||||
|
@ -164,7 +164,8 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
|||
}
|
||||
};
|
||||
|
||||
let chain = self.chain
|
||||
let chain = self
|
||||
.chain
|
||||
.upgrade()
|
||||
.expect("failed to upgrade weak ref to chain");
|
||||
|
||||
|
@ -372,7 +373,7 @@ impl NetToChainAdapter {
|
|||
sync_state: Arc<SyncState>,
|
||||
archive_mode: bool,
|
||||
chain_ref: Weak<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
config: ServerConfig,
|
||||
) -> NetToChainAdapter {
|
||||
NetToChainAdapter {
|
||||
|
@ -437,7 +438,8 @@ impl NetToChainAdapter {
|
|||
// we have a fast sync'd node and are sent a block older than our horizon,
|
||||
// only sync can do something with that
|
||||
if b.header.height
|
||||
< head.height
|
||||
< head
|
||||
.height
|
||||
.saturating_sub(global::cut_through_horizon() as u64)
|
||||
{
|
||||
return true;
|
||||
|
@ -602,7 +604,7 @@ impl NetToChainAdapter {
|
|||
/// the network to broadcast the block
|
||||
pub struct ChainToPoolAndNetAdapter {
|
||||
sync_state: Arc<SyncState>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
peers: OneTime<Weak<p2p::Peers>>,
|
||||
}
|
||||
|
||||
|
@ -665,7 +667,7 @@ impl ChainToPoolAndNetAdapter {
|
|||
/// Construct a ChainToPoolAndNetAdapter instance.
|
||||
pub fn new(
|
||||
sync_state: Arc<SyncState>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
) -> ChainToPoolAndNetAdapter {
|
||||
ChainToPoolAndNetAdapter {
|
||||
sync_state,
|
||||
|
|
|
@ -21,7 +21,7 @@ use std::time::Duration;
|
|||
|
||||
use core::core::hash::Hashed;
|
||||
use core::core::transaction;
|
||||
use pool::{BlockChain, DandelionConfig, PoolEntryState, PoolError, TransactionPool, TxSource};
|
||||
use pool::{DandelionConfig, PoolEntryState, PoolError, TransactionPool, TxSource};
|
||||
use util::LOGGER;
|
||||
|
||||
/// A process to monitor transactions in the stempool.
|
||||
|
@ -32,13 +32,11 @@ use util::LOGGER;
|
|||
/// stempool and test if the timer is expired for each transaction. In that case
|
||||
/// the transaction will be sent in fluff phase (to multiple peers) instead of
|
||||
/// sending only to the peer relay.
|
||||
pub fn monitor_transactions<T>(
|
||||
pub fn monitor_transactions(
|
||||
dandelion_config: DandelionConfig,
|
||||
tx_pool: Arc<RwLock<TransactionPool<T>>>,
|
||||
tx_pool: Arc<RwLock<TransactionPool>>,
|
||||
stop: Arc<AtomicBool>,
|
||||
) where
|
||||
T: BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
) {
|
||||
debug!(LOGGER, "Started Dandelion transaction monitor.");
|
||||
|
||||
let _ = thread::Builder::new()
|
||||
|
@ -84,10 +82,7 @@ pub fn monitor_transactions<T>(
|
|||
});
|
||||
}
|
||||
|
||||
fn process_stem_phase<T>(tx_pool: Arc<RwLock<TransactionPool<T>>>) -> Result<(), PoolError>
|
||||
where
|
||||
T: BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
fn process_stem_phase(tx_pool: Arc<RwLock<TransactionPool>>) -> Result<(), PoolError> {
|
||||
let mut tx_pool = tx_pool.write().unwrap();
|
||||
|
||||
let header = tx_pool.blockchain.chain_head()?;
|
||||
|
@ -127,10 +122,7 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn process_fluff_phase<T>(tx_pool: Arc<RwLock<TransactionPool<T>>>) -> Result<(), PoolError>
|
||||
where
|
||||
T: BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
fn process_fluff_phase(tx_pool: Arc<RwLock<TransactionPool>>) -> Result<(), PoolError> {
|
||||
let mut tx_pool = tx_pool.write().unwrap();
|
||||
|
||||
let header = tx_pool.blockchain.chain_head()?;
|
||||
|
@ -162,13 +154,10 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn process_fresh_entries<T>(
|
||||
fn process_fresh_entries(
|
||||
dandelion_config: DandelionConfig,
|
||||
tx_pool: Arc<RwLock<TransactionPool<T>>>,
|
||||
) -> Result<(), PoolError>
|
||||
where
|
||||
T: BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
tx_pool: Arc<RwLock<TransactionPool>>,
|
||||
) -> Result<(), PoolError> {
|
||||
let mut tx_pool = tx_pool.write().unwrap();
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
|
@ -199,13 +188,10 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn process_expired_entries<T>(
|
||||
fn process_expired_entries(
|
||||
dandelion_config: DandelionConfig,
|
||||
tx_pool: Arc<RwLock<TransactionPool<T>>>,
|
||||
) -> Result<(), PoolError>
|
||||
where
|
||||
T: BlockChain + Send + Sync + 'static,
|
||||
{
|
||||
tx_pool: Arc<RwLock<TransactionPool>>,
|
||||
) -> Result<(), PoolError> {
|
||||
let now = Utc::now().timestamp();
|
||||
let embargo_sec = dandelion_config.embargo_secs.unwrap() + rand::thread_rng().gen_range(0, 31);
|
||||
let cutoff = now - embargo_sec as i64;
|
||||
|
|
|
@ -48,7 +48,7 @@ pub struct Server {
|
|||
/// data store access
|
||||
pub chain: Arc<chain::Chain>,
|
||||
/// in-memory transaction pool
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
/// Whether we're currently syncing
|
||||
sync_state: Arc<SyncState>,
|
||||
/// To be passed around to collect stats and info
|
||||
|
@ -421,7 +421,8 @@ impl Server {
|
|||
}
|
||||
};
|
||||
|
||||
let peer_stats = self.p2p
|
||||
let peer_stats = self
|
||||
.p2p
|
||||
.peers
|
||||
.connected_peers()
|
||||
.into_iter()
|
||||
|
|
|
@ -23,7 +23,6 @@ use std::thread;
|
|||
use std::time::Duration;
|
||||
|
||||
use chain;
|
||||
use common::adapters::PoolToChainAdapter;
|
||||
use common::types::Error;
|
||||
use core::ser::{self, AsFixedBytes};
|
||||
use core::{consensus, core};
|
||||
|
@ -76,7 +75,7 @@ impl ser::Writer for HeaderPrePowWriter {
|
|||
// Warning: This call does not return until/unless a new block can be built
|
||||
pub fn get_block(
|
||||
chain: &Arc<chain::Chain>,
|
||||
tx_pool: &Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: &Arc<RwLock<pool::TransactionPool>>,
|
||||
key_id: Option<Identifier>,
|
||||
wallet_listener_url: Option<String>,
|
||||
) -> (core::Block, BlockFees) {
|
||||
|
@ -118,7 +117,7 @@ pub fn get_block(
|
|||
/// transactions from the pool.
|
||||
fn build_block(
|
||||
chain: &Arc<chain::Chain>,
|
||||
tx_pool: &Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: &Arc<RwLock<pool::TransactionPool>>,
|
||||
key_id: Option<Identifier>,
|
||||
wallet_listener_url: Option<String>,
|
||||
) -> Result<(core::Block, BlockFees), Error> {
|
||||
|
|
|
@ -26,7 +26,6 @@ use std::time::{Duration, SystemTime};
|
|||
use std::{cmp, thread};
|
||||
|
||||
use chain;
|
||||
use common::adapters::PoolToChainAdapter;
|
||||
use common::stats::{StratumStats, WorkerStats};
|
||||
use common::types::{StratumServerConfig, SyncState};
|
||||
use core::core::Block;
|
||||
|
@ -229,7 +228,7 @@ pub struct StratumServer {
|
|||
id: String,
|
||||
config: StratumServerConfig,
|
||||
chain: Arc<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
current_block_versions: Vec<Block>,
|
||||
current_difficulty: u64,
|
||||
minimum_share_difficulty: u64,
|
||||
|
@ -243,7 +242,7 @@ impl StratumServer {
|
|||
pub fn new(
|
||||
config: StratumServerConfig,
|
||||
chain_ref: Arc<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
) -> StratumServer {
|
||||
StratumServer {
|
||||
id: String::from("StratumServer"),
|
||||
|
|
|
@ -22,7 +22,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use chain;
|
||||
use common::adapters::PoolToChainAdapter;
|
||||
use common::types::StratumServerConfig;
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::core::{Block, BlockHeader, Proof};
|
||||
|
@ -35,7 +34,7 @@ use util::LOGGER;
|
|||
pub struct Miner {
|
||||
config: StratumServerConfig,
|
||||
chain: Arc<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
stop: Arc<AtomicBool>,
|
||||
|
||||
// Just to hold the port we're on, so this miner can be identified
|
||||
|
@ -49,7 +48,7 @@ impl Miner {
|
|||
pub fn new(
|
||||
config: StratumServerConfig,
|
||||
chain_ref: Arc<chain::Chain>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
|
||||
tx_pool: Arc<RwLock<pool::TransactionPool>>,
|
||||
stop: Arc<AtomicBool>,
|
||||
) -> Miner {
|
||||
Miner {
|
||||
|
|
|
@ -35,6 +35,9 @@ pub struct LeafSet {
|
|||
bitmap_bak: Bitmap,
|
||||
}
|
||||
|
||||
unsafe impl Send for LeafSet {}
|
||||
unsafe impl Sync for LeafSet {}
|
||||
|
||||
impl LeafSet {
|
||||
/// Open the remove log file.
|
||||
/// The content of the file will be read in memory for fast checking.
|
||||
|
|
|
@ -48,6 +48,9 @@ pub struct PruneList {
|
|||
bitmap: Bitmap,
|
||||
}
|
||||
|
||||
unsafe impl Send for PruneList {}
|
||||
unsafe impl Sync for PruneList {}
|
||||
|
||||
impl PruneList {
|
||||
/// Instantiate a new empty prune list
|
||||
pub fn new() -> PruneList {
|
||||
|
|
Loading…
Reference in a new issue