Skip to content

Commit 71bb5bd

Browse files
committed
feat(block_producer): cleanup and fixes
re: #124
1 parent 8f2c83c commit 71bb5bd

19 files changed

+202
-122
lines changed

cli/src/commands/node/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use std::sync::Arc;
55
use std::time::Duration;
66

77
use mina_p2p_messages::v2::{
8-
CurrencyFeeStableV1, NonZeroCurvePoint, NonZeroCurvePointUncompressedStableV1,
9-
UnsignedExtendedUInt64Int64ForVersionTagsStableV1,
8+
CurrencyFeeStableV1, UnsignedExtendedUInt64Int64ForVersionTagsStableV1,
109
};
1110
use rand::prelude::*;
1211

core/src/block.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ impl<T: AsRef<Block>> BlockWithHash<T> {
6565
global_slot(self.header())
6666
}
6767

68+
pub fn global_slot_since_genesis(&self) -> u32 {
69+
global_slot_since_genesis(self.header())
70+
}
71+
72+
pub fn global_slot_diff(&self) -> u32 {
73+
global_slot_diff(self.header())
74+
}
75+
6876
pub fn timestamp(&self) -> Timestamp {
6977
timestamp(self.header())
7078
}
@@ -191,6 +199,14 @@ impl<T: AsRef<BlockHeader>> BlockHeaderWithHash<T> {
191199
global_slot(self.header())
192200
}
193201

202+
pub fn global_slot_since_genesis(&self) -> u32 {
203+
global_slot_since_genesis(self.header())
204+
}
205+
206+
pub fn global_slot_diff(&self) -> u32 {
207+
global_slot_diff(self.header())
208+
}
209+
194210
pub fn timestamp(&self) -> Timestamp {
195211
timestamp(self.header())
196212
}
@@ -237,12 +253,23 @@ fn height(header: &BlockHeader) -> u32 {
237253
}
238254

239255
fn global_slot(header: &BlockHeader) -> u32 {
256+
consensus_state(header).global_slot()
257+
}
258+
259+
fn global_slot_since_genesis(header: &BlockHeader) -> u32 {
240260
consensus_state(header).global_slot_since_genesis.as_u32()
241261
}
242262

263+
fn global_slot_diff(header: &BlockHeader) -> u32 {
264+
let s = consensus_state(header);
265+
s.global_slot_since_genesis
266+
.as_u32()
267+
.saturating_sub(s.global_slot())
268+
}
269+
243270
fn timestamp(header: &BlockHeader) -> Timestamp {
244271
let genesis_timestamp = constants(header).genesis_state_timestamp.0.as_u64();
245-
let slot = global_slot(header) as u64;
272+
let slot = global_slot_since_genesis(header) as u64;
246273
// FIXME: this calculation must use values from the protocol constants,
247274
// now it assumes 3 minutes blocks.
248275
let time_ms = genesis_timestamp + slot * 3 * 60 * 1000;

node/native/src/block_producer/vrf_evaluator.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ pub fn vrf_evaluator(
5454
impl node::block_producer::vrf_evaluator::BlockProducerVrfEvaluatorService for NodeService {
5555
fn evaluate(&mut self, data: VrfEvaluatorInput) {
5656
if let Some(bp) = self.block_producer.as_mut() {
57-
// TODO(adonagy): send the data to the vrf_evaluator thread
5857
let _ = bp.vrf_evaluation_sender.send(data);
5958
}
6059
}

node/src/block_producer/block_producer_actions.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub struct BlockProducerBestTipUpdateAction {
3535
}
3636

3737
impl redux::EnablingCondition<crate::State> for BlockProducerBestTipUpdateAction {
38-
fn is_enabled(&self, state: &crate::State) -> bool {
38+
fn is_enabled(&self, _state: &crate::State) -> bool {
3939
true
4040
}
4141
}
@@ -47,9 +47,16 @@ impl redux::EnablingCondition<crate::State> for BlockProducerWonSlotSearchAction
4747
fn is_enabled(&self, state: &crate::State) -> bool {
4848
state
4949
.block_producer
50-
.with(false, |this| this.current.won_slot_should_search())
51-
// TODO(adonagy): check also if we have any won slots with higher
52-
// global slot than current best tip in transition frontier.
50+
.with(None, |this| {
51+
if !this.current.won_slot_should_search() {
52+
return None;
53+
}
54+
let best_tip = state.transition_frontier.best_tip()?;
55+
let cur_global_slot = state.cur_global_slot()?;
56+
let next = this.vrf_evaluator.next_won_slot(cur_global_slot, best_tip);
57+
Some(next.is_some())
58+
})
59+
.is_some_and(|v| v)
5360
}
5461
}
5562

@@ -66,8 +73,8 @@ impl redux::EnablingCondition<crate::State> for BlockProducerWonSlotAction {
6673
};
6774

6875
this.current.won_slot_should_search()
69-
&& state.time() < self.won_slot.next_slot_time()
70-
&& self.won_slot.global_slot_since_genesis.as_u32() >= best_tip.global_slot()
76+
&& self.won_slot.global_slot() >= state.cur_global_slot().unwrap()
77+
&& &self.won_slot > best_tip
7178
})
7279
}
7380
}

