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
use std::convert::TryInto;

use lifeline::Sender;

use crate::bridge::{Extrinsic, ToExtrinsicsMessage};
use crate::service::pangolin::types::ScanDataWrapper;

pub struct ScanScheduleAuthoritiesChangeEvent<'a> {
    data: &'a mut ScanDataWrapper,
}

impl<'a> ScanScheduleAuthoritiesChangeEvent<'a> {
    pub fn new(data: &'a mut ScanDataWrapper) -> Self {
        Self { data }
    }
}

impl<'a> ScanScheduleAuthoritiesChangeEvent<'a> {
    pub async fn handle(&mut self) -> color_eyre::Result<Option<u32>> {
        let events = self
            .data
            .subquery
            .query_schedule_authorities_change_event(self.data.from, self.data.limit)
            .await?;

        tracing::debug!(
            target: "pangolin-ropsten",
            "[pangolin] [schedule-authorities-change] Track pangolin ScheduleAuthoritiesChangeEvent block: {} and limit: {}",
            self.data.from,
            self.data.limit
        );
        if events.is_empty() {
            tracing::info!(
                target: "pangolin-ropsten",
                "[pangolin] [schedule-authorities-change] Not have more ScheduleAuthoritiesChangeEvent"
            );
            return Ok(None);
        }
        for event in &events {
            let block_number = Some(event.at_block_number);
            let message = event.message.as_slice().try_into()?;
            let client = &self.data.pangolin;
            let real_account = client.account().real_account();
            let need_to_sign = client
                .ethereum()
                .is_authority(block_number, real_account)
                .await?
                && client
                    .ethereum()
                    .need_to_sign_authorities(block_number, real_account, message)
                    .await?;

            if !need_to_sign {
                tracing::trace!(
                    target: "pangolin-ropsten",
                    "[pangolin] [schedule-authorities-change] The ScheduleAuthoritiesChangeEvent message: {} don't need to sign and send it at block: {}",
                    array_bytes::bytes2hex("0x", message.as_ref()),
                    event.at_block_number
                );
                continue;
            }

            tracing::info!(
                target: "pangolin-ropsten",
                "[pangolin] [schedule-authorities-change] Try sign and send authorities with message: {} at block: {}",
                array_bytes::bytes2hex("0x", message.as_ref()),
                event.at_block_number
            );
            let ex = Extrinsic::SignAndSendAuthorities(message);
            let sender = self.data.sender_to_extrinsics_mut();
            sender.send(ToExtrinsicsMessage::Extrinsic(ex)).await?;
        }
        let latest = events.last().unwrap();
        Ok(Some(latest.at_block_number))
    }
}