Skip to content

Commit

Permalink
fix: issue raised in #2913
Browse files Browse the repository at this point in the history
  • Loading branch information
kantai committed Nov 10, 2021
1 parent f688e8c commit 9ee9101
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 44 deletions.
6 changes: 4 additions & 2 deletions src/chainstate/coordinator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ impl BlockEventDispatcher for NullEventDispatcher {
_parent_burn_block_hash: BurnchainHeaderHash,
_parent_burn_block_height: u32,
_parent_burn_block_timestamp: u64,
_anchor_block_cost: &ExecutionCost,
_confirmed_mblock_cost: &ExecutionCost,
) {
assert!(
false,
Expand Down Expand Up @@ -463,7 +465,7 @@ fn make_genesis_block_with_recipients(
.unwrap();

let iconn = sort_db.index_conn();
let mut epoch_tx = builder.epoch_begin(state, &iconn).unwrap();
let mut epoch_tx = builder.epoch_begin(state, &iconn).unwrap().0;
builder.try_mine_tx(&mut epoch_tx, &coinbase_op).unwrap();

let block = builder.mine_anchored_block(&mut epoch_tx);
Expand Down Expand Up @@ -673,7 +675,7 @@ fn make_stacks_block_with_input(
next_hash160(),
)
.unwrap();
let mut epoch_tx = builder.epoch_begin(state, &iconn).unwrap();
let mut epoch_tx = builder.epoch_begin(state, &iconn).unwrap().0;
builder.try_mine_tx(&mut epoch_tx, &coinbase_op).unwrap();

let block = builder.mine_anchored_block(&mut epoch_tx);
Expand Down
91 changes: 69 additions & 22 deletions src/chainstate/stacks/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,14 +1136,16 @@ impl StacksBlockBuilder {
}

/// Begin mining an epoch's transactions.
/// Returns an open ClarityTx for mining the block, as well as the ExecutionCost of any confirmed
/// microblocks.
/// NOTE: even though we don't yet know the block hash, the Clarity VM ensures that a
/// transaction can't query information about the _current_ block (i.e. information that is not
/// yet known).
pub fn epoch_begin<'a>(
&mut self,
chainstate: &'a mut StacksChainState,
burn_dbconn: &'a SortitionDBConn,
) -> Result<ClarityTx<'a>, Error> {
) -> Result<(ClarityTx<'a>, ExecutionCost), Error> {
let mainnet = chainstate.config().mainnet;

// find matured miner rewards, so we can grant them within the Clarity DB tx.
Expand Down Expand Up @@ -1217,6 +1219,12 @@ impl StacksBlockBuilder {
let stacking_burn_ops = SortitionDB::get_stack_stx_ops(burn_dbconn.conn(), &burn_tip)?;
let transfer_burn_ops = SortitionDB::get_transfer_stx_ops(burn_dbconn.conn(), &burn_tip)?;

let parent_block_cost_opt = if parent_microblocks.is_empty() {
None
} else {
StacksChainState::get_stacks_block_anchored_cost(chainstate.db(), &parent_index_hash)?
};

let mut tx = chainstate.block_begin(
burn_dbconn,
&parent_consensus_hash,
Expand All @@ -1243,9 +1251,19 @@ impl StacksBlockBuilder {

let t1 = get_epoch_time_ms();

if parent_microblocks.len() == 0 {
let mblock_confirmed_cost = if parent_microblocks.len() == 0 {
self.set_parent_microblock(&EMPTY_MICROBLOCK_PARENT_HASH, 0);
ExecutionCost::zero()
} else {
let parent_block_cost = parent_block_cost_opt.ok_or_else(|| {
Error::InvalidStacksBlock(format!(
"Failed to load parent block cost. parent_stacks_block_id = {}",
&parent_index_hash
))
})?;

tx.reset_cost(parent_block_cost.clone());

match StacksChainState::process_microblocks_transactions(&mut tx, &parent_microblocks) {
Ok((fees, ..)) => {
self.total_confirmed_streamed_fees += fees as u64;
Expand All @@ -1263,7 +1281,18 @@ impl StacksBlockBuilder {
let num_mblocks = parent_microblocks.len();
let last_mblock_hdr = parent_microblocks[num_mblocks - 1].header.clone();
self.set_parent_microblock(&last_mblock_hdr.block_hash(), last_mblock_hdr.sequence);
}

let mut microblock_cost = tx.cost_so_far();
microblock_cost
.sub(&parent_block_cost)
.expect("BUG: block_cost + microblock_cost < block_cost");

// if we get here, then we need to reset the block-cost back to 0 because this begins the
// block defined by this miner.
tx.reset_cost(ExecutionCost::zero());

microblock_cost
};

let t2 = get_epoch_time_ms();

Expand All @@ -1278,7 +1307,7 @@ impl StacksBlockBuilder {
StacksChainState::process_stacking_ops(&mut tx, stacking_burn_ops);
StacksChainState::process_transfer_ops(&mut tx, transfer_burn_ops);

Ok(tx)
Ok((tx, mblock_confirmed_cost))
}

/// Finish up mining an epoch's transactions
Expand Down Expand Up @@ -1317,7 +1346,7 @@ impl StacksBlockBuilder {
) -> Result<(StacksBlock, u64, ExecutionCost), Error> {
debug!("Build anchored block from {} transactions", txs.len());
let (mut chainstate, _) = chainstate_handle.reopen()?;
let mut epoch_tx = builder.epoch_begin(&mut chainstate, burn_dbconn)?;
let (mut epoch_tx, _) = builder.epoch_begin(&mut chainstate, burn_dbconn)?;
for tx in txs.drain(..) {
match builder.try_mine_tx(&mut epoch_tx, &tx) {
Ok(_) => {
Expand Down Expand Up @@ -1490,7 +1519,8 @@ impl StacksBlockBuilder {

let ts_start = get_epoch_time_ms();

let mut epoch_tx = builder.epoch_begin(&mut chainstate, burn_dbconn)?;
let (mut epoch_tx, confirmed_mblock_cost) =
builder.epoch_begin(&mut chainstate, burn_dbconn)?;

let block_limit = epoch_tx
.block_limit()
Expand Down Expand Up @@ -1669,6 +1699,7 @@ impl StacksBlockBuilder {
&block,
size,
&consumed,
&confirmed_mblock_cost,
);
}

Expand Down Expand Up @@ -2762,7 +2793,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -2942,7 +2974,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3081,7 +3114,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3125,7 +3159,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3411,7 +3446,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3455,7 +3491,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3664,7 +3701,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3710,7 +3748,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -3994,7 +4033,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4035,7 +4075,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4229,7 +4270,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4273,7 +4315,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4527,7 +4570,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4568,7 +4612,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4762,7 +4807,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_1_block_builder(
&mut epoch,
&mut builder,
Expand Down Expand Up @@ -4806,7 +4852,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;
let (stacks_block, microblocks) = miner_2_block_builder(
&mut epoch,
&mut builder,
Expand Down
1 change: 1 addition & 0 deletions src/core/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub trait MemPoolEventDispatcher {
block: &StacksBlock,
block_size_bytes: u64,
consumed: &ExecutionCost,
confirmed_microblock_cost: &ExecutionCost,
);
}

Expand Down
5 changes: 4 additions & 1 deletion src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,8 @@ pub mod test {
parent_burn_block_hash: BurnchainHeaderHash,
parent_burn_block_height: u32,
parent_burn_block_timestamp: u64,
_anchor_block_cost: &ExecutionCost,
_confirmed_mblock_cost: &ExecutionCost,
) {
self.blocks.lock().unwrap().push(TestEventObserverBlock {
block,
Expand Down Expand Up @@ -3356,7 +3358,8 @@ pub mod test {
let sort_iconn = sortdb.index_conn();
let mut epoch = builder
.epoch_begin(&mut miner_chainstate, &sort_iconn)
.unwrap();
.unwrap()
.0;

let (stacks_block, microblocks) =
mine_smart_contract_block_contract_call_microblock(
Expand Down
20 changes: 15 additions & 5 deletions testnet/stacks-node/src/event_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ pub struct MinedBlockEvent {
pub block_hash: String,
pub stacks_height: u64,
pub block_size: u64,
pub anchor_consumed: ExecutionCost,
pub anchored_cost: ExecutionCost,
pub confirmed_microblocks_cost: ExecutionCost,
}

impl EventObserver {
Expand Down Expand Up @@ -364,8 +365,8 @@ impl EventObserver {
"parent_burn_block_hash": format!("0x{}", parent_burn_block_hash),
"parent_burn_block_height": parent_burn_block_height,
"parent_burn_block_timestamp": parent_burn_block_timestamp,
"anchored_block_consumed_cost": anchored_consumed,
"microblocks_confirmed_consumed_cost": mblock_confirmed_consumed,
"anchored_cost": anchored_consumed,
"confirmed_microblocks_cost": mblock_confirmed_consumed,
});

// Send payload
Expand Down Expand Up @@ -400,8 +401,15 @@ impl MemPoolEventDispatcher for EventDispatcher {
block: &StacksBlock,
block_size_bytes: u64,
consumed: &ExecutionCost,
confirmed_microblock_cost: &ExecutionCost,
) {
self.process_mined_block_event(target_burn_height, block, block_size_bytes, consumed)
self.process_mined_block_event(
target_burn_height,
block,
block_size_bytes,
consumed,
confirmed_microblock_cost,
)
}
}

Expand Down Expand Up @@ -781,6 +789,7 @@ impl EventDispatcher {
block: &StacksBlock,
block_size_bytes: u64,
consumed: &ExecutionCost,
confirmed_microblock_cost: &ExecutionCost,
) {
let interested_observers: Vec<_> = self
.registered_observers
Expand All @@ -797,7 +806,8 @@ impl EventDispatcher {
block_hash: block.block_hash().to_string(),
stacks_height: block.header.total_work.work,
block_size: block_size_bytes,
anchor_consumed: consumed.clone(),
anchored_cost: consumed.clone(),
confirmed_microblocks_cost: confirmed_microblock_cost.clone(),
})
.unwrap();

Expand Down
Loading

0 comments on commit 9ee9101

Please sign in to comment.