Skip to content

Commit d598a5a

Browse files
adonagybinier
authored andcommitted
Connect vrf and block producer (#184)
* WIP: connect vrf and block producer * Add slot time calculation for won slot * chore: cargo fmt
1 parent 1039e22 commit d598a5a

File tree

15 files changed

+217
-74
lines changed

15 files changed

+217
-74
lines changed

Cargo.lock

Lines changed: 52 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/block.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ impl<T: AsRef<Block>> BlockWithHash<T> {
6969
timestamp(self.header())
7070
}
7171

72+
pub fn genesis_timestamp(&self) -> Timestamp {
73+
genesis_timestamp(self.header())
74+
}
75+
7276
pub fn constants(&self) -> &MinaBaseProtocolConstantsCheckedValueStableV1 {
7377
constants(self.header())
7478
}
@@ -191,6 +195,10 @@ impl<T: AsRef<BlockHeader>> BlockHeaderWithHash<T> {
191195
timestamp(self.header())
192196
}
193197

198+
pub fn genesis_timestamp(&self) -> Timestamp {
199+
genesis_timestamp(self.header())
200+
}
201+
194202
pub fn constants(&self) -> &MinaBaseProtocolConstantsCheckedValueStableV1 {
195203
constants(self.header())
196204
}
@@ -241,6 +249,11 @@ fn timestamp(header: &BlockHeader) -> Timestamp {
241249
Timestamp::new(time_ms * 1_000_000)
242250
}
243251

252+
fn genesis_timestamp(header: &BlockHeader) -> Timestamp {
253+
let genesis_timestamp = constants(header).genesis_state_timestamp.0.as_u64();
254+
Timestamp::new(genesis_timestamp * 1_000_000)
255+
}
256+
244257
fn constants(header: &BlockHeader) -> &MinaBaseProtocolConstantsCheckedValueStableV1 {
245258
&header.protocol_state.body.constants
246259
}

node/native/src/block_producer/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
mod vrf_evaluator;
22

33
use mina_signer::Keypair;
4-
use node::core::channels::mpsc;
4+
use node::{core::channels::mpsc, block_producer::vrf_evaluator::VrfEvaluatorInput};
55

66
use crate::NodeService;
77

8-
use vrf::VrfEvaluatorInput;
9-
108
pub struct BlockProducerService {
119
vrf_evaluation_sender: mpsc::UnboundedSender<VrfEvaluatorInput>,
1210
}

node/native/src/block_producer/vrf_evaluator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use mina_signer::Keypair;
2-
use node::{block_producer::BlockProducerEvent, event_source::Event};
2+
use node::{block_producer::{BlockProducerEvent, vrf_evaluator::VrfEvaluatorInput}, event_source::Event};
33
use openmina_core::channels::mpsc::{UnboundedReceiver, UnboundedSender};
4-
use vrf::{VrfEvaluationInput, VrfEvaluationOutput, VrfEvaluatorInput};
4+
use vrf::{VrfEvaluationInput, VrfEvaluationOutput};
55

66
use crate::NodeService;
77
use node::block_producer::BlockProducerVrfEvaluatorEvent;
@@ -26,9 +26,9 @@ pub fn vrf_evaluator(
2626
let vrf_input = VrfEvaluationInput::new(
2727
keypair.clone(),
2828
vrf_evaluator_input.epoch_seed.clone(),
29-
account.0.clone(),
29+
account.0.to_string(),
3030
vrf_evaluator_input.global_slot,
31-
index.as_u64(),
31+
index.clone(),
3232
account.1.into(),
3333
vrf_evaluator_input.total_currency.into(),
3434
);

node/src/block_producer/block_producer_effects.rs

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

2021
pub fn block_producer_effects<S: crate::Service>(
@@ -120,11 +121,23 @@ impl BlockProducerBestTipUpdateAction {
120121

121122
impl BlockProducerWonSlotSearchAction {
122123
pub fn effects<S: redux::Service>(self, _: &ActionMeta, store: &mut Store<S>) {
123-
// TODO(adonagy): find next slot in `won_slots`, for which global
124-
// slot is higher then current best tip. It can be in the future,
125-
// doesn't have to be next slot.
126-
//
127-
// store.dispatch(BlockProducerWonSlotAction { won_slot });
124+
let vrf_evaluator_state = store.state().block_producer.vrf_evaluator();
125+
126+
if let Some(vrf_evaluator_state) = vrf_evaluator_state {
127+
if let Some((_, won_slot)) = vrf_evaluator_state
128+
.won_slots
129+
.range(vrf_evaluator_state.current_best_tip_slot + 1..)
130+
.next()
131+
{
132+
let genesis_timestamp = vrf_evaluator_state.genesis_timestamp;
133+
store.dispatch(BlockProducerWonSlotAction {
134+
won_slot: BlockProducerWonSlot::from_vrf_won_slot(
135+
won_slot.clone(),
136+
genesis_timestamp,
137+
),
138+
});
139+
}
140+
}
128141
}
129142
}
130143

node/src/block_producer/block_producer_reducer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ impl BlockProducerEnabled {
5757
.curr_global_slot
5858
.slot_number
5959
.as_u32();
60+
61+
// set the genesis timestamp on the first best tip update
62+
// TODO: move/remove once we can generate the genesis block
63+
if self.vrf_evaluator.genesis_timestamp == redux::Timestamp::ZERO {
64+
self.vrf_evaluator.genesis_timestamp = action.best_tip.genesis_timestamp();
65+
}
6066
}
6167
BlockProducerAction::WonSlotSearch(_) => {}
6268
BlockProducerAction::WonSlot(action) => {

node/src/block_producer/mod.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,17 @@ use mina_p2p_messages::{
2626
bigint::BigInt,
2727
v2::{
2828
BlockTimeTimeStableV1, ConsensusGlobalSlotStableV1, ConsensusVrfOutputTruncatedStableV1,
29-
LedgerHash, MinaNumbersGlobalSlotSinceGenesisMStableV1, NonZeroCurvePoint,
29+
LedgerHash, MinaNumbersGlobalSlotSinceGenesisMStableV1,
30+
MinaNumbersGlobalSlotSinceHardForkMStableV1, NonZeroCurvePoint,
3031
UnsignedExtendedUInt64Int64ForVersionTagsStableV1,
3132
},
3233
};
34+
use mina_signer::CompressedPubKey;
3335
use openmina_core::block::ArcBlockWithHash;
3436
use serde::{Deserialize, Serialize};
37+
use vrf::VrfWonSlot;
38+
39+
use crate::account::AccountPublicKey;
3540

3641
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
3742
pub struct BlockProducerWonSlot {
@@ -43,11 +48,45 @@ pub struct BlockProducerWonSlot {
4348
// TODO(adonagy): maybe instead of passing it here, it can be
4449
// calculated on spot from `vrf_output`? Maybe with `vrf_output.blake2b()`?
4550
pub vrf_hash: BigInt,
46-
/// Staking ledger which was used during vrf evaluation.
47-
pub staking_ledger_hash: LedgerHash,
51+
// Staking ledger which was used during vrf evaluation.
52+
// pub staking_ledger_hash: LedgerHash,
4853
}
4954

5055
impl BlockProducerWonSlot {
56+
pub fn from_vrf_won_slot(won_slot: VrfWonSlot, genesis_timestamp: redux::Timestamp) -> Self {
57+
let slot_time = Self::calculate_slot_time(genesis_timestamp, won_slot.global_slot);
58+
59+
let winner_pub_key = AccountPublicKey::from(
60+
CompressedPubKey::from_address(&won_slot.winner_account).unwrap(),
61+
);
62+
let delegator = (winner_pub_key.into(), won_slot.account_index.clone());
63+
let global_slot = ConsensusGlobalSlotStableV1 {
64+
slot_number: MinaNumbersGlobalSlotSinceHardForkMStableV1::SinceHardFork(
65+
won_slot.global_slot.into(),
66+
),
67+
slots_per_epoch: 7140.into(), // TODO
68+
};
69+
let global_slot_since_genesis =
70+
MinaNumbersGlobalSlotSinceGenesisMStableV1::SinceGenesis(won_slot.global_slot.into());
71+
72+
let vrf_output = ConsensusVrfOutputTruncatedStableV1(won_slot.vrf_output_bytes.into());
73+
let vrf_hash = won_slot.vrf_hash;
74+
Self {
75+
slot_time,
76+
delegator,
77+
global_slot,
78+
global_slot_since_genesis,
79+
vrf_output,
80+
vrf_hash,
81+
}
82+
}
83+
84+
fn calculate_slot_time(genesis_timestamp: redux::Timestamp, slot: u32) -> redux::Timestamp {
85+
// FIXME: this calculation must use values from the protocol constants,
86+
// now it assumes 3 minutes blocks.
87+
genesis_timestamp + (slot as u64) * 3 * 60 * 1_000_000_000_u64
88+
}
89+
5190
pub fn timestamp(&self) -> BlockTimeTimeStableV1 {
5291
let ms = u64::from(self.slot_time) / 1_000_000;
5392
BlockTimeTimeStableV1(UnsignedExtendedUInt64Int64ForVersionTagsStableV1(ms.into()))

0 commit comments

Comments
 (0)