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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
pub(crate) const DEFERRED_CALL_TOTAL_GAS: &str = "deferred_call_total_gas";

pub(crate) const DEFERRED_CALL_TOTAL_REGISTERED: &str = "deferred_call_total_registered";

pub(crate) const CALLS_TAG: u8 = 0u8;
// slot fields
pub(crate) const SLOT_TOTAL_GAS: u8 = 1u8;
pub(crate) const SLOT_BASE_FEE: u8 = 2u8;

// call fields
pub(crate) const CALL_FIELD_SENDER_ADDRESS: u8 = 1u8;
pub(crate) const CALL_FIELD_TARGET_SLOT: u8 = 2u8;
pub(crate) const CALL_FIELD_TARGET_ADDRESS: u8 = 3u8;
pub(crate) const CALL_FIELD_TARGET_FUNCTION: u8 = 4u8;
pub(crate) const CALL_FIELD_PARAMETERS: u8 = 5u8;
pub(crate) const CALL_FIELD_COINS: u8 = 6u8;
pub(crate) const CALL_FIELD_MAX_GAS: u8 = 7u8;
pub(crate) const CALL_FIELD_FEE: u8 = 8u8;
pub(crate) const CALL_FIELD_CANCELED: u8 = 9u8;

#[macro_export]
macro_rules! deferred_call_slot_total_gas_key {
    ($slot:expr) => {
        [
            DEFERRED_CALLS_PREFIX.as_bytes(),
            &$slot[..],
            &[$crate::macros::SLOT_TOTAL_GAS],
        ]
        .concat()
    };
}

#[macro_export]
macro_rules! deferred_call_slot_base_fee_key {
    ($slot:expr) => {
        [
            DEFERRED_CALLS_PREFIX.as_bytes(),
            &$slot[..],
            &[$crate::macros::SLOT_BASE_FEE],
        ]
        .concat()
    };
}

#[macro_export]
macro_rules! deferred_slot_call_prefix_key {
    ($slot:expr) => {
        [
            DEFERRED_CALLS_PREFIX.as_bytes(),
            &$slot[..],
            &[$crate::macros::CALLS_TAG],
        ]
        .concat()
    };
}

#[macro_export]
macro_rules! deferred_call_prefix_key {
    ($id:expr, $slot:expr) => {
        [&deferred_slot_call_prefix_key!($slot), &$id[..]].concat()
    };
}

/// key formatting macro
#[macro_export]
macro_rules! deferred_call_field_key {
    ($id:expr, $slot:expr, $field:expr) => {
        [deferred_call_prefix_key!($id, $slot), vec![$field]].concat()
    };
}

/// sender address key formatting macro
#[macro_export]
macro_rules! sender_address_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_SENDER_ADDRESS)
    };
}

/// target slot key formatting macro
#[macro_export]
macro_rules! target_slot_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_TARGET_SLOT)
    };
}

/// target address key formatting macro
#[macro_export]
macro_rules! target_address_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_TARGET_ADDRESS)
    };
}

/// target function key formatting macro
#[macro_export]
macro_rules! target_function_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_TARGET_FUNCTION)
    };
}

/// parameters key formatting macro
#[macro_export]
macro_rules! parameters_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_PARAMETERS)
    };
}

/// coins key formatting macro
#[macro_export]
macro_rules! coins_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_COINS)
    };
}

/// max gas key formatting macro
#[macro_export]
macro_rules! max_gas_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_MAX_GAS)
    };
}

/// fee key formatting macro
#[macro_export]
macro_rules! fee_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_FEE)
    };
}

/// cancelled key formatting macro
#[macro_export]
macro_rules! cancelled_key {
    ($id:expr, $slot:expr) => {
        deferred_call_field_key!($id, $slot, $crate::macros::CALL_FIELD_CANCELED)
    };
}

#[cfg(test)]
mod tests {
    use massa_db_exports::DEFERRED_CALLS_PREFIX;
    use massa_models::{
        deferred_calls::{DeferredCallId, DeferredCallIdSerializer},
        slot::Slot,
    };
    use massa_serialization::Serializer;

    #[test]
    fn test_deferred_call_prefix_key() {
        let slot_ser = Slot {
            period: 1,
            thread: 5,
        }
        .to_bytes_key();

        let id = DeferredCallId::new(
            0,
            Slot {
                thread: 5,
                period: 1,
            },
            1,
            &[],
        )
        .unwrap();

        let id_ser = DeferredCallIdSerializer::new();
        let mut buf_id = Vec::new();
        id_ser.serialize(&id, &mut buf_id).unwrap();

        let prefix = ["deferred_calls/".as_bytes(), &slot_ser, &[0u8], &buf_id].concat();

        assert_eq!(deferred_call_prefix_key!(buf_id, slot_ser), prefix);

        // let to_check = [prefix[..], &[1u8]].concat();
        // assert_eq!(sender_address_key!(buf_id, slot_ser), to_check);
    }
}