casper-binary-port 1.1.1

Types for the casper node binary port
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
//! The payload type.

use core::{convert::TryFrom, fmt};

#[cfg(test)]
use rand::Rng;

#[cfg(test)]
use casper_types::testing::TestRng;
use casper_types::{
    contracts::ContractPackage,
    execution::{ExecutionResult, ExecutionResultV1},
    AvailableBlockRange, BlockBody, BlockBodyV1, BlockHeader, BlockHeaderV1, BlockSignatures,
    BlockSignaturesV1, BlockSynchronizerStatus, BlockWithSignatures, ChainspecRawBytes, Deploy,
    NextUpgrade, Package, Peers, ProtocolVersion, StoredValue, Transaction, Transfer,
};

use crate::{
    global_state_query_result::GlobalStateQueryResult,
    node_status::NodeStatus,
    speculative_execution_result::SpeculativeExecutionResult,
    type_wrappers::{
        ConsensusStatus, ConsensusValidatorChanges, GetTrieFullResult, LastProgress, NetworkName,
        ReactorStateName, RewardResponse,
    },
    AccountInformation, AddressableEntityInformation, BalanceResponse, ContractInformation,
    DictionaryQueryResult, RecordId, TransactionWithExecutionInfo, Uptime, ValueWithProof,
};

/// A type of the payload being returned in a binary response.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum ResponseType {
    /// Legacy version of the block header.
    BlockHeaderV1,
    /// Block header.
    BlockHeader,
    /// Legacy version of the block body.
    BlockBodyV1,
    /// Block body.
    BlockBody,
    /// Legacy version of the approvals hashes.
    ApprovalsHashesV1,
    /// Approvals hashes
    ApprovalsHashes,
    /// Legacy version of the block signatures.
    BlockSignaturesV1,
    /// Block signatures.
    BlockSignatures,
    /// Deploy.
    Deploy,
    /// Transaction.
    Transaction,
    /// Legacy version of the execution result.
    ExecutionResultV1,
    /// Execution result.
    ExecutionResult,
    /// Wasm V1 execution result.
    WasmV1Result,
    /// Transfers.
    Transfers,
    /// Finalized deploy approvals.
    FinalizedDeployApprovals,
    /// Finalized approvals.
    FinalizedApprovals,
    /// Block with signatures.
    BlockWithSignatures,
    /// Transaction with approvals and execution info.
    TransactionWithExecutionInfo,
    /// Peers.
    Peers,
    /// Last progress.
    LastProgress,
    /// State of the reactor.
    ReactorState,
    /// Network name.
    NetworkName,
    /// Consensus validator changes.
    ConsensusValidatorChanges, // return type in `effects.rs` will be turned into dedicated type.
    /// Status of the block synchronizer.
    BlockSynchronizerStatus,
    /// Available block range.
    AvailableBlockRange,
    /// Information about the next network upgrade.
    NextUpgrade,
    /// Consensus status.
    ConsensusStatus, // return type in `effects.rs` will be turned into dedicated type.
    /// Chainspec represented as raw bytes.
    ChainspecRawBytes,
    /// Uptime.
    Uptime,
    /// Result of checking if given block is in the highest available block range.
    HighestBlockSequenceCheckResult,
    /// Result of the speculative execution,
    SpeculativeExecutionResult,
    /// Result of querying global state,
    GlobalStateQueryResult,
    /// Result of querying global state for all values under a specified key.
    StoredValues,
    /// Result of querying global state for a full trie.
    GetTrieFullResult,
    /// Node status.
    NodeStatus,
    /// Result of querying for a dictionary item.
    DictionaryQueryResult,
    /// Balance query response.
    BalanceResponse,
    /// Reward response.
    Reward,
    /// Protocol version.
    ProtocolVersion,
    /// Contract package with Merkle proof.
    ContractPackageWithProof,
    /// Contract information.
    ContractInformation,
    /// Account information.
    AccountInformation,
    /// Package with Merkle proof.
    PackageWithProof,
    /// Addressable entity information.
    AddressableEntityInformation,
}

