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
use scale::{Decode, Encode};

use crate::OcallError;

pub type AccountId = [u8; 32];
pub type H256 = [u8; 32];

#[derive(Encode, Decode)]
pub struct QueryRequest {
    pub origin: Option<AccountId>,
    pub payload: Vec<u8>,
    pub reply_tx: i32,
}

#[derive(Encode, Decode, Debug)]
pub struct HttpHead {
    pub method: String,
    pub url: String,
    pub headers: Vec<(String, String)>,
}

impl HttpHead {
    pub fn get_header(&self, key: &str) -> Option<&str> {
        let key = key.to_ascii_lowercase();
        for (k, v) in &self.headers {
            if k.to_ascii_lowercase() == key {
                return Some(v);
            }
        }
        None
    }
}

#[derive(Encode, Decode, Debug)]
pub struct HttpRequest {
    pub head: HttpHead,
    pub response_tx: i32,
    pub io_stream: i32,
}

#[derive(Encode, Decode, Debug)]
pub struct HttpResponseHead {
    pub status: u16,
    pub headers: Vec<(String, String)>,
}

#[derive(Encode, Decode)]
pub enum SystemMessage {
    PinkLog {
        block_number: u32,
        contract: AccountId,
        entry: AccountId,
        exec_mode: String,
        timestamp_ms: u64,
        level: u8,
        message: String,
    },
    PinkEvent {
        block_number: u32,
        contract: AccountId,
        topics: Vec<H256>,
        payload: Vec<u8>,
    },
    PinkMessageOutput {
        block_number: u32,
        origin: AccountId,
        contract: AccountId,
        nonce: Vec<u8>,
        output: Vec<u8>,
    },
    Metric(Metric),
}

#[derive(Encode, Decode)]
pub enum Metric {
    PinkQueryIn([u8; 8]),
}

/// Errors that may occur during the contract query.
#[derive(Debug, Encode, Decode)]
pub enum QueryError {
    /// Ocall error.
    OcallError(OcallError),
    /// The origin is invalid.
    BadOrigin,
    /// An error occurred during the contract execution.
    RuntimeError(String),
    /// The contract is not found.
    SidevmNotFound,
    /// No response received from the contract. Maybe the contract was panicked during execution.
    NoResponse,
    /// The contract is busy and cannot process the request.
    ServiceUnavailable,
    /// The request is timeout.
    Timeout,
    /// Signature is invalid.
    InvalidSignature,
    /// No such contract.
    ContractNotFound,
    /// Unable to decode the request data.
    DecodeError,
    /// Other errors reported during the contract query execution.
    OtherError(String),
    /// The operation is unsupported.
    Unsupported,
    /// Failed to decode the ContractExecResult.
    InvalidContractExecResult,
    /// Error reported by the pink runtime.
    DispatchError(String),
}

impl From<OcallError> for QueryError {
    fn from(err: OcallError) -> Self {
        Self::OcallError(err)
    }
}

#[derive(Encode, Decode)]
pub enum QueryResponse {
    OutputWithGasEstimation {
        output: Vec<u8>,
        gas_consumed: u64,
        gas_required: u64,
        storage_deposit_value: u128,
        storage_deposit_is_charge: bool,
    },
    SimpleOutput(Vec<u8>),
}