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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
//! The type of accounts stored in the Mina ledger
//!
//! This defines the complete types used by the protocol as ammended by the proposed snapps
//! specification.
use crate::pickles;
use crate::primitives::*;
use crate::sequence_event::SequenceState;
use crate::token_id;
#[derive(Clone, Copy)]
pub struct TimingInfo {
pub initial_minimum_balance: u64,
pub cliff_time: u32,
pub cliff_amount: u64,
pub vesting_period: u32,
pub vesting_increment: u64,
}
/// Timing of the cliff and vesting for unlock of 'protocol-locked' tokens.
#[derive(Clone, Copy)]
pub enum AccountTiming {
Timed(TimingInfo),
Untimed,
}
/// The type of accounts stored in the ledger.
pub struct Account<'a> {
/// Public key for the account.
pub public_key: CompressedPublicKey,
/// ID of the token whose balance is stored in this account.
pub token_id: token_id::TokenID,
/// Balance in tokens in this account.
pub balance: u64,
/// Nonce of the account. This is incremented by transactions with signatures to ensure that a
/// signed transaction cannot be replayed more than once.
pub nonce: u32,
/// The hash of all previous signed transactions applied to this account.
pub receipt_chain_hash: Hash,
/// Public key to delegate staking of the balance to.
pub delegate: CompressedPublicKey,
/// The state hash of the Mina chain that this account is voting for.
pub voting_for: StateHash,
/// Timing of the cliff and vesting for token unlock.
pub timing: AccountTiming,
/// Authorization kinds required for account actions.
pub permissions: Permissions,
/// Optional information for use by snapp smart contracts.
pub snapp: Option<SnappAccount<'a>>,
}
impl<'a> Account<'a> {
/// The 'empty' account, used for unused positions in the ledger.
///
/// ```rust
/// empty() =
/// Account {
/// public_key: CompressedPublicKey::empty(),
/// token_id: 1,
/// balance: 0,
/// nonce: 0,
/// receipt_chain_hash: Hash::empty_receipt_chain_hash(),
/// delegate: CompressedPublicKey::empty(),
/// voting_for: StateHash::invalid_hash(),
/// timing: AccountTiming::Untimed,
/// permissions: Permissions::default() ,
/// snapp: None,
/// }
/// ```
pub fn empty() -> Account<'a> {
Account {
public_key: CompressedPublicKey::empty(),
token_id: 1,
balance: 0,
nonce: 0,
receipt_chain_hash: Hash::empty_receipt_chain_hash(),
delegate: CompressedPublicKey::empty(),
voting_for: StateHash::invalid_hash(),
timing: AccountTiming::Untimed,
permissions: Permissions::default(),
snapp: None,
}
}
}
/// Account information for use by snapp smart contracts.
pub struct SnappAccount<'a> {
/// General purpose storage for use by the snapp associated with this account.
pub app_state: [Fp; 8],
/// Verification key for the snapp associated with this account, or `None` if this account has
/// no associated snapp.
pub verification_key: Option<pickles::VerificationKey>,
/// Snapp protocol version
pub snapp_protocol_version: u32,
/// History of sequenced event updates for the most recent 5 slots with updates
pub sequence_state: SequenceState,
/// `true` if the current `app_state` was initialized by a transaction authorized using a proof,
/// and every subsequent update was also authorized by a transaction using a proof; `false`
/// otherwise.
///
/// Snapp authors may use this field to validate that their snapp was initialized honestly and
/// correctly before being used.
pub proved_state: bool,
/// URI to access the code and other resources for this account's snapp smart contract
pub uri: &'a str,
/// The symbol for the token managed by this account.
/// This string has a maximum length of 6 characters.
pub token_symbol: &'a str,
}
impl<'a> SnappAccount<'a> {
/// The 'empty' snapp account state.
/// The `snapp` field of an account is equivalent to this value if and only if it is set to
/// `None`.
/// ```rust
/// empty() =
/// SnappAccount {
/// app_state: [Fp::zero(); 8],
/// verification_key: None,
/// snapp_protocol_version: 0,
/// sequence_state: SequenceState::empty(),
/// proved_state: false,
/// uri: "",
/// token_symbol: "",
/// }
/// ```
pub fn empty() -> SnappAccount<'a> {
SnappAccount {
app_state: [Fp::zero(); 8],
verification_key: None,
snapp_protocol_version: 0,
sequence_state: SequenceState::empty(),
proved_state: false,
uri: "",
token_symbol: "",
}
}
/// Returns true if the argument is identical to [`SnappAccount::empty`], false otherwise.
#[allow(unused)]
pub fn is_empty(snapp: &SnappAccount<'a>) -> bool {
panic!("TODO")
}
}
/// Permissions required for updates to the account.
///
/// Each update applied to the account by a snapp transaction corresponds to one of the fields of
/// this record. The [`AuthorizationRequired`] value of the field determines which authorization
/// kinds may accompany a transaction issuing that update.
#[derive(Copy, Clone)]
pub struct Permissions {
/// Authorization required to update the account's `snapp.app_state`.
pub edit_state: AuthorizationRequired,
/// Authorization required to decrease the `balance` of this account.
pub send: AuthorizationRequired,
/// Authorization required to increase the `balance` of this account.
pub receive: AuthorizationRequired,
/// Authorization required to modify this account's `delegate`.
pub set_delegate: AuthorizationRequired,
/// Authorization required to modify this account's `permissions`.
pub set_permissions: AuthorizationRequired,
/// Authorization required to modify this account's `snapp.verification_key`.
pub set_verification_key: AuthorizationRequired,
/// Authorization required to modify this account's `snapp.uri`.
pub set_snapp_uri: AuthorizationRequired,
/// Authorization required to submit sequence events to this account.
pub add_sequence_events: AuthorizationRequired,
/// Authorization required to increment this account's `nonce`.
pub increment_nonce: AuthorizationRequired,
}
impl Permissions {
/// The default permissions. Sets every field of [`Permissions`] to
/// [`AuthorizationRequired::Signature`].
pub fn default() -> Permissions {
Permissions {
edit_state: AuthorizationRequired::Signature,
send: AuthorizationRequired::Signature,
receive: AuthorizationRequired::Signature,
set_delegate: AuthorizationRequired::Signature,
set_permissions: AuthorizationRequired::Signature,
set_verification_key: AuthorizationRequired::Signature,
set_snapp_uri: AuthorizationRequired::Signature,
add_sequence_events: AuthorizationRequired::Signature,
increment_nonce: AuthorizationRequired::Signature,
}
}
}
/// The kind of authorization that must be provided in a transaction to apply a particular kind of
/// updates.
#[derive(Copy, Clone)]
pub enum AuthorizationRequired {
/// No authorization required.
NoneRequired,
/// Either a proof or a signature may be provided as authorization.
ProofOrSignature,
/// A proof must be provided as authorization.
Proof,
/// A signature must be provided as authorization.
Signature,
/// This kind of update is disabled.
Disabled,
}