unc_primitives/action/
mod.rs

1pub mod delegate;
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use serde_with::base64::Base64;
5use serde_with::serde_as;
6use std::fmt;
7use unc_crypto::PublicKey;
8use unc_primitives_core::{
9    account::AccessKey,
10    serialize::dec_format,
11    types::{AccountId, Balance, Gas},
12};
13
14fn base64(s: &[u8]) -> String {
15    use base64::Engine;
16    base64::engine::general_purpose::STANDARD.encode(s)
17}
18
19#[derive(
20    BorshSerialize,
21    BorshDeserialize,
22    PartialEq,
23    Eq,
24    Clone,
25    Debug,
26    serde::Serialize,
27    serde::Deserialize,
28)]
29pub struct AddKeyAction {
30    /// A public key which will be associated with an access_key
31    pub public_key: PublicKey,
32    /// An access key with the permission
33    pub access_key: AccessKey,
34}
35
36/// Create account action
37#[derive(
38    BorshSerialize,
39    BorshDeserialize,
40    PartialEq,
41    Eq,
42    Clone,
43    Debug,
44    serde::Serialize,
45    serde::Deserialize,
46)]
47pub struct CreateAccountAction {}
48
49#[derive(
50    BorshSerialize,
51    BorshDeserialize,
52    PartialEq,
53    Eq,
54    Clone,
55    Debug,
56    serde::Serialize,
57    serde::Deserialize,
58)]
59pub struct DeleteAccountAction {
60    pub beneficiary_id: AccountId,
61}
62
63#[derive(
64    BorshSerialize,
65    BorshDeserialize,
66    PartialEq,
67    Eq,
68    Clone,
69    Debug,
70    serde::Serialize,
71    serde::Deserialize,
72)]
73pub struct DeleteKeyAction {
74    /// A public key associated with the access_key to be deleted.
75    pub public_key: PublicKey,
76}
77
78/// Deploy contract action
79#[serde_as]
80#[derive(
81    BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
82)]
83pub struct DeployContractAction {
84    /// WebAssembly binary
85    #[serde_as(as = "Base64")]
86    pub code: Vec<u8>,
87}
88
89impl fmt::Debug for DeployContractAction {
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        f.debug_struct("DeployContractAction")
92            .field("code", &format_args!("{}", base64(&self.code)))
93            .finish()
94    }
95}
96
97#[serde_as]
98#[derive(
99    BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
100)]
101pub struct FunctionCallAction {
102    pub method_name: String,
103    #[serde_as(as = "Base64")]
104    pub args: Vec<u8>,
105    pub gas: Gas,
106    #[serde(with = "dec_format")]
107    pub deposit: Balance,
108}
109
110impl fmt::Debug for FunctionCallAction {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        f.debug_struct("FunctionCallAction")
113            .field("method_name", &format_args!("{}", &self.method_name))
114            .field("args", &format_args!("{}", base64(&self.args)))
115            .field("gas", &format_args!("{}", &self.gas))
116            .field("deposit", &format_args!("{}", &self.deposit))
117            .finish()
118    }
119}
120
121/// An action which pledges signer_id tokens and setup's validator public key
122#[derive(
123    BorshSerialize,
124    BorshDeserialize,
125    PartialEq,
126    Eq,
127    Clone,
128    Debug,
129    serde::Serialize,
130    serde::Deserialize,
131)]
132pub struct PledgeAction {
133    /// Amount of tokens to pledge.
134    #[serde(with = "dec_format")]
135    pub pledge: Balance,
136    /// Validator key which will be used to sign transactions on behalf of signer_id
137    pub public_key: PublicKey,
138}
139
140#[derive(
141    BorshSerialize,
142    BorshDeserialize,
143    PartialEq,
144    Eq,
145    Clone,
146    Debug,
147    serde::Serialize,
148    serde::Deserialize,
149)]
150pub struct TransferAction {
151    #[serde(with = "dec_format")]
152    pub deposit: Balance,
153}
154
155#[serde_as]
156#[derive(
157    BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
158)]
159pub struct RegisterRsa2048KeysAction {
160    /// this only can be used by the owner of root account
161    /// Public key used to sign this rsa keys action.
162    pub public_key: PublicKey,
163    /// addkeys or deletekeys
164    pub operation_type: u8,
165    /// attach args such as Miner id, sequence number,power,etc.
166    #[serde_as(as = "Base64")]
167    pub args: Vec<u8>,
168}
169
170impl fmt::Debug for RegisterRsa2048KeysAction {
171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172        f.debug_struct("RegisterRsa2048KeysAction")
173            .field("public_key", &format_args!("{}", &self.public_key))
174            .field("operation_type", &format_args!("{}", &self.operation_type))
175            .field("args", &format_args!("{}", base64(&self.args)))
176            .finish()
177    }
178}
179
180#[serde_as]
181#[derive(
182    BorshSerialize, BorshDeserialize, serde::Serialize, serde::Deserialize, PartialEq, Eq, Clone,
183)]
184pub struct CreateRsa2048ChallengeAction {
185    /// real miner request to create rsa2048 challenge
186    /// Public key used to sign this rsa keys action.
187    pub public_key: PublicKey,
188    /// Challenge key used to bind ValidatorPower
189    pub challenge_key: PublicKey,
190    /// attach args such as Miner id, sequence number,power,etc.
191    #[serde_as(as = "Base64")]
192    pub args: Vec<u8>,
193}
194
195impl fmt::Debug for CreateRsa2048ChallengeAction {
196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197        f.debug_struct("CreateRsa2048ChallengeAction")
198            .field("public_key", &format_args!("{}", &self.public_key))
199            .field("challenge_key", &format_args!("{}", &self.challenge_key))
200            .field("args", &format_args!("{}", base64(&self.args)))
201            .finish()
202    }
203}
204
205#[derive(
206    BorshSerialize,
207    BorshDeserialize,
208    PartialEq,
209    Eq,
210    Debug,
211    Clone,
212    serde::Serialize,
213    serde::Deserialize,
214    strum::AsRefStr,
215)]
216pub enum Action {
217    /// Create an (sub)account using a transaction `receiver_id` as an ID for
218    /// a new account ID must pass validation rules described here
219    /// <http://nomicon.io/Primitives/Account.html>.
220    CreateAccount(CreateAccountAction),
221    /// Sets a Wasm code to a receiver_id
222    DeployContract(DeployContractAction),
223    FunctionCall(Box<FunctionCallAction>),
224    Transfer(TransferAction),
225    Pledge(Box<PledgeAction>),
226    AddKey(Box<AddKeyAction>),
227    DeleteKey(Box<DeleteKeyAction>),
228    DeleteAccount(DeleteAccountAction),
229    Delegate(Box<delegate::SignedDelegateAction>),
230    RegisterRsa2048Keys(Box<RegisterRsa2048KeysAction>),
231    CreateRsa2048Challenge(Box<CreateRsa2048ChallengeAction>),
232}
233
234const _: () = assert!(
235    // 1 word for tag plus the largest variant `DeployContractAction` which is a 3-word `Vec`.
236    // The `<=` check covers platforms that have pointers smaller than 8 bytes as well as random
237    // freak nightlies that somehow find a way to pack everything into one less word.
238    std::mem::size_of::<Action>() <= 32,
239    "Action <= 32 bytes for performance reasons, see #9451"
240);
241
242impl Action {
243    pub fn get_prepaid_gas(&self) -> Gas {
244        match self {
245            Action::FunctionCall(a) => a.gas,
246            _ => 0,
247        }
248    }
249    pub fn get_deposit_balance(&self) -> Balance {
250        match self {
251            Action::FunctionCall(a) => a.deposit,
252            Action::Transfer(a) => a.deposit,
253            _ => 0,
254        }
255    }
256}
257
258impl From<CreateAccountAction> for Action {
259    fn from(create_account_action: CreateAccountAction) -> Self {
260        Self::CreateAccount(create_account_action)
261    }
262}
263
264impl From<DeployContractAction> for Action {
265    fn from(deploy_contract_action: DeployContractAction) -> Self {
266        Self::DeployContract(deploy_contract_action)
267    }
268}
269
270impl From<FunctionCallAction> for Action {
271    fn from(function_call_action: FunctionCallAction) -> Self {
272        Self::FunctionCall(Box::new(function_call_action))
273    }
274}
275
276impl From<TransferAction> for Action {
277    fn from(transfer_action: TransferAction) -> Self {
278        Self::Transfer(transfer_action)
279    }
280}
281
282impl From<PledgeAction> for Action {
283    fn from(pledge_action: PledgeAction) -> Self {
284        Self::Pledge(Box::new(pledge_action))
285    }
286}
287
288impl From<AddKeyAction> for Action {
289    fn from(add_key_action: AddKeyAction) -> Self {
290        Self::AddKey(Box::new(add_key_action))
291    }
292}
293
294impl From<DeleteKeyAction> for Action {
295    fn from(delete_key_action: DeleteKeyAction) -> Self {
296        Self::DeleteKey(Box::new(delete_key_action))
297    }
298}
299
300impl From<DeleteAccountAction> for Action {
301    fn from(delete_account_action: DeleteAccountAction) -> Self {
302        Self::DeleteAccount(delete_account_action)
303    }
304}
305
306impl From<RegisterRsa2048KeysAction> for Action {
307    fn from(rsa2048_keys_action: RegisterRsa2048KeysAction) -> Self {
308        Self::RegisterRsa2048Keys(Box::new(rsa2048_keys_action))
309    }
310}
311
312impl From<CreateRsa2048ChallengeAction> for Action {
313    fn from(create_rsa2048_challenge_action: CreateRsa2048ChallengeAction) -> Self {
314        Self::CreateRsa2048Challenge(Box::new(create_rsa2048_challenge_action))
315    }
316}