impl ResponseType {
    pub fn from_record_id(record_id: RecordId, is_legacy: bool) -> Self {
        match (is_legacy, record_id) {
            (true, RecordId::BlockHeader) => Self::BlockHeaderV1,
            (true, RecordId::BlockBody) => Self::BlockBodyV1,
            (true, RecordId::ApprovalsHashes) => Self::ApprovalsHashesV1,
            (true, RecordId::BlockMetadata) => Self::BlockSignaturesV1,
            (true, RecordId::Transaction) => Self::Deploy,
            (true, RecordId::ExecutionResult) => Self::ExecutionResultV1,
            (true, RecordId::Transfer) => Self::Transfers,
            (true, RecordId::FinalizedTransactionApprovals) => Self::FinalizedDeployApprovals,
            (false, RecordId::BlockHeader) => Self::BlockHeader,
            (false, RecordId::BlockBody) => Self::BlockBody,
            (false, RecordId::ApprovalsHashes) => Self::ApprovalsHashes,
            (false, RecordId::BlockMetadata) => Self::BlockSignatures,
            (false, RecordId::Transaction) => Self::Transaction,
            (false, RecordId::ExecutionResult) => Self::ExecutionResult,
            (false, RecordId::Transfer) => Self::Transfers,
            (false, RecordId::FinalizedTransactionApprovals) => Self::FinalizedApprovals,
        }
    }

    #[cfg(test)]
    pub(crate) fn random(rng: &mut TestRng) -> Self {
        Self::try_from(rng.gen_range(0..44)).unwrap()
    }
}

impl TryFrom<u8> for ResponseType {
    type Error = ();

