mina_node_common/service/block_producer/
vrf_evaluator.rs

1use mina_signer::Keypair;
2use node::{
3    block_producer::{
4        vrf_evaluator::{VrfEvaluationOutputWithHash, VrfEvaluatorInput},
5        BlockProducerEvent, BlockProducerVrfEvaluatorEvent,
6    },
7    core::channels::mpsc::{TrackedUnboundedReceiver, UnboundedSender},
8    event_source::Event,
9};
10use vrf::{VrfEvaluationInput, VrfEvaluationOutput};
11
12use crate::NodeService;
13
14pub fn vrf_evaluator(
15    event_sender: UnboundedSender<Event>,
16    mut vrf_evaluation_receiver: TrackedUnboundedReceiver<VrfEvaluatorInput>,
17    keypair: Keypair,
18) {
19    while let Some(vrf_evaluator_input) = vrf_evaluation_receiver.blocking_recv() {
20        // let bytes = serde_json::to_string(&vrf_evaluator_input).unwrap();
21        // mina_core::http::download("vrf.json".to_string(), bytes.as_bytes().to_vec()).unwrap();
22
23        let keypair = &keypair;
24        let VrfEvaluatorInput {
25            epoch_seed,
26            delegator_table,
27            global_slot,
28            total_currency,
29            staking_ledger_hash: _,
30        } = &*vrf_evaluator_input;
31
32        let vrf_result = delegator_table
33            .iter()
34            .find_map(|(index, (pub_key, stake))| {
35                let vrf_input = VrfEvaluationInput {
36                    producer_key: keypair.clone(),
37                    global_slot: *global_slot,
38                    epoch_seed: epoch_seed.clone(),
39                    account_pub_key: pub_key.clone(),
40                    delegator_index: *index,
41                    delegated_stake: (*stake).into(),
42                    total_currency: (*total_currency).into(),
43                };
44
45                let vrf_result = vrf::evaluate_vrf(vrf_input).unwrap();
46
47                // the first delegate that won the slot
48                if let VrfEvaluationOutput::SlotWon(_) = vrf_result {
49                    return Some(vrf_result);
50                }
51                None
52            })
53            .unwrap_or(VrfEvaluationOutput::SlotLost(*global_slot));
54
55        let vrf_result_with_hash = VrfEvaluationOutputWithHash::new(
56            vrf_result,
57            vrf_evaluator_input.staking_ledger_hash.clone(),
58        );
59
60        // send the result back to the state machine
61        let _ = event_sender.send(
62            BlockProducerEvent::VrfEvaluator(BlockProducerVrfEvaluatorEvent::Evaluated(
63                vrf_result_with_hash,
64            ))
65            .into(),
66        );
67    }
68}
69
70impl node::block_producer_effectful::vrf_evaluator_effectful::BlockProducerVrfEvaluatorService
71    for NodeService
72{
73    fn evaluate(&mut self, data: VrfEvaluatorInput) {
74        if let Some(bp) = self.block_producer.as_mut() {
75            let _ = bp.vrf_evaluation_sender.tracked_send(data);
76        }
77    }
78}