spacejam_service/service/
account.rs

1//! Service account types
2
3use crate::{BTreeMap, Gas, OpaqueHash, TimeSlot, Vec, service::GasLimit};
4use anyhow::Result;
5use serde::{Deserialize, Serialize};
6
7#[cfg(feature = "json")]
8use {crate::String, spacejson::Json};
9
10/// The service accounts (δ)
11#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
12#[cfg_attr(feature = "json", derive(Json))]
13pub struct ServiceAccount {
14    /// The index of the service account (i)
15    pub index: u32,
16
17    /// storage of the service account (s)
18    pub storage: BTreeMap<Vec<u8>, Vec<u8>>,
19
20    /// The preimage of the service account (p)
21    pub preimage: BTreeMap<OpaqueHash, Vec<u8>>,
22
23    /// Preimage lookup dictionary (l)
24    pub lookup: BTreeMap<(OpaqueHash, u32), Vec<TimeSlot>>,
25
26    /// The info of the service account
27    #[cfg_attr(feature = "json", json(nested))]
28    pub info: ServiceInfo,
29}
30
31impl ServiceAccount {
32    /// Create a new service account
33    pub fn new(gas: GasLimit) -> Self {
34        Self {
35            index: 0,
36            storage: BTreeMap::new(),
37            preimage: BTreeMap::new(),
38            lookup: BTreeMap::new(),
39            info: ServiceInfo {
40                transfer: gas.transfer,
41                accumulate: gas.accumulate,
42                ..Default::default()
43            },
44        }
45    }
46
47    /// The state of the service account
48    pub fn state(&self) -> ServiceInfo {
49        self.info.clone()
50    }
51}
52
53/// Service info for pvm execution
54#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
55#[cfg_attr(feature = "json", derive(Json))]
56pub struct ServiceInfo {
57    /// The version of the service account (v)
58    pub version: u8,
59
60    /// The code hash of the service account (c)
61    #[cfg_attr(feature = "json", json(hex))]
62    #[serde(alias = "code_hash")]
63    pub code: OpaqueHash,
64
65    /// The balance of the service account (b)
66    pub balance: u64,
67
68    /// The minimum gas in order to execute the accumulate
69    /// entry-point of the service code (g)
70    #[serde(alias = "min_memo_gas")]
71    pub accumulate: Gas,
72
73    /// The minimum required for the on transfer entry-point (m)
74    #[serde(alias = "min_item_gas")]
75    pub transfer: Gas,
76
77    /// The total number of octets used in storage (o)
78    #[serde(alias = "bytes")]
79    pub total: u64,
80
81    /// The deposit offset of the service account (f)
82    #[serde(alias = "deposit_offset")]
83    pub offset: u64,
84
85    /// The number of items in storage (i)
86    pub items: u32,
87
88    /// The creation time of the service account (r)
89    #[serde(alias = "creation_slot")]
90    pub creation: u32,
91
92    /// The last update time of the service account (a)
93    #[serde(alias = "last_accumulation_slot")]
94    pub update: u32,
95
96    /// The parent of the service account (p)
97    #[serde(alias = "parent_service")]
98    pub parent: u32,
99}
100
101impl ServiceInfo {
102    /// encode self into the info that host call required
103    ///
104    /// FIXME: currently just for passing the test, we should
105    /// use the account's threshold without conditions.
106    pub fn host(&self) -> Result<Vec<u8>> {
107        codec::encode(&(
108            self.code,
109            self.balance,
110            self.threshold(),
111            self.accumulate,
112            self.transfer,
113            self.total,
114            self.items,
115            self.offset,
116            self.creation,
117            self.update,
118            self.parent,
119        ))
120        .map_err(Into::into)
121    }
122
123    /// The threshold of the service account
124    pub fn threshold(&self) -> u64 {
125        (crate::BALANCE_PER_SERVICE
126            + crate::BALANCE_PER_ITEM * self.items as u64
127            + crate::BALANCE_PER_OCTET * self.total)
128            .saturating_sub(self.offset)
129    }
130}