    fn try_from(v: u8) -> Result<Self, Self::Error> {
        match v {
            x if x == ResponseType::BlockHeaderV1 as u8 => Ok(ResponseType::BlockHeaderV1),
            x if x == ResponseType::BlockHeader as u8 => Ok(ResponseType::BlockHeader),
            x if x == ResponseType::BlockBodyV1 as u8 => Ok(ResponseType::BlockBodyV1),
            x if x == ResponseType::BlockBody as u8 => Ok(ResponseType::BlockBody),
            x if x == ResponseType::ApprovalsHashesV1 as u8 => Ok(ResponseType::ApprovalsHashesV1),
            x if x == ResponseType::ApprovalsHashes as u8 => Ok(ResponseType::ApprovalsHashes),
            x if x == ResponseType::BlockSignaturesV1 as u8 => Ok(ResponseType::BlockSignaturesV1),
            x if x == ResponseType::BlockSignatures as u8 => Ok(ResponseType::BlockSignatures),
            x if x == ResponseType::Deploy as u8 => Ok(ResponseType::Deploy),
            x if x == ResponseType::Transaction as u8 => Ok(ResponseType::Transaction),
            x if x == ResponseType::ExecutionResultV1 as u8 => Ok(ResponseType::ExecutionResultV1),
            x if x == ResponseType::ExecutionResult as u8 => Ok(ResponseType::ExecutionResult),
            x if x == ResponseType::Transfers as u8 => Ok(ResponseType::Transfers),
            x if x == ResponseType::FinalizedDeployApprovals as u8 => {
                Ok(ResponseType::FinalizedDeployApprovals)
            }
            x if x == ResponseType::FinalizedApprovals as u8 => {
                Ok(ResponseType::FinalizedApprovals)
            }
            x if x == ResponseType::BlockWithSignatures as u8 => {
                Ok(ResponseType::BlockWithSignatures)
            }
            x if x == ResponseType::TransactionWithExecutionInfo as u8 => {
                Ok(ResponseType::TransactionWithExecutionInfo)
            }
            x if x == ResponseType::Peers as u8 => Ok(ResponseType::Peers),
            x if x == ResponseType::Uptime as u8 => Ok(ResponseType::Uptime),
            x if x == ResponseType::LastProgress as u8 => Ok(ResponseType::LastProgress),
            x if x == ResponseType::ReactorState as u8 => Ok(ResponseType::ReactorState),
            x if x == ResponseType::NetworkName as u8 => Ok(ResponseType::NetworkName),
            x if x == ResponseType::ConsensusValidatorChanges as u8 => {
                Ok(ResponseType::ConsensusValidatorChanges)
            }
            x if x == ResponseType::BlockSynchronizerStatus as u8 => {
                Ok(ResponseType::BlockSynchronizerStatus)
            }
            x if x == ResponseType::AvailableBlockRange as u8 => {
                Ok(ResponseType::AvailableBlockRange)
            }
            x if x == ResponseType::NextUpgrade as u8 => Ok(ResponseType::NextUpgrade),
            x if x == ResponseType::ConsensusStatus as u8 => Ok(ResponseType::ConsensusStatus),
            x if x == ResponseType::ChainspecRawBytes as u8 => Ok(ResponseType::ChainspecRawBytes),
            x if x == ResponseType::HighestBlockSequenceCheckResult as u8 => {
                Ok(ResponseType::HighestBlockSequenceCheckResult)
            }
            x if x == ResponseType::SpeculativeExecutionResult as u8 => {
                Ok(ResponseType::SpeculativeExecutionResult)
            }
            x if x == ResponseType::GlobalStateQueryResult as u8 => {
                Ok(ResponseType::GlobalStateQueryResult)
            }
            x if x == ResponseType::StoredValues as u8 => Ok(ResponseType::StoredValues),
            x if x == ResponseType::GetTrieFullResult as u8 => Ok(ResponseType::GetTrieFullResult),
            x if x == ResponseType::NodeStatus as u8 => Ok(ResponseType::NodeStatus),
            x if x == ResponseType::DictionaryQueryResult as u8 => {
                Ok(ResponseType::DictionaryQueryResult)
            }
            x if x == ResponseType::WasmV1Result as u8 => Ok(ResponseType::WasmV1Result),
            x if x == ResponseType::BalanceResponse as u8 => Ok(ResponseType::BalanceResponse),
            x if x == ResponseType::Reward as u8 => Ok(ResponseType::Reward),
            x if x == ResponseType::ProtocolVersion as u8 => Ok(ResponseType::ProtocolVersion),
            x if x == ResponseType::ContractPackageWithProof as u8 => {
                Ok(ResponseType::ContractPackageWithProof)
            }
            x if x == ResponseType::ContractInformation as u8 => {
                Ok(ResponseType::ContractInformation)
            }
            x if x == ResponseType::AccountInformation as u8 => {
                Ok(ResponseType::AccountInformation)
            }
            x if x == ResponseType::PackageWithProof as u8 => Ok(ResponseType::PackageWithProof),
            x if x == ResponseType::AddressableEntityInformation as u8 => {
                Ok(ResponseType::AddressableEntityInformation)
            }
            _ => Err(()),
        }
    }
}

impl From<ResponseType> for u8 {
    fn from(value: ResponseType) -> Self {
        value as u8
    }
}

