Skip to content

Commit

Permalink
[miner] Refactor GenerateBlockEvent (starcoinorg#3575)
Browse files Browse the repository at this point in the history
  • Loading branch information
jolestar authored Jul 28, 2022
1 parent 491d158 commit f71484d
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 62 deletions.
2 changes: 1 addition & 1 deletion miner/src/generate_block_event_pacemaker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl ServiceFactory<Self> for GenerateBlockEventPacemaker {

impl GenerateBlockEventPacemaker {
pub fn send_event(&mut self, force: bool, ctx: &mut ServiceContext<Self>) {
ctx.broadcast(GenerateBlockEvent::new(force));
ctx.broadcast(GenerateBlockEvent::new_break(force));
}

pub fn is_synced(&self) -> bool {
Expand Down
55 changes: 13 additions & 42 deletions miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use starcoin_service_registry::{
use std::sync::Arc;
use std::time::Duration;
use types::block::BlockTemplate;
use types::system_events::GenerateSleepBlockEvent;

mod create_block_template;
pub mod generate_block_event_pacemaker;
Expand Down Expand Up @@ -128,13 +127,11 @@ impl ServiceFactory<MinerService> for MinerService {
impl ActorService for MinerService {
fn started(&mut self, ctx: &mut ServiceContext<Self>) -> Result<()> {
ctx.subscribe::<GenerateBlockEvent>();
ctx.subscribe::<GenerateSleepBlockEvent>();
Ok(())
}

fn stopped(&mut self, ctx: &mut ServiceContext<Self>) -> Result<()> {
ctx.unsubscribe::<GenerateBlockEvent>();
ctx.unsubscribe::<GenerateSleepBlockEvent>();
Ok(())
}
}
Expand All @@ -157,7 +154,11 @@ impl ServiceHandler<Self, SubmitSealRequest> for MinerService {
const MAX_BLOCK_TIME_GAP: u64 = 3600 * 1000;

impl MinerService {
pub fn dispatch_task(&mut self, ctx: &mut ServiceContext<MinerService>) -> Result<()> {
pub fn dispatch_task(
&mut self,
ctx: &mut ServiceContext<MinerService>,
event: GenerateBlockEvent,
) -> Result<()> {
//create block template should block_on for avoid mint same block template.
let response = block_on(async {
self.create_block_template_service
Expand All @@ -168,10 +169,11 @@ impl MinerService {
let block_template = response.template;
let block_time_gap = block_template.timestamp - parent.timestamp();

if block_template.body.transactions.is_empty()
if !event.skip_empty_block_check
&& (block_template.body.transactions.is_empty()
&& self.config.miner.is_disable_mint_empty_block()
//if block time gap > 3600, force create a empty block for fix https://github.com/starcoinorg/starcoin/issues/3036
&& block_time_gap < MAX_BLOCK_TIME_GAP
&& block_time_gap < MAX_BLOCK_TIME_GAP)
{
debug!("The flag disable_mint_empty_block is true and no txn in pool, so skip mint empty block.");
Ok(())
Expand Down Expand Up @@ -270,56 +272,25 @@ impl MinerService {
impl EventHandler<Self, GenerateBlockEvent> for MinerService {
fn handle_event(&mut self, event: GenerateBlockEvent, ctx: &mut ServiceContext<MinerService>) {
debug!("Handle GenerateBlockEvent:{:?}", event);
if !event.force && self.is_minting() {
if !event.break_current_task && self.is_minting() {
debug!("Miner has mint job so just ignore this event.");
return;
}
if self.config.miner.disable_miner_client() && self.client_subscribers_num == 0 {
debug!("No miner client connected, ignore GenerateBlockEvent.");
// Once Miner client connect, we should dispatch task.
ctx.run_later(Duration::from_secs(2), |ctx| {
ctx.notify(GenerateBlockEvent::new(false));
ctx.notify(GenerateBlockEvent::default());
});
return;
}
if let Err(err) = self.dispatch_task(ctx) {
if let Err(err) = self.dispatch_task(ctx, event) {
warn!(
"Failed to process generate block event:{}, delay to trigger a new event.",
err
);
ctx.run_later(Duration::from_secs(2), |ctx| {
ctx.notify(GenerateBlockEvent::new(false));
});
}
}
}

impl EventHandler<Self, GenerateSleepBlockEvent> for MinerService {
fn handle_event(
&mut self,
event: GenerateSleepBlockEvent,
ctx: &mut ServiceContext<MinerService>,
) {
debug!("Handle GenerateSleepBlockEvent:{:?}", event);
if !event.force && self.is_minting() {
debug!("Miner has mint job so just ignore this event.");
return;
}
if self.config.miner.disable_miner_client() && self.client_subscribers_num == 0 {
debug!("No miner client connected, ignore GenerateSleepBlockEvent.");
// Once Miner client connect, we should dispatch task.
ctx.run_later(Duration::from_secs(2), |ctx| {
ctx.notify(GenerateSleepBlockEvent::new(false));
});
return;
}
if let Err(err) = self.dispatch_sleep_task(ctx) {
warn!(
"Failed to process generate sleep block event:{}, delay to trigger a new event.",
err
);
ctx.run_later(Duration::from_secs(2), |ctx| {
ctx.notify(GenerateSleepBlockEvent::new(false));
ctx.run_later(Duration::from_secs(2), move |ctx| {
ctx.notify(GenerateBlockEvent::default());
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions miner/tests/miner_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ async fn test_miner_service() {
assert!(miner.is_ok());

let miner = miner.unwrap();
miner.notify(GenerateBlockEvent::new(false)).unwrap();
miner.notify(GenerateBlockEvent::new_break(false)).unwrap();

sleep(Duration::from_millis(200)).await;
miner.notify(GenerateBlockEvent::new(true)).unwrap();
miner.notify(GenerateBlockEvent::new_break(true)).unwrap();
sleep(Duration::from_millis(200)).await;
// Generate a event
let diff = U256::from(1024);
Expand Down
2 changes: 1 addition & 1 deletion node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl NodeHandle {
let head = chain_service.main_head_block().await?;
debug!("generate_block: current head block: {:?}", head.header);
let receiver = bus.oneshot::<NewHeadBlock>().await?;
bus.broadcast(GenerateBlockEvent::new(true))?;
bus.broadcast(GenerateBlockEvent::new_break(true))?;
let block = if let Ok(Ok(event)) =
async_std::future::timeout(Duration::from_secs(5), receiver).await
{
Expand Down
4 changes: 2 additions & 2 deletions rpc/server/src/module/debug_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use starcoin_rpc_api::debug::DebugApi;
use starcoin_rpc_api::types::FactoryAction;
use starcoin_service_registry::bus::{Bus, BusService};
use starcoin_service_registry::ServiceRef;
use starcoin_types::system_events::GenerateSleepBlockEvent;
use starcoin_types::system_events::GenerateBlockEvent;
use std::str::FromStr;
use std::sync::Arc;

Expand Down Expand Up @@ -74,7 +74,7 @@ impl DebugApi for DebugRpcImpl {
}
self.config.net().time_service().sleep(time);
self.bus
.broadcast(GenerateSleepBlockEvent::new(true))
.broadcast(GenerateBlockEvent::new(true, true))
.map_err(|_e| jsonrpc_core::Error::internal_error())?;
Ok(())
}
Expand Down
33 changes: 19 additions & 14 deletions types/src/system_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,30 @@ pub struct SyncStatusChangeEvent(pub SyncStatus);
///Fire this event for generate a new block
#[derive(Clone, Debug)]
pub struct GenerateBlockEvent {
/// Force break current minting, and Generate new block.
pub force: bool,
/// Force break current minting task, and Generate new block.
pub break_current_task: bool,
/// Skip the empty block check, see MinerConfig::disable_mint_empty_block
pub skip_empty_block_check: bool,
}

impl GenerateBlockEvent {
pub fn new(force: bool) -> Self {
Self { force }
impl Default for GenerateBlockEvent {
fn default() -> Self {
Self::new(false, false)
}
}

#[derive(Clone, Debug)]
pub struct GenerateSleepBlockEvent {
/// Force break current minting, and Generate new block.
pub force: bool,
}

impl GenerateSleepBlockEvent {
pub fn new(force: bool) -> Self {
Self { force }
impl GenerateBlockEvent {
pub fn new(break_current_task: bool, skip_empty_block_check: bool) -> Self {
Self {
break_current_task,
skip_empty_block_check,
}
}
pub fn new_break(break_current_task: bool) -> Self {
Self {
break_current_task,
skip_empty_block_check: false,
}
}
}

Expand Down

0 comments on commit f71484d

Please sign in to comment.