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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

// Copyright 2021 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/

//! This module defines representation of Diem core data structures at physical
//! level via schemas that implement [`schemadb::schema::Schema`].
//!
//! All schemas are `pub(crate)` so not shown in rustdoc, refer to the source
//! code to see details.

use anyhow::{ensure, Result};

use schemadb::ColumnFamilyName;

pub(crate) mod block_by_epoch_and_round;
pub(crate) mod committed_block;
pub(crate) mod committed_block_by_view;
pub(crate) mod epoch_by_version;
pub(crate) mod event;
pub(crate) mod event_accumulator;
pub(crate) mod event_by_key;
pub(crate) mod event_by_version;
pub(crate) mod jellyfish_merkle_node;
pub(crate) mod ledger_counters;
pub(crate) mod ledger_info;
pub(crate) mod ledger_info_by_block;
pub(crate) mod ledger_info_by_voted_block;
pub(crate) mod pos_state;
pub(crate) mod reward_event;
pub(crate) mod stale_node_index;
pub(crate) mod transaction;
pub(crate) mod transaction_accumulator;
pub(crate) mod transaction_by_account;
pub(crate) mod transaction_info;

pub const EPOCH_BY_VERSION_CF_NAME: ColumnFamilyName = "epoch_by_version";
pub const EVENT_ACCUMULATOR_CF_NAME: ColumnFamilyName = "event_accumulator";
pub const EVENT_BY_KEY_CF_NAME: ColumnFamilyName = "event_by_key";
pub const EVENT_BY_VERSION_CF_NAME: ColumnFamilyName = "event_by_version";
pub const EVENT_CF_NAME: ColumnFamilyName = "event";
pub const JELLYFISH_MERKLE_NODE_CF_NAME: ColumnFamilyName =
    "jellyfish_merkle_node";
pub const LEDGER_COUNTERS_CF_NAME: ColumnFamilyName = "ledger_counters";
pub const STALE_NODE_INDEX_CF_NAME: ColumnFamilyName = "stale_node_index";
pub const TRANSACTION_CF_NAME: ColumnFamilyName = "transaction";
pub const TRANSACTION_ACCUMULATOR_CF_NAME: ColumnFamilyName =
    "transaction_accumulator";
pub const TRANSACTION_BY_ACCOUNT_CF_NAME: ColumnFamilyName =
    "transaction_by_account";
pub const TRANSACTION_INFO_CF_NAME: ColumnFamilyName = "transaction_info";
pub const LEDGER_INFO_BY_BLOCK_CF_NAME: ColumnFamilyName =
    "ledger_info_by_block";
pub const POS_STATE_CF_NAME: ColumnFamilyName = "pos_state";
pub const REWARD_EVENT_CF_NAME: ColumnFamilyName = "reward_event";
pub const COMMITTED_BLOCK_CF_NAME: ColumnFamilyName = "committed_block";
pub const COMMITTED_BLOCK_BY_VIEW_CF_NAME: ColumnFamilyName =
    "committed_block_by_view";
pub const LEDGER_INFO_BY_VOTED_BLOCK_CF_NAME: ColumnFamilyName =
    "ledger_info_by_voted_block";
pub const BLOCK_BY_EPOCH_AND_ROUND_CF_NAME: ColumnFamilyName =
    "block_by_epoch_and_round";

fn ensure_slice_len_eq(data: &[u8], len: usize) -> Result<()> {
    ensure!(
        data.len() == len,
        "Unexpected data len {}, expected {}.",
        data.len(),
        len,
    );
    Ok(())
}

fn ensure_slice_len_gt(data: &[u8], len: usize) -> Result<()> {
    ensure!(
        data.len() > len,
        "Unexpected data len {}, expected to be greater than {}.",
        data.len(),
        len,
    );
    Ok(())
}

#[cfg(feature = "fuzzing")]
pub mod fuzzing {
    use schemadb::schema::{KeyCodec, Schema, ValueCodec};

    macro_rules! decode_key_value {
        ($schema_type: ty, $data: ident) => {
            <<$schema_type as Schema>::Key as KeyCodec<$schema_type>>::decode_key($data);
            <<$schema_type as Schema>::Value as ValueCodec<$schema_type>>::decode_value($data);
        };
    }

    pub fn fuzz_decode(data: &[u8]) {
        #[allow(unused_must_use)]
        {
            decode_key_value!(
                super::epoch_by_version::EpochByVersionSchema,
                data
            );
            decode_key_value!(super::event::EventSchema, data);
            decode_key_value!(
                super::event_accumulator::EventAccumulatorSchema,
                data
            );
            decode_key_value!(super::event_by_key::EventByKeySchema, data);
            decode_key_value!(
                super::event_by_version::EventByVersionSchema,
                data
            );
            decode_key_value!(
                super::jellyfish_merkle_node::JellyfishMerkleNodeSchema,
                data
            );
            decode_key_value!(
                super::ledger_counters::LedgerCountersSchema,
                data
            );
            decode_key_value!(super::ledger_info::LedgerInfoSchema, data);
            decode_key_value!(
                super::stale_node_index::StaleNodeIndexSchema,
                data
            );
            decode_key_value!(super::transaction::TransactionSchema, data);
            decode_key_value!(
                super::transaction_accumulator::TransactionAccumulatorSchema,
                data
            );
            decode_key_value!(
                super::transaction_by_account::TransactionByAccountSchema,
                data
            );
            decode_key_value!(
                super::transaction_info::TransactionInfoSchema,
                data
            );
        }
    }
}