impl fmt::Display for ResponseType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ResponseType::BlockHeaderV1 => write!(f, "BlockHeaderV1"),
            ResponseType::BlockHeader => write!(f, "BlockHeader"),
            ResponseType::BlockBodyV1 => write!(f, "BlockBodyV1"),
            ResponseType::BlockBody => write!(f, "BlockBody"),
            ResponseType::ApprovalsHashesV1 => write!(f, "ApprovalsHashesV1"),
            ResponseType::ApprovalsHashes => write!(f, "ApprovalsHashes"),
            ResponseType::BlockSignaturesV1 => write!(f, "BlockSignaturesV1"),
            ResponseType::BlockSignatures => write!(f, "BlockSignatures"),
            ResponseType::Deploy => write!(f, "Deploy"),
            ResponseType::Transaction => write!(f, "Transaction"),
            ResponseType::ExecutionResultV1 => write!(f, "ExecutionResultV1"),
            ResponseType::ExecutionResult => write!(f, "ExecutionResult"),
            ResponseType::Transfers => write!(f, "Transfers"),
            ResponseType::FinalizedDeployApprovals => write!(f, "FinalizedDeployApprovals"),
            ResponseType::FinalizedApprovals => write!(f, "FinalizedApprovals"),
            ResponseType::BlockWithSignatures => write!(f, "BlockWithSignatures"),
            ResponseType::TransactionWithExecutionInfo => write!(f, "TransactionWithExecutionInfo"),
            ResponseType::Peers => write!(f, "Peers"),
            ResponseType::LastProgress => write!(f, "LastProgress"),
            ResponseType::ReactorState => write!(f, "ReactorState"),
            ResponseType::NetworkName => write!(f, "NetworkName"),
            ResponseType::ConsensusValidatorChanges => write!(f, "ConsensusValidatorChanges"),
            ResponseType::BlockSynchronizerStatus => write!(f, "BlockSynchronizerStatus"),
            ResponseType::AvailableBlockRange => write!(f, "AvailableBlockRange"),
            ResponseType::NextUpgrade => write!(f, "NextUpgrade"),
            ResponseType::ConsensusStatus => write!(f, "ConsensusStatus"),
            ResponseType::ChainspecRawBytes => write!(f, "ChainspecRawBytes"),
            ResponseType::Uptime => write!(f, "Uptime"),
            ResponseType::HighestBlockSequenceCheckResult => {
                write!(f, "HighestBlockSequenceCheckResult")
            }
            ResponseType::SpeculativeExecutionResult => write!(f, "SpeculativeExecutionResult"),
            ResponseType::GlobalStateQueryResult => write!(f, "GlobalStateQueryResult"),
            ResponseType::StoredValues => write!(f, "StoredValues"),
            ResponseType::GetTrieFullResult => write!(f, "GetTrieFullResult"),
            ResponseType::NodeStatus => write!(f, "NodeStatus"),
            ResponseType::WasmV1Result => write!(f, "WasmV1Result"),
            ResponseType::DictionaryQueryResult => write!(f, "DictionaryQueryResult"),
            ResponseType::BalanceResponse => write!(f, "BalanceResponse"),
            ResponseType::Reward => write!(f, "Reward"),
            ResponseType::ProtocolVersion => write!(f, "ProtocolVersion"),
            ResponseType::ContractPackageWithProof => write!(f, "ContractPackageWithProof"),
            ResponseType::ContractInformation => write!(f, "ContractInformation"),
            ResponseType::AccountInformation => write!(f, "AccountInformation"),
            ResponseType::PackageWithProof => write!(f, "PackageWithProof"),
            ResponseType::AddressableEntityInformation => {
                write!(f, "AddressableEntityInformation")
            }
        }
    }
}

/// Represents an entity that can be sent as a payload.
pub trait PayloadEntity {
    /// Returns the payload type of the entity.
    const RESPONSE_TYPE: ResponseType;
}

impl PayloadEntity for Transaction {
    const RESPONSE_TYPE: ResponseType = ResponseType::Transaction;
}

impl PayloadEntity for Deploy {
    const RESPONSE_TYPE: ResponseType = ResponseType::Deploy;
}

impl PayloadEntity for BlockHeader {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockHeader;
}

impl PayloadEntity for BlockHeaderV1 {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockHeaderV1;
}

impl PayloadEntity for BlockBody {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockBody;
}

impl PayloadEntity for BlockBodyV1 {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockBodyV1;
}

impl PayloadEntity for BlockSignatures {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockSignatures;
}

impl PayloadEntity for BlockSignaturesV1 {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockSignaturesV1;
}

impl PayloadEntity for ExecutionResult {
    const RESPONSE_TYPE: ResponseType = ResponseType::ExecutionResult;
}

impl PayloadEntity for ExecutionResultV1 {
    const RESPONSE_TYPE: ResponseType = ResponseType::ExecutionResultV1;
}

impl PayloadEntity for BlockWithSignatures {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockWithSignatures;
}

impl PayloadEntity for TransactionWithExecutionInfo {
    const RESPONSE_TYPE: ResponseType = ResponseType::TransactionWithExecutionInfo;
}

impl PayloadEntity for Peers {
    const RESPONSE_TYPE: ResponseType = ResponseType::Peers;
}

impl PayloadEntity for Vec<Transfer> {
    const RESPONSE_TYPE: ResponseType = ResponseType::Transfers;
}

