Skip to content

Commit 3e87a11

Browse files
committed
Setup rust PLT scheduler project and CI
1 parent ece1fa6 commit 3e87a11

File tree

6 files changed

+234
-2
lines changed

6 files changed

+234
-2
lines changed

.github/workflows/deployment-build-test.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ on:
77
paths:
88
- '.github/workflows/deployment-build-test.yaml'
99
- 'concordium-base'
10-
- 'deployment'
10+
- 'plt-deployment-unit'
1111

1212
pull_request:
1313
paths:
1414
- '.github/workflows/deployment-build-test.yaml'
1515
- 'concordium-base'
16-
- 'deployment'
16+
- 'plt-deployment-unit'
1717
env:
1818
CARGO_TERM_COLOR: always # implicitly adds '--color=always' to all cargo commands
1919

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: PLT scheduler checks
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- '.github/workflows/deployment-build-test.yaml'
9+
- 'concordium-base'
10+
- 'plt-deployment-unit'
11+
- 'plt-scheduler'
12+
13+
pull_request:
14+
paths:
15+
- '.github/workflows/plt-scheduler-build-test.yaml'
16+
- 'concordium-base'
17+
- 'plt-deployment-unit'
18+
- 'plt-scheduler'
19+
env:
20+
CARGO_TERM_COLOR: always # implicitly adds '--color=always' to all cargo commands
21+
22+
jobs:
23+
rustfmt:
24+
name: Check formatting
25+
runs-on: ubuntu-latest
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v2
29+
with:
30+
submodules: recursive
31+
- name: Run rustfmt
32+
working-directory: plt-scheduler
33+
run: |
34+
rustup component add rustfmt
35+
cargo fmt -- --check
36+
37+
clippy_test:
38+
name: Run Clippy and tests
39+
runs-on: ubuntu-latest
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v4
43+
with:
44+
submodules: recursive
45+
- name: Clippy
46+
working-directory: plt-scheduler
47+
run: |
48+
rustup component add clippy
49+
cargo clippy --all-targets --all-features --locked -- -D warnings
50+
- name: Test
51+
working-directory: plt-scheduler
52+
run: cargo test --all-targets --all-features

plt-scheduler/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "plt-scheduler"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]

