diem_types/
block_metadata.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use crate::{
9    account_address::AccountAddress,
10    account_config::diem_root_address,
11    event::{EventHandle, EventKey},
12};
13use diem_crypto::HashValue;
14use move_core_types::move_resource::MoveResource;
15use once_cell::sync::Lazy;
16use serde::{Deserialize, Serialize};
17
18/// Struct that will be persisted on chain to store the information of the
19/// current block.
20///
21/// The flow will look like following:
22/// 1. The executor will pass this struct to VM at the end of a block proposal.
23/// 2. The VM will use this struct to create a special system transaction that
24/// will emit an event    represents the information of the current block. This
25/// transaction can't    be emitted by regular users and is generated by each of
26/// the validators on the fly. Such    transaction will be executed before all
27/// of the user-submitted transactions in the blocks. 3. Once that special
28/// resource is modified, the other user transactions can read the consensus
29///    info by calling into the read method of that resource, which would thus
30/// give users the    information such as the current leader.
31#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
32pub struct BlockMetadata {
33    id: HashValue,
34    round: u64,
35    timestamp_usecs: u64,
36    // The vector has to be sorted to ensure consistent result among all nodes
37    previous_block_votes: Vec<AccountAddress>,
38    proposer: AccountAddress,
39}
40
41impl BlockMetadata {
42    pub fn new(
43        id: HashValue, round: u64, timestamp_usecs: u64,
44        previous_block_votes: Vec<AccountAddress>, proposer: AccountAddress,
45    ) -> Self {
46        Self {
47            id,
48            round,
49            timestamp_usecs,
50            previous_block_votes,
51            proposer,
52        }
53    }
54
55    pub fn id(&self) -> HashValue { self.id }
56
57    pub fn into_inner(self) -> (u64, u64, Vec<AccountAddress>, AccountAddress) {
58        (
59            self.round,
60            self.timestamp_usecs,
61            self.previous_block_votes.clone(),
62            self.proposer,
63        )
64    }
65
66    pub fn timestamp_usec(&self) -> u64 { self.timestamp_usecs }
67
68    pub fn proposer(&self) -> AccountAddress { self.proposer }
69}
70
71pub fn new_block_event_key() -> EventKey {
72    EventKey::new_from_address(&diem_root_address(), 17)
73}
74
75/// The path to the new block event handle under a DiemBlock::BlockMetadata
76/// resource.
77pub static NEW_BLOCK_EVENT_PATH: Lazy<Vec<u8>> = Lazy::new(|| {
78    let mut path = DiemBlockResource::resource_path();
79    // it can be anything as long as it's referenced in
80    // AccountState::get_event_handle_by_query_path
81    path.extend_from_slice(b"/new_block_event/");
82    path
83});
84
85#[derive(Deserialize, Serialize)]
86pub struct DiemBlockResource {
87    height: u64,
88    new_block_events: EventHandle,
89}
90
91impl DiemBlockResource {
92    pub fn new_block_events(&self) -> &EventHandle { &self.new_block_events }
93}
94
95impl MoveResource for DiemBlockResource {
96    const MODULE_NAME: &'static str = "DiemBlock";
97    const STRUCT_NAME: &'static str = "BlockMetadata";
98}
99
100#[derive(Clone, Deserialize, Serialize)]
101pub struct NewBlockEvent {
102    round: u64,
103    proposer: AccountAddress,
104    votes: Vec<AccountAddress>,
105    timestamp: u64,
106}
107
108impl NewBlockEvent {
109    pub fn new(
110        round: u64, proposer: AccountAddress, votes: Vec<AccountAddress>,
111        timestamp: u64,
112    ) -> Self {
113        Self {
114            round,
115            proposer,
116            votes,
117            timestamp,
118        }
119    }
120
121    pub fn round(&self) -> u64 { self.round }
122
123    pub fn proposer(&self) -> AccountAddress { self.proposer }
124
125    pub fn votes(&self) -> Vec<AccountAddress> { self.votes.clone() }
126}