Skip to content

Commit b4341c7

Browse files
committed
Refactor the token module and host interface.
1 parent 50264c6 commit b4341c7

File tree

5 files changed

+394
-388
lines changed

5 files changed

+394
-388
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//! Host interface for protocol-level tokens.
2+
use concordium_base::base::{AccountIndex, Energy};
3+
use concordium_base::contracts_common::AccountAddress;
4+
use concordium_base::protocol_level_tokens::RawCbor;
5+
use concordium_base::transactions::Memo;
6+
7+
pub type StateKey = Vec<u8>;
8+
pub type StateValue = Vec<u8>;
9+
pub type TokenEventType = String;
10+
pub type TokenEventDetails = RawCbor;
11+
pub type Parameter = RawCbor;
12+
pub type TokenRawAmount = u64;
13+
14+
/// The account has insufficient balance.
15+
#[derive(Debug)]
16+
pub struct InsufficientBalanceError;
17+
18+
/// Update to state key failed because the key was locked by an iterator.
19+
#[derive(Debug, thiserror::Error)]
20+
#[error("State key is locked")]
21+
pub struct LockedStateKeyError;
22+
23+
/// Mint exceed the representable amount.
24+
#[derive(Debug, thiserror::Error)]
25+
#[error("Amount not representable")]
26+
pub struct AmountNotRepresentableError;
27+
28+
/// Operations provided by the deployment unit host.
29+
///
30+
/// This is abstracted in a trait to allow for a testing stub.
31+
pub trait HostOperations {
32+
/// The type for the account object.
33+
///
34+
/// The account is guaranteed to exist on chain, when holding an instance of this type.
35+
type Account;
36+
37+
/// Lookup the account using an account address.
38+
fn account_by_address(&self, address: &AccountAddress) -> Option<Self::Account>;
39+
40+
/// Lookup the account using an account index.
41+
fn account_by_index(&self, index: AccountIndex) -> Option<Self::Account>;
42+
43+
/// Get the account index for the account.
44+
fn account_index(&self, account: &Self::Account) -> AccountIndex;
45+
46+
/// Get the canonical account address of the account, i.e. the address used as part of the
47+
/// credential deployment and not an alias.
48+
fn account_canonical_address(&self, account: &Self::Account) -> AccountAddress;
49+
50+
/// Get the token balance of the account.
51+
fn account_balance(&self, account: &Self::Account) -> TokenRawAmount;
52+
53+
/// Update the balance of the given account to zero if it didn't have a balance before.
54+
///
55+
/// Returns `true` if the balance wasn't present on the given account and `false` otherwise.
56+
fn touch(&mut self, account: &Self::Account) -> bool;
57+
58+
/// Mint a specified amount and deposit it in the account.
59+
///
60+
/// # Events
61+
///
62+
/// This will produce a `TokenMintEvent` in the logs.
63+
///
64+
/// # Errors
65+
///
66+
/// - [`AmountNotRepresentableError`] The total supply would exceed the representable amount.
67+
fn mint(
68+
&mut self,
69+
account: &Self::Account,
70+
amount: TokenRawAmount,
71+
) -> Result<(), AmountNotRepresentableError>;
72+
73+
/// Burn a specified amount from the account.
74+
///
75+
/// # Events
76+
///
77+
/// This will produce a `TokenBurnEvent` in the logs.
78+
///
79+
/// # Errors
80+
///
81+
/// - [`InsufficientBalanceError`] The sender has insufficient balance.
82+
fn burn(
83+
&mut self,
84+
account: &Self::Account,
85+
amount: TokenRawAmount,
86+
) -> Result<(), InsufficientBalanceError>;
87+
88+
/// Transfer a token amount from one account to another, with an optional memo.
89+
///
90+
/// # Events
91+
///
92+
/// This will produce a `TokenTransferEvent` in the logs.
93+
///
94+
/// # Errors
95+
///
96+
/// - [`InsufficientBalanceError`] The sender has insufficient balance.
97+
fn transfer(
98+
&mut self,
99+
from: &Self::Account,
100+
to: &Self::Account,
101+
amount: TokenRawAmount,
102+
memo: Option<Memo>,
103+
) -> Result<(), InsufficientBalanceError>;
104+
105+
/// The current token circulation supply.
106+
fn circulating_supply(&self) -> TokenRawAmount;
107+
108+
/// The number of decimals used in the presentation of the token amount.
109+
fn decimals(&self) -> u8;
110+
111+
/// Lookup a key in the token state.
112+
fn get_token_state(&self, key: StateKey) -> Option<StateValue>;
113+
114+
/// Set or clear a value in the token state at the corresponding key.
115+
///
116+
/// Returns whether there was an existing entry.
117+
///
118+
/// # Errors
119+
///
120+
/// - [`LockedStateKeyError`] if the update failed because the key was locked by an iterator.
121+
fn set_token_state(
122+
&mut self,
123+
key: StateKey,
124+
value: Option<StateValue>,
125+
) -> Result<bool, LockedStateKeyError>;
126+
127+
/// Reduce the available energy for the PLT module execution.
128+
///
129+
/// If the available energy is smaller than the given amount, the containing transaction will
130+
/// abort and the effects of the transaction will be rolled back.
131+
/// The energy is charged in any case (also in case of failure).
132+
fn tick_energy(&mut self, energy: Energy);
133+
134+
/// Log a token module event with the specified type and details.
135+
///
136+
/// # Events
137+
///
138+
/// This will produce a `TokenModuleEvent` in the logs.
139+
fn log_token_event(&mut self, event_type: TokenEventType, event_details: TokenEventDetails);
140+
}

0 commit comments

Comments
 (0)