node/src/block_producer/block_producer_effects.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ use super::{
1212
BlockProducerBlockProducedAction, BlockProducerBlockUnprovenBuildAction, BlockProducerService,
1313
BlockProducerStagedLedgerDiffCreateInitAction,
1414
BlockProducerStagedLedgerDiffCreatePendingAction,
15-
BlockProducerStagedLedgerDiffCreateSuccessAction, BlockProducerWonSlot,
16-
BlockProducerWonSlotAction, BlockProducerWonSlotDiscardAction,
17-
BlockProducerWonSlotProduceInitAction, BlockProducerWonSlotSearchAction,
18-
BlockProducerWonSlotWaitAction,
15+
BlockProducerStagedLedgerDiffCreateSuccessAction, BlockProducerWonSlotAction,
16+
BlockProducerWonSlotDiscardAction, BlockProducerWonSlotProduceInitAction,
17+
BlockProducerWonSlotSearchAction, BlockProducerWonSlotWaitAction,
1918
};
2019

2120
pub fn block_producer_effects<S: crate::Service>(
@@ -119,22 +118,12 @@ impl BlockProducerBestTipUpdateAction {
119118

120119
impl BlockProducerWonSlotSearchAction {
121120
pub fn effects<S: redux::Service>(self, _: &ActionMeta, store: &mut Store<S>) {
122-
let vrf_evaluator_state = store.state().block_producer.vrf_evaluator();
123-
124-
if let Some(vrf_evaluator_state) = vrf_evaluator_state {
125-
if let Some((_, won_slot)) = vrf_evaluator_state
126-
.won_slots
127-
.range(vrf_evaluator_state.current_best_tip_slot + 1..)
128-
.next()
129-
{
130-
let genesis_timestamp = vrf_evaluator_state.genesis_timestamp;
131-
store.dispatch(BlockProducerWonSlotAction {
132-
won_slot: BlockProducerWonSlot::from_vrf_won_slot(
133-
won_slot.clone(),
134-
genesis_timestamp,
135-
),
136-
});
137-
}
121+
if let Some(won_slot) = store.state().block_producer.with(None, |bp| {
122+
let best_tip = store.state().transition_frontier.best_tip()?;
123+
let cur_global_slot = store.state().cur_global_slot()?;
124+
bp.vrf_evaluator.next_won_slot(cur_global_slot, best_tip)
125+
}) {
126+
store.dispatch(BlockProducerWonSlotAction { won_slot });
138127
}
139128
}
140129
}

node/src/block_producer/block_producer_reducer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl BlockProducerEnabled {
9191
BlockProducerAction::WonSlotProduceInit(_) => {
9292
if let Some(won_slot) = self.current.won_slot() {
9393
let Some(chain) = best_chain.last().map(|best_tip| {
94-
if best_tip.global_slot() == won_slot.global_slot_since_genesis.as_u32() {
94+
if best_tip.global_slot() == won_slot.global_slot() {
9595
// We are producing block which replaces current best tip
9696
// instead of extending it.
9797
best_chain[..(best_chain.len() - 1)].to_vec()
@@ -168,7 +168,8 @@ impl BlockProducerEnabled {
168168
let block_timestamp = won_slot.timestamp();
169169
let pred_global_slot = pred_consensus_state.curr_global_slot.clone();
170170
let curr_global_slot = won_slot.global_slot.clone();
171-
let global_slot_since_genesis = won_slot.global_slot_since_genesis.clone();
171+
let global_slot_since_genesis =
172+
won_slot.global_slot_since_genesis(pred_block.global_slot_diff());
172173
let (pred_epoch, _) = to_epoch_and_slot(&pred_global_slot);
173174
let (next_epoch, next_slot) = to_epoch_and_slot(&curr_global_slot);
174175
let has_ancestor_in_same_checkpoint_window =

node/src/block_producer/block_producer_state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl BlockProducerState {
9696
pub fn new(now: redux::Timestamp, config: Option<BlockProducerConfig>) -> Self {
9797
Self(config.map(|config| BlockProducerEnabled {
9898
config: config.clone(),
99-
vrf_evaluator: BlockProducerVrfEvaluatorState::new(now, config),
99+
vrf_evaluator: BlockProducerVrfEvaluatorState::new(now),
100100
current: BlockProducerCurrentState::Idle { time: now },
101101
}))
102102
}
@@ -226,7 +226,7 @@ impl BlockProducerCurrentState {
226226
best_tip: &ArcBlockWithHash,
227227
) -> Option<BlockProducerWonSlotDiscardReason> {
228228
let won_slot = self.won_slot()?;
229-
if won_slot.global_slot_since_genesis.as_u32() < best_tip.global_slot() {
229+
if won_slot.global_slot() < best_tip.global_slot() {
230230
return Some(BlockProducerWonSlotDiscardReason::BestTipGlobalSlotHigher);
231231
}
232232

node/src/block_producer/mod.rs

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use mina_p2p_messages::{
3434
use mina_signer::CompressedPubKey;
3535
use openmina_core::block::ArcBlockWithHash;
3636
use serde::{Deserialize, Serialize};
37-
use vrf::VrfWonSlot;
3837

3938
use crate::account::AccountPublicKey;
4039

@@ -45,7 +44,6 @@ pub struct BlockProducerWonSlot {
4544
pub slot_time: redux::Timestamp,
4645
pub delegator: (NonZeroCurvePoint, AccountIndex),
4746
pub global_slot: ConsensusGlobalSlotStableV1,
48-
pub global_slot_since_genesis: MinaNumbersGlobalSlotSinceGenesisMStableV1,
4947
pub vrf_output: ConsensusVrfOutputTruncatedStableV1,
5048
// TODO(adonagy): maybe instead of passing it here, it can be
5149
// calculated on spot from `vrf_output`? Maybe with `vrf_output.blake2b()`?
@@ -56,7 +54,7 @@ pub struct BlockProducerWonSlot {
5654

5755
impl BlockProducerWonSlot {
5856
pub fn from_vrf_won_slot(
59-
won_slot_with_hash: VrfWonSlotWithHash,
57+
won_slot_with_hash: &VrfWonSlotWithHash,
6058
genesis_timestamp: redux::Timestamp,
6159
) -> Self {
6260
let VrfWonSlotWithHash {
@@ -76,19 +74,16 @@ impl BlockProducerWonSlot {
7674
),
7775
slots_per_epoch: 7140.into(), // TODO
7876
};
79-
let global_slot_since_genesis =
80-
MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(won_slot.global_slot.into());
8177

82-
let vrf_output = ConsensusVrfOutputTruncatedStableV1(won_slot.vrf_output_bytes.into());
83-
let vrf_hash = won_slot.vrf_hash;
8478
Self {
8579
slot_time,
8680
delegator,
8781
global_slot,
88-
global_slot_since_genesis,
89-
vrf_output,
90-
vrf_hash,
91-
staking_ledger_hash,
82+
vrf_output: ConsensusVrfOutputTruncatedStableV1(
83+
(&won_slot.vrf_output_bytes[..]).into(),
84+
),
85+
vrf_hash: won_slot.vrf_hash.clone(),
86+
staking_ledger_hash: staking_ledger_hash.clone(),
9287
}
9388
}
9489

@@ -98,6 +93,18 @@ impl BlockProducerWonSlot {
9893
genesis_timestamp + (slot as u64) * 3 * 60 * 1_000_000_000_u64
9994
}
10095

96+
pub fn global_slot(&self) -> u32 {
97+
self.global_slot.slot_number.as_u32()
98+
}
99+
100+
pub fn global_slot_since_genesis(
101+
&self,
102+
slot_diff: u32,
103+
) -> MinaNumbersGlobalSlotSinceGenesisMStableV1 {
104+
let slot = self.global_slot() + slot_diff;
105+
MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(slot.into())
106+
}
107+
101108
pub fn timestamp(&self) -> BlockTimeTimeStableV1 {
102109
let ms = u64::from(self.slot_time) / 1_000_000;
103110
BlockTimeTimeStableV1(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(ms.into()))
@@ -111,9 +118,8 @@ impl BlockProducerWonSlot {
111118
impl PartialOrd for BlockProducerWonSlot {
112119
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
113120
Some(
114-
self.global_slot_since_genesis
115-
.as_u32()
116-
.cmp(&other.global_slot_since_genesis.as_u32())
121+
self.global_slot()
122+
.cmp(&other.global_slot())
117123
.then_with(|| self.vrf_output.blake2b().cmp(&other.vrf_output.blake2b())),
118124
)
119125
}
@@ -128,21 +134,16 @@ impl PartialEq<ArcBlockWithHash> for BlockProducerWonSlot {
128134
impl PartialOrd<ArcBlockWithHash> for BlockProducerWonSlot {
129135
fn partial_cmp(&self, other: &ArcBlockWithHash) -> Option<std::cmp::Ordering> {
130136
// TODO(binier): this assumes short range fork
131-
Some(
132-
self.global_slot_since_genesis
133-
.as_u32()
134-
.cmp(&other.global_slot())
135-
.then_with(|| {
136-
self.vrf_output.blake2b().cmp(
137-
&other
138-
.header()
139-
.protocol_state
140-
.body
141-
.consensus_state
142-
.last_vrf_output
143-
.blake2b(),
144-
)
145-
}),
146-
)
137+
Some(self.global_slot().cmp(&other.global_slot()).then_with(|| {
138+
self.vrf_output.blake2b().cmp(
139+
&other
140+
.header()
141+
.protocol_state
142+
.body
143+
.consensus_state
144+
.last_vrf_output
145+
.blake2b(),
146+
)
147+
}))
147148
}
148149
}

node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use std::collections::BTreeMap;
21
use std::sync::Arc;
32

43
use crate::account::AccountPublicKey;
54
use crate::block_producer::{vrf_evaluator::BlockProducerVrfEvaluatorStatus, BlockProducerAction};
6-
use ledger::AccountIndex;
75
use mina_p2p_messages::v2::{
86
ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1,
97
ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, LedgerHash,

0 commit comments

Comments
 (0)