plt-scheduler/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# concordium-node: Scheduler implementation for Protocol-level token (PLT)
2+
3+
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](https://github.com/Concordium/.github/blob/main/.github/CODE_OF_CONDUCT.md)
4+
![Build and test](https://github.com/Concordium/concordium-node/actions/workflows/plt-scheduler-build-test.yaml/badge.svg)
5+
6+
This crate provides a scheduler (transaction execution) implementation for concordium-node, and currently only supports transactions related to Protocol-level Tokens.
7+
8+
It is compiled as a native library and is used within the Haskell implemented scheduler found as part of [`concordium-consensus`](../concordium-consensus/README.md).

plt-scheduler/rust-toolchain.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[toolchain]
2+
channel = "1.82"

plt-scheduler/src/lib.rs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Placeholder types to be defined or replaced with types from concordium-base.
2+
3+
type MutableTokenState = ();
4+
type PLTConfiguration = ();
5+
type TokenRawAmount = ();
6+
type TokenAmountDelta = ();
7+
type TokenIndex = ();
8+
type AccountIndex = ();
9+
type TokenId = ();
10+
11+
/// Operations on the state of a block in the chain.
12+
trait BlockStateOperations {
13+
// Protocol-level token state query interface.
14+
15+
/// Get the [`TokenId`]s of all protocol-level tokens registered on the chain.
16+
///
17+
/// If the protocol version does not support protocol-level tokens, this will return the empty
18+
/// list.
19+
fn get_plt_list(&self) -> impl std::iter::Iterator<Item = TokenId>;
20+
21+
/// Get the [`TokenIndex`] associated with a [`TokenId`] (if it exists).
22+
///
23+
/// # Arguments
24+
///
25+
/// - `token_index` The token index to update.
26+
fn get_token_index(&self, token_id: TokenId) -> Option<TokenIndex>;
27+
28+
/// Convert a persistent state to a mutable one that can be updated by the scheduler.
29+
///
30+
/// Updates to this state will only persist in the block state using [`BlockStateOperaionts::set_token_state`].
31+
///
32+
/// # Arguments
33+
///
34+
/// - `token_index` The index of the token to get the state from.
35+
///
36+
/// # Panics
37+
///
38+
/// Panics if the token identified by `token_index` does not exist.
39+
fn get_mutable_token_state(&self, token_index: TokenIndex) -> MutableTokenState;
40+
41+
/// Get the configuration of a protocol-level token.
42+
///
43+
/// # Arguments
44+
///
45+
/// - `token_index` The index of the token to get the config for.
46+
///
47+
/// # Panics
48+
///
49+
/// Panics if the token identified by `token_index` does not exist.
50+
fn get_token_configuration(&self, token_index: TokenIndex) -> PLTConfiguration;
51+
52+
/// Get the circulating supply of a protocol-level token.
53+
///
54+
/// # Arguments
55+
///
56+
/// - `token_index` The index of the token to get the circulating supply.
57+
///
58+
/// # Panics
59+
///
60+
/// Panics if the token identified by `token_index` does not exist.
61+
fn get_token_circulating_supply(&self, token_index: TokenIndex) -> TokenRawAmount;
62+
63+
/// Set the recorded total circulating supply for a protocol-level token.
64+
///
65+
/// This should always be kept up-to-date with the total balance held in accounts.
66+
///
67+
/// # Arguments
68+
///
69+
/// - `token_index` The token index to update.
70+
/// - `circulation_supply` The new total circulating supply for the token.
71+
///
72+
/// # Panics
73+
///
74+
/// Panics if the token identified by `token_index` does not exist.
75+
fn set_token_circulating_supply(
76+
&mut self,
77+
token_index: TokenIndex,
78+
circulating_supply: TokenRawAmount,
79+
);
80+
81+
/// Create a new token with the given configuration. The initial state will be empty
82+
/// and the initial supply will be 0. Returns the token index and the updated state.
83+
///
84+
/// # Arguments
85+
///
86+
/// - `configuration` The configuration for the token.
87+
///
88+
/// # Preconditions
89+
///
90+
/// The caller must ensure the following conditions are true, and failing to do so results in
91+
/// undefined behavior.
92+
///
93+
/// - The `token_id` of the given configuration MUST NOT already be in use by a protocol-level
94+
/// token, i.e. `assert_eq!(s.get_token_index(configuration.token_id), None)`.
95+
/// - The [`PLTConfiguration`] MUST be valid and in particular the 'governance_account_index'
96+
/// MUST reference a valid account.
97+
fn create_token(&mut self, configuration: PLTConfiguration) -> TokenIndex;
98+
99+
/// Update the token balance of an account.
100+
///
101+
/// # Arguments
102+
///
103+
/// - `token_index` The token index to update.
104+
/// - `account_index` The account to update.
105+
/// - `amount_delta` The token balance delta.
106+
///
107+
/// # Errors
108+
///
109+
/// - [`OverflowError`] The update would overflow or underflow the token balance on the account.
110+
///
111+
/// # Panics
112+
///
113+
/// Panics if the token identified by `token_index` does not exist.
114+
fn update_token_account_balance(
115+
&mut self,
116+
token_index: TokenIndex,
117+
account_index: AccountIndex,
118+
amount_delta: TokenAmountDelta,
119+
) -> Result<(), OverflowError>;
120+
121+
/// Touch the token account. This initializes a token account state with a
122+
/// balance of zero. This only affects an account if its state for the token
123+
/// is empty.
124+
///
125+
/// Returns `false`, if the account already contained a token account state.
126+
///
127+
/// # Arguments
128+
///
129+
/// - `token_index` The token index to update.
130+
/// - `account_index` The account to update.
131+
///
132+
/// # Panics
133+
///
134+
/// Panics if:
135+
///
136+
/// - the token identified by `token_index` does not exist.
137+
/// - the account identified by `account_index` does not exist.
138+
#[must_use]
139+
fn touch_token_account(&mut self, token_index: TokenIndex, account_index: AccountIndex)
140+
-> bool;
141+
142+
/// Increment the update sequence number for Protocol Level Tokens (PLT).
143+
///
144+
/// Unlike the other chain updates this is a separate function, since there is no queue associated with PLTs.
145+
fn increment_plt_update_sequence_number(&mut self);
146+
147+
/// Convert a mutable state to a persistent one and store it in the block state.
148+
///
149+
/// To ensure this is future-proof, the mutable state should not be used after this call.
150+
///
151+
/// # Arguments
152+
///
153+
/// - `token_index` The token index to update.
154+
/// - `mutable_token_state` The mutated state to set as the current token state.
155+
///
156+
/// # Panics
157+
///
158+
/// Panics if the token identified by `token_index` does not exist.
159+
fn set_token_state(&mut self, token_index: TokenIndex, mutable_token_state: MutableTokenState);
160+
}
161+
162+
/// The computation resulted in overflow.
163+
#[derive(Debug)]
164+
pub struct OverflowError;

0 commit comments

Comments
 (0)