impl PayloadEntity for AvailableBlockRange {
    const RESPONSE_TYPE: ResponseType = ResponseType::AvailableBlockRange;
}

impl PayloadEntity for ChainspecRawBytes {
    const RESPONSE_TYPE: ResponseType = ResponseType::ChainspecRawBytes;
}

impl PayloadEntity for ConsensusValidatorChanges {
    const RESPONSE_TYPE: ResponseType = ResponseType::ConsensusValidatorChanges;
}

impl PayloadEntity for GlobalStateQueryResult {
    const RESPONSE_TYPE: ResponseType = ResponseType::GlobalStateQueryResult;
}

impl PayloadEntity for DictionaryQueryResult {
    const RESPONSE_TYPE: ResponseType = ResponseType::DictionaryQueryResult;
}

impl PayloadEntity for Vec<StoredValue> {
    const RESPONSE_TYPE: ResponseType = ResponseType::StoredValues;
}

impl PayloadEntity for GetTrieFullResult {
    const RESPONSE_TYPE: ResponseType = ResponseType::GetTrieFullResult;
}

impl PayloadEntity for SpeculativeExecutionResult {
    const RESPONSE_TYPE: ResponseType = ResponseType::SpeculativeExecutionResult;
}

impl PayloadEntity for NodeStatus {
    const RESPONSE_TYPE: ResponseType = ResponseType::NodeStatus;
}

impl PayloadEntity for NextUpgrade {
    const RESPONSE_TYPE: ResponseType = ResponseType::NextUpgrade;
}

impl PayloadEntity for Uptime {
    const RESPONSE_TYPE: ResponseType = ResponseType::Uptime;
}

impl PayloadEntity for LastProgress {
    const RESPONSE_TYPE: ResponseType = ResponseType::LastProgress;
}

impl PayloadEntity for ReactorStateName {
    const RESPONSE_TYPE: ResponseType = ResponseType::ReactorState;
}

impl PayloadEntity for NetworkName {
    const RESPONSE_TYPE: ResponseType = ResponseType::NetworkName;
}

impl PayloadEntity for BlockSynchronizerStatus {
    const RESPONSE_TYPE: ResponseType = ResponseType::BlockSynchronizerStatus;
}

impl PayloadEntity for ConsensusStatus {
    const RESPONSE_TYPE: ResponseType = ResponseType::ConsensusStatus;
}

impl PayloadEntity for BalanceResponse {
    const RESPONSE_TYPE: ResponseType = ResponseType::BalanceResponse;
}

impl PayloadEntity for RewardResponse {
    const RESPONSE_TYPE: ResponseType = ResponseType::Reward;
}

impl PayloadEntity for ProtocolVersion {
    const RESPONSE_TYPE: ResponseType = ResponseType::ProtocolVersion;
}

impl PayloadEntity for ValueWithProof<ContractPackage> {
    const RESPONSE_TYPE: ResponseType = ResponseType::ContractPackageWithProof;
}

impl PayloadEntity for ContractInformation {
    const RESPONSE_TYPE: ResponseType = ResponseType::ContractInformation;
}

impl PayloadEntity for AccountInformation {
    const RESPONSE_TYPE: ResponseType = ResponseType::AccountInformation;
}

impl PayloadEntity for ValueWithProof<Package> {
    const RESPONSE_TYPE: ResponseType = ResponseType::PackageWithProof;
}

impl PayloadEntity for AddressableEntityInformation {
    const RESPONSE_TYPE: ResponseType = ResponseType::AddressableEntityInformation;
}

impl<T> PayloadEntity for Box<T>
where
    T: PayloadEntity,
{
    const RESPONSE_TYPE: ResponseType = T::RESPONSE_TYPE;
}

#[cfg(test)]
mod tests {
    use super::*;
    use casper_types::testing::TestRng;

    #[test]
    fn convert_u8_roundtrip() {
        let rng = &mut TestRng::new();

        let val = ResponseType::random(rng);
        assert_eq!(ResponseType::try_from(val as u8), Ok(val));
    }
}