Skip to content

Commit 69b1df8

Browse files
author
Hyunsik Jeong
committed
Add reseal timer to client
1 parent e186a44 commit 69b1df8

File tree

6 files changed

+79
-11
lines changed

6 files changed

+79
-11
lines changed

codechain/run_node.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,22 @@ fn discovery_start(service: &NetworkService, cfg: &config::Network) -> Result<()
8686
Ok(())
8787
}
8888

89-
fn client_start(cfg: &config::Operating, scheme: &Scheme, miner: Arc<Miner>) -> Result<ClientService, String> {
89+
fn client_start(
90+
timer_loop: &TimerLoop,
91+
cfg: &config::Operating,
92+
scheme: &Scheme,
93+
miner: Arc<Miner>,
94+
) -> Result<ClientService, String> {
9095
cinfo!(CLIENT, "Starting client");
9196
let db_path = cfg.db_path.as_ref().map(|s| s.as_str()).unwrap();
9297
let client_path = Path::new(db_path);
9398
let client_config = Default::default();
9499
let service = ClientService::start(&client_config, &scheme, &client_path, miner)
95100
.map_err(|e| format!("Client service error: {}", e))?;
96101

102+
let reseal_timer = timer_loop.new_timer("Client reseal timer", service.client());
103+
service.client().register_reseal_timer(reseal_timer);
104+
97105
Ok(service)
98106
}
99107

@@ -229,7 +237,7 @@ pub fn run_node(matches: &ArgMatches) -> Result<(), String> {
229237
unlock_accounts(&*ap, &pf)?;
230238

231239
let miner = new_miner(&config, &scheme, ap.clone())?;
232-
let client = client_start(&config.operating, &scheme, miner.clone())?;
240+
let client = client_start(&timer_loop, &config.operating, &scheme, miner.clone())?;
233241
let sync = BlockSyncExtension::new(client.client());
234242

235243
scheme.engine.register_chain_notify(client.client().as_ref());

core/src/client/client.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
1818
use std::sync::{Arc, Weak};
19-
use std::time::Instant;
19+
use std::time::{Duration, Instant};
2020

2121
use cio::IoChannel;
2222
use ckey::{Address, PlatformAddress, Public};
@@ -25,6 +25,7 @@ use cnetwork::NodeId;
2525
use cstate::{
2626
ActionHandler, AssetScheme, AssetSchemeAddress, OwnedAsset, OwnedAssetAddress, StateDB, TopLevelState, TopStateView,
2727
};
28+
use ctimer::{TimeoutHandler, TimerApi, TimerToken};
2829
use ctypes::invoice::Invoice;
2930
use ctypes::transaction::Transaction;
3031
use ctypes::{BlockNumber, ShardId};
@@ -41,7 +42,8 @@ use super::{
4142
AccountData, AssetClient, Balance, BlockChain as BlockChainTrait, BlockChainClient, BlockChainInfo, BlockInfo,
4243
BlockProducer, ChainInfo, ChainNotify, ClientConfig, DatabaseClient, EngineClient, EngineInfo,
4344
Error as ClientError, ExecuteClient, ImportBlock, ImportResult, ImportSealedBlock, MiningBlockChainClient,
44-
ParcelInfo, PrepareOpenBlock, RegularKey, RegularKeyOwner, ReopenBlock, Seq, Shard, StateOrBlock, TransactionInfo,
45+
ParcelInfo, PrepareOpenBlock, RegularKey, RegularKeyOwner, ReopenBlock, ResealTimer, Seq, Shard, StateOrBlock,
46+
TransactionInfo,
4547
};
4648
use crate::block::{ClosedBlock, IsBlock, OpenBlock, SealedBlock};
4749
use crate::blockchain::{
@@ -79,6 +81,8 @@ pub struct Client {
7981
genesis_accounts: Vec<Address>,
8082

8183
importer: Importer,
84+
85+
reseal_timer: RwLock<Option<TimerApi>>,
8286
}
8387

8488
impl Client {
@@ -121,13 +125,18 @@ impl Client {
121125
queue_parcels: AtomicUsize::new(0),
122126
genesis_accounts,
123127
importer,
128+
reseal_timer: RwLock::new(None),
124129
});
125130

126131
// ensure buffered changes are flushed.
127132
client.db.read().flush().map_err(ClientError::Database)?;
128133
Ok(client)
129134
}
130135

136+
pub fn register_reseal_timer(&self, timer: TimerApi) {
137+
self.register_timer(timer);
138+
}
139+
131140
/// Returns engine reference.
132141
pub fn engine(&self) -> &CodeChainEngine {
133142
&*self.engine
@@ -260,6 +269,34 @@ impl Client {
260269
}
261270
}
262271

272+
const RESEAL_TIMER_TOKEN: TimerToken = 0;
273+
274+
impl TimeoutHandler for Client {
275+
fn on_timeout(&self, token: TimerToken) {
276+
match token {
277+
RESEAL_TIMER_TOKEN => {
278+
if !self.ready_parcels().is_empty() {
279+
self.update_sealing();
280+
}
281+
}
282+
_ => unreachable!(),
283+
}
284+
}
285+
}
286+
287+
impl ResealTimer for Client {
288+
fn register_timer(&self, timer: TimerApi) {
289+
*self.reseal_timer.write() = Some(timer);
290+
}
291+
292+
fn set_timer(&self, duration: Duration) {
293+
if let Some(reseal_timer) = self.reseal_timer.read().as_ref() {
294+
reseal_timer.cancel(RESEAL_TIMER_TOKEN).expect("Timer clear succeeds");
295+
reseal_timer.schedule_once(duration, RESEAL_TIMER_TOKEN).expect("Timer set succeeds");
296+
};
297+
}
298+
}
299+
263300
impl DatabaseClient for Client {
264301
fn database(&self) -> Arc<KeyValueDB> {
265302
Arc::clone(&self.db())

core/src/client/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ pub use self::error::Error;
3030
pub use self::test_client::TestBlockChainClient;
3131

3232
use std::sync::Arc;
33+
use std::time::Duration;
3334

3435
use ckey::{Address, PlatformAddress, Public};
3536
use cmerkle::Result as TrieResult;
3637
use cnetwork::NodeId;
3738
use cstate::{ActionHandler, AssetScheme, AssetSchemeAddress, OwnedAsset, TopStateView};
39+
use ctimer::TimerApi;
3840
use ctypes::invoice::Invoice;
3941
use ctypes::transaction::Transaction;
4042
use ctypes::{BlockNumber, ShardId};
@@ -183,6 +185,11 @@ pub trait Shard {
183185
fn shard_root(&self, shard_id: ShardId, state: StateOrBlock) -> Option<H256>;
184186
}
185187

188+
pub trait ResealTimer {
189+
fn register_timer(&self, timer: TimerApi);
190+
fn set_timer(&self, duration: Duration);
191+
}
192+
186193
/// Provides methods to access account info
187194
pub trait AccountData: Seq + Balance {}
188195

@@ -200,7 +207,7 @@ pub trait BlockChain: ChainInfo + BlockInfo + ParcelInfo + TransactionInfo {}
200207

201208
/// Blockchain database client. Owns and manages a blockchain and a block queue.
202209
pub trait BlockChainClient:
203-
Sync + Send + AccountData + BlockChain + ImportBlock + RegularKeyOwner + ChainTimeInfo {
210+
Sync + Send + AccountData + BlockChain + ImportBlock + RegularKeyOwner + ChainTimeInfo + ResealTimer {
204211
/// Get block queue information.
205212
fn queue_info(&self) -> BlockQueueInfo;
206213

core/src/client/test_client.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ use std::collections::HashMap;
3434
use std::mem;
3535
use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
3636
use std::sync::Arc;
37+
use std::time::Duration;
3738

3839
use ckey::{public_to_address, Address, Generator, NetworkId, PlatformAddress, Random};
3940
use cmerkle::skewed_merkle_root;
4041
use cnetwork::NodeId;
4142
use cstate::{ActionHandler, StateDB};
43+
use ctimer::{TimeoutHandler, TimerApi, TimerToken};
4244
use ctypes::invoice::Invoice;
4345
use ctypes::parcel::{Action, Parcel};
4446
use ctypes::transaction::Transaction;
@@ -55,8 +57,8 @@ use crate::blockchain_info::BlockChainInfo;
5557
use crate::client::ImportResult;
5658
use crate::client::{
5759
AccountData, Balance, BlockChain, BlockChainClient, BlockInfo, BlockProducer, BlockStatus, ChainInfo, ImportBlock,
58-
ImportSealedBlock, MiningBlockChainClient, ParcelInfo, PrepareOpenBlock, RegularKeyOwner, ReopenBlock, Seq,
59-
StateOrBlock, TransactionInfo,
60+
ImportSealedBlock, MiningBlockChainClient, ParcelInfo, PrepareOpenBlock, RegularKeyOwner, ReopenBlock, ResealTimer,
61+
Seq, StateOrBlock, TransactionInfo,
6062
};
6163
use crate::db::{COL_STATE, NUM_COLUMNS};
6264
use crate::encoded;
@@ -529,6 +531,16 @@ impl BlockChainClient for TestBlockChainClient {
529531
}
530532
}
531533

534+
impl TimeoutHandler for TestBlockChainClient {
535+
fn on_timeout(&self, _token: TimerToken) {}
536+
}
537+
538+
impl ResealTimer for TestBlockChainClient {
539+
fn register_timer(&self, _timer: TimerApi) {}
540+
541+
fn set_timer(&self, _duration: Duration) {}
542+
}
543+
532544
impl ChainTimeInfo for TestBlockChainClient {
533545
fn best_block_number(&self) -> u64 {
534546
0

core/src/miner/miner.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use crate::account_provider::{AccountProvider, SignError};
3737
use crate::block::{Block, ClosedBlock, IsBlock};
3838
use crate::client::{
3939
AccountData, BlockChain, BlockProducer, ImportSealedBlock, MiningBlockChainClient, RegularKey, RegularKeyOwner,
40+
ResealTimer,
4041
};
4142
use crate::consensus::{CodeChainEngine, EngineType};
4243
use crate::error::Error;
@@ -178,7 +179,7 @@ impl Miner {
178179
}
179180

180181
/// Check is reseal is allowed and necessary.
181-
fn requires_reseal(&self, best_block: BlockNumber) -> bool {
182+
fn requires_reseal<C: ResealTimer>(&self, reseal_timer: &C, best_block: BlockNumber) -> bool {
182183
let has_local_parcels = self.mem_pool.read().has_local_pending_parcels();
183184
let mut sealing_work = self.sealing_work.lock();
184185
if sealing_work.enabled {
@@ -205,6 +206,7 @@ impl Miner {
205206
false
206207
} else {
207208
// sealing enabled and we don't want to sleep.
209+
reseal_timer.set_timer(self.options.reseal_min_period);
208210
*self.next_allowed_reseal.lock() = Instant::now() + self.options.reseal_min_period;
209211
true
210212
}
@@ -706,10 +708,11 @@ impl MinerService for Miner {
706708

707709
fn update_sealing<C>(&self, chain: &C)
708710
where
709-
C: AccountData + BlockChain + BlockProducer + ImportSealedBlock + RegularKeyOwner + ChainTimeInfo, {
711+
C: AccountData + BlockChain + BlockProducer + ImportSealedBlock + RegularKeyOwner + ResealTimer + ChainTimeInfo,
712+
{
710713
ctrace!(MINER, "update_sealing: preparing a block");
711714

712-
if self.requires_reseal(chain.chain_info().best_block_number) {
715+
if self.requires_reseal(chain, chain.chain_info().best_block_number) {
713716
let (block, original_work_hash) = match self.prepare_block(chain) {
714717
Ok((block, original_work_hash)) => (block, original_work_hash),
715718
Err(err) => {

core/src/miner/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use crate::account_provider::{AccountProvider, SignError};
3434
use crate::block::ClosedBlock;
3535
use crate::client::{
3636
AccountData, BlockChain, BlockProducer, ImportSealedBlock, MiningBlockChainClient, RegularKey, RegularKeyOwner,
37+
ResealTimer,
3738
};
3839
use crate::consensus::EngineType;
3940
use crate::error::Error;
@@ -82,7 +83,7 @@ pub trait MinerService: Send + Sync {
8283
/// New chain head event. Restart mining operation.
8384
fn update_sealing<C>(&self, chain: &C)
8485
where
85-
C: AccountData + BlockChain + BlockProducer + ImportSealedBlock + RegularKeyOwner + ChainTimeInfo;
86+
C: AccountData + BlockChain + BlockProducer + ImportSealedBlock + RegularKeyOwner + ResealTimer + ChainTimeInfo;
8687

8788
/// Submit `seal` as a valid solution for the header of `pow_hash`.
8889
/// Will check the seal, but not actually insert the block into the chain.

0 commit comments

Comments
 (0)