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
// Copyright (c) 2022 MASSA LABS <info@massa.net>

use massa_deferred_calls::DeferredCall;
use massa_final_state::StateChanges;
use massa_models::{
    address::Address, amount::Amount, block_id::BlockId, operation::OperationId,
    output_event::SCOutputEvent, slot::Slot,
};
use serde::{Deserialize, Serialize};
use std::{collections::VecDeque, fmt::Display};

/// The result of the read-only execution.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ReadOnlyResult {
    /// An error occurred during execution.
    Error(String),
    /// The result of a successful execution.
    Ok(Vec<u8>),
}

/// The response to a request for a read-only execution.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ExecuteReadOnlyResponse {
    /// The slot at which the read-only execution occurred.
    pub executed_at: Slot,
    /// The result of the read-only execution.
    pub result: ReadOnlyResult,
    /// The output events generated by the read-only execution.
    pub output_events: VecDeque<SCOutputEvent>,
    /// The gas cost for the execution
    pub gas_cost: u64,
    /// state changes caused by the execution step
    pub state_changes: StateChanges,
}

impl Display for ExecuteReadOnlyResponse {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "Executed at slot: {}", self.executed_at)?;
        writeln!(
            f,
            "Result: {}",
            match &self.result {
                ReadOnlyResult::Error(e) =>
                    format!("an error occurred during the execution: {}", e),
                ReadOnlyResult::Ok(ret) => format!("success, returned value: {:?}", ret),
            }
        )?;
        writeln!(f, "Gas cost: {}", self.gas_cost)?;
        if !self.output_events.is_empty() {
            writeln!(f, "Generated events:",)?;
            for event in self.output_events.iter() {
                writeln!(f, "{}", event)?; // id already displayed in event
            }
        }
        Ok(())
    }
}

/// read only bytecode execution request
#[derive(Debug, Deserialize, Clone, Serialize)]
pub struct ReadOnlyBytecodeExecution {
    /// max available gas
    pub max_gas: u64,
    /// byte code
    pub bytecode: Vec<u8>,
    /// caller's address, optional
    pub address: Option<Address>,
    /// Operation datastore, optional
    pub operation_datastore: Option<Vec<u8>>,
    /// fee
    pub fee: Option<Amount>,
}

/// read SC call request
#[derive(Debug, Deserialize, Clone, Serialize)]
pub struct ReadOnlyCall {
    /// max available gas
    pub max_gas: u64,
    /// target address
    pub target_address: Address,
    /// target function
    pub target_function: String,
    /// function parameter
    pub parameter: Vec<u8>,
    /// caller's address, optional
    pub caller_address: Option<Address>,
    /// coins
    pub coins: Option<Amount>,
    /// fee
    pub fee: Option<Amount>,
}

/// Context of the transfer
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TransferContext {
    #[serde(rename = "operation_id")]
    /// Transfer made in an operation
    Operation(OperationId),
    #[serde(rename = "asc_index")]
    /// Transfer made in an asynchronous call
    ASC(u64),
}

/// Structure defining a transfer
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Transfer {
    /// The sender of the transfer
    pub from: Address,
    /// The receiver of the transfer
    pub to: Address,
    /// The amount of the transfer
    pub amount: Amount,
    /// The effective amount received by the receiver
    pub effective_amount_received: Amount,
    /// If the transfer succeed or not
    pub succeed: bool,
    /// Fee
    pub fee: Amount,
    /// Block ID
    pub block_id: BlockId,
    /// Context
    pub context: TransferContext,
}

/// request for deferred call quote
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeferredCallsQuoteRequest {
    /// The slot at which the deferred call is to be executed.
    pub target_slot: Slot,
    /// The maximum gas requested.
    pub max_gas_request: u64,
    /// Size of parameters
    pub params_size: u64,
}

/// The response to a request for a deferred call quote.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeferredCallsQuoteResponse {
    /// The slot at which the deferred call is to be executed.
    pub target_slot: Slot,
    /// The maximum gas requested.
    pub max_gas_request: u64,
    /// if the slot is bookable
    pub available: bool,
    /// the cost for booking the call
    pub price: Amount,
}

/// response for deferred call
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeferredCallResponse {
    /// deferred call id
    pub call_id: String,
    /// deferred call
    pub call: DeferredCall,
}

/// response for deferred calls by slot
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeferredCallsSlotResponse {
    /// deferred calls
    pub slot: Slot,
    /// deferred calls
    pub call_ids: Vec<String>,
}