1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::sync::Arc;

use async_trait::async_trait;
use crossbeam::channel;
use tokio::sync::oneshot;

use crate::{
    consensus::{
        beacon::EpochTime,
        roothash::Header,
        state::ConsensusState,
        tendermint::decode_light_block,
        verifier::{self, Error},
        Event, LightBlock,
    },
    protocol::Protocol,
    types::EventKind,
};

use super::types::Command;

pub struct Handle {
    pub protocol: Arc<Protocol>,
    pub command_sender: channel::Sender<Command>,
}

#[async_trait]
impl verifier::Verifier for Handle {
    async fn sync(&self, height: u64) -> Result<(), Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::Synchronize(height, sender))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn verify(
        &self,
        consensus_block: LightBlock,
        runtime_header: Header,
        epoch: EpochTime,
    ) -> Result<ConsensusState, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::Verify(
                consensus_block,
                runtime_header,
                epoch,
                sender,
                false,
            ))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn verify_for_query(
        &self,
        consensus_block: LightBlock,
        runtime_header: Header,
        epoch: EpochTime,
    ) -> Result<ConsensusState, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::Verify(
                consensus_block,
                runtime_header,
                epoch,
                sender,
                true,
            ))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn unverified_state(&self, consensus_block: LightBlock) -> Result<ConsensusState, Error> {
        let untrusted_block =
            decode_light_block(consensus_block).map_err(Error::VerificationFailed)?;
        // NOTE: No actual verification is performed.
        let state_root = untrusted_block.get_state_root();
        Ok(ConsensusState::from_protocol(
            self.protocol.clone(),
            state_root.version + 1,
            state_root,
        ))
    }

    async fn latest_state(&self) -> Result<ConsensusState, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::LatestState(sender))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn state_at(&self, height: u64) -> Result<ConsensusState, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::StateAt(height, sender))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn events_at(&self, height: u64, kind: EventKind) -> Result<Vec<Event>, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::EventsAt(height, kind, sender))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }

    async fn latest_height(&self) -> Result<u64, Error> {
        let (sender, receiver) = oneshot::channel();
        self.command_sender
            .send(Command::LatestHeight(sender))
            .map_err(|_| Error::Internal)?;

        receiver.await.map_err(|_| Error::Internal)?
    }
}