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 code hash of the service account (c)
58    #[cfg_attr(feature = "json", json(hex))]
59    #[serde(alias = "code_hash")]
60    pub code: OpaqueHash,
61
62    /// The balance of the service account (b)
63    pub balance: u64,
64
65    /// The minimum gas in order to execute the accumulate
66    /// entry-point of the service code (g)
67    #[serde(alias = "min_memo_gas")]
68    pub accumulate: Gas,
69
70    /// The minimum required for the on transfer entry-point (m)
71    #[serde(alias = "min_item_gas")]
72    pub transfer: Gas,
73
74    /// The total number of octets used in storage (o)
75    #[serde(alias = "bytes")]
76    pub total: u64,
77
78    /// The deposit offset of the service account (f)
79    #[serde(alias = "deposit_offset")]
80    pub offset: u64,
81
82    /// The number of items in storage (i)
83    pub items: u32,
84
85    /// The creation time of the service account (r)
86    #[serde(alias = "creation_slot")]
87    pub creation: u32,
88
89    /// The last update time of the service account (a)
90    #[serde(alias = "last_accumulation_slot")]
91    pub update: u32,
92
93    /// The parent of the service account (p)
94    #[serde(alias = "parent_service")]
95    pub parent: u32,
96}
97
98impl ServiceInfo {
99    /// encode self into the info that host call required
100    ///
101    /// FIXME: currently just for passing the test, we should
102    /// use the account's threshold without conditions.
103    pub fn host(&self) -> Result<Vec<u8>> {
104        codec::encode(&(
105            self.code,
106            self.balance,
107            self.threshold(),
108            self.accumulate,
109            self.transfer,
110            self.total,
111            self.items,
112            self.offset,
113            self.creation,
114            self.update,
115            self.parent,
116        ))
117        .map_err(Into::into)
118    }
119
120    /// The threshold of the service account
121    pub fn threshold(&self) -> u64 {
122        (crate::BALANCE_PER_SERVICE
123            + crate::BALANCE_PER_ITEM * self.items as u64
124            + crate::BALANCE_PER_OCTET * self.total)
125            .saturating_sub(self.offset)
126    }
127}