mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Properly define the core pallet instead of placing it within the runtime
This commit is contained in:
23
.github/workflows/tests.yml
vendored
23
.github/workflows/tests.yml
vendored
@@ -83,21 +83,16 @@ jobs:
|
||||
run: |
|
||||
GITHUB_CI=true RUST_BACKTRACE=1 cargo test --all-features \
|
||||
-p serai-primitives \
|
||||
-p serai-coins-primitives \
|
||||
-p serai-coins-pallet \
|
||||
-p serai-dex-pallet \
|
||||
-p serai-validator-sets-primitives \
|
||||
-p serai-validator-sets-pallet \
|
||||
-p serai-genesis-liquidity-primitives \
|
||||
-p serai-genesis-liquidity-pallet \
|
||||
-p serai-emissions-primitives \
|
||||
-p serai-emissions-pallet \
|
||||
-p serai-economic-security-pallet \
|
||||
-p serai-in-instructions-primitives \
|
||||
-p serai-in-instructions-pallet \
|
||||
-p serai-signals-primitives \
|
||||
-p serai-signals-pallet \
|
||||
-p serai-abi \
|
||||
-p serai-core-pallet \
|
||||
-p serai-coins-pallet \
|
||||
-p serai-validator-sets-pallet \
|
||||
-p serai-signals-pallet \
|
||||
-p serai-dex-pallet \
|
||||
-p serai-genesis-liquidity-pallet \
|
||||
-p serai-economic-security-pallet \
|
||||
-p serai-emissions-pallet \
|
||||
-p serai-in-instructions-pallet \
|
||||
-p serai-runtime \
|
||||
-p serai-node
|
||||
|
||||
|
||||
69
Cargo.lock
generated
69
Cargo.lock
generated
@@ -101,9 +101,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "alloy-chains"
|
||||
version = "0.2.9"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef8ff73a143281cb77c32006b04af9c047a6b8fe5860e85a88ad325328965355"
|
||||
checksum = "f3008b4f680adca5a81fad5f6cdbb561cca0cee7e97050756c2c1f3e41d2103c"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"num_enum",
|
||||
@@ -197,9 +197,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-eips"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cd749c57f38f8cbf433e651179fc5a676255e6b95044f467d49255d2b81725a"
|
||||
checksum = "2a33d1723ecf64166c2a0371e25d1bce293b873527a7617688c9375384098ea1"
|
||||
dependencies = [
|
||||
"alloy-eip2124",
|
||||
"alloy-eip2930",
|
||||
@@ -219,9 +219,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-genesis"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d32cbf6c26d7d87e8a4e5925bbce41456e0bbeed95601add3443af277cd604e"
|
||||
checksum = "3865dd77a0fcbe61a35f08171af54d54617372df0544d7626f9ee5a42103c825"
|
||||
dependencies = [
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
@@ -257,9 +257,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-json-rpc"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f614019a029c8fec14ae661aa7d4302e6e66bdbfb869dab40e78dcfba935fc97"
|
||||
checksum = "d24aba9adc7e22cec5ae396980cac73792f5cb5407dc1efc07292e7f96fb65d5"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-sol-types",
|
||||
@@ -419,9 +419,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-rpc-client"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33732242ca63f107f5f8284190244038905fb233280f4b7c41f641d4f584d40d"
|
||||
checksum = "bca26070f1fc94d69e8d41fcde991b0556dbf8fac737dc09102d461d957a1bb9"
|
||||
dependencies = [
|
||||
"alloy-json-rpc",
|
||||
"alloy-primitives",
|
||||
@@ -450,9 +450,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-rpc-types-debug"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d46cb226f1c8071875f4d0d8a0eb3ac571fcc49cd3bcdc20a5818de7b6ef0634"
|
||||
checksum = "01289dae0aa187f76bb964f3fa2dcd86e70de033f3f048caddf677066e8f47e7"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"derive_more 2.0.1",
|
||||
@@ -497,9 +497,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-serde"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04dfe41a47805a34b848c83448946ca96f3d36842e8c074bcf8fa0870e337d12"
|
||||
checksum = "5f0ee5af728e144e0e5bde52114c7052249a9833d9fba79aeacfbdee1aad69e8"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"serde",
|
||||
@@ -508,9 +508,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-signer"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f79237b4c1b0934d5869deea4a54e6f0a7425a8cd943a739d6293afdf893d847"
|
||||
checksum = "0efbce76baf1b012e379a5e486822c71b0de0a957ddedd5410427789516a47b9"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"async-trait",
|
||||
@@ -620,9 +620,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alloy-transport"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb43750e137fe3a69a325cd89a8f8e2bbf4f83e70c0f60fbe49f22511ca075e8"
|
||||
checksum = "7200a72ccda236bc841df56964b1f816f451e317b172538ba3977357e789b8bd"
|
||||
dependencies = [
|
||||
"alloy-json-rpc",
|
||||
"alloy-primitives",
|
||||
@@ -732,9 +732,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.99"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
@@ -1501,9 +1501,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "blst"
|
||||
version = "0.3.15"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080"
|
||||
checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"glob",
|
||||
@@ -6029,7 +6029,7 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
|
||||
dependencies = [
|
||||
"proc-macro-crate 1.1.3",
|
||||
"proc-macro-crate 3.3.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
@@ -7556,9 +7556,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.31"
|
||||
version = "0.23.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
|
||||
checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"ring",
|
||||
@@ -9019,6 +9019,19 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serai-core-pallet"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"borsh",
|
||||
"frame-support",
|
||||
"frame-system",
|
||||
"parity-scale-codec",
|
||||
"serai-abi",
|
||||
"sp-core",
|
||||
"sp-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serai-cosign"
|
||||
version = "0.1.0"
|
||||
@@ -9691,6 +9704,7 @@ dependencies = [
|
||||
"parity-scale-codec",
|
||||
"serai-abi",
|
||||
"serai-coins-pallet",
|
||||
"serai-core-pallet",
|
||||
"serai-signals-pallet",
|
||||
"serai-validator-sets-pallet",
|
||||
"sp-api",
|
||||
@@ -11070,11 +11084,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.43"
|
||||
version = "0.3.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031"
|
||||
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
|
||||
@@ -84,6 +84,7 @@ members = [
|
||||
"substrate/primitives",
|
||||
"substrate/abi",
|
||||
|
||||
"substrate/core",
|
||||
"substrate/coins",
|
||||
"substrate/validator-sets",
|
||||
"substrate/signals",
|
||||
|
||||
@@ -79,6 +79,7 @@ exceptions = [
|
||||
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-libp2p-p2p" },
|
||||
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator" },
|
||||
|
||||
{ allow = ["AGPL-3.0-only"], name = "serai-core-pallet" },
|
||||
{ allow = ["AGPL-3.0-only"], name = "serai-coins-pallet" },
|
||||
{ allow = ["AGPL-3.0-only"], name = "serai-dex-pallet" },
|
||||
|
||||
|
||||
@@ -297,6 +297,8 @@ mod substrate {
|
||||
/// Begin execution of a transaction.
|
||||
fn start_transaction(&self);
|
||||
/// Consume the next nonce for an account.
|
||||
///
|
||||
/// This MUST NOT be called if the next nonce is `u32::MAX`. The caller MAY panic in that case.
|
||||
fn consume_next_nonce(&self, signer: &SeraiAddress);
|
||||
/// Have the transaction pay its SRI fee.
|
||||
fn pay_fee(&self, signer: &SeraiAddress, fee: Amount) -> Result<(), TransactionValidityError>;
|
||||
@@ -425,13 +427,20 @@ mod substrate {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?;
|
||||
}
|
||||
}
|
||||
match self.1.next_nonce(signer).cmp(nonce) {
|
||||
core::cmp::Ordering::Less => {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?
|
||||
|
||||
{
|
||||
let next_nonce = self.1.next_nonce(signer);
|
||||
if next_nonce == u32::MAX {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::BadSigner))?;
|
||||
}
|
||||
core::cmp::Ordering::Equal => {}
|
||||
core::cmp::Ordering::Greater => {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Future))?
|
||||
match next_nonce.cmp(nonce) {
|
||||
core::cmp::Ordering::Less => {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))?
|
||||
}
|
||||
core::cmp::Ordering::Equal => {}
|
||||
core::cmp::Ordering::Greater => {
|
||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Future))?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
56
substrate/core/Cargo.toml
Normal file
56
substrate/core/Cargo.toml
Normal file
@@ -0,0 +1,56 @@
|
||||
[package]
|
||||
name = "serai-core-pallet"
|
||||
version = "0.1.0"
|
||||
description = "Core pallet"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/core"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.85"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["scale"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"] }
|
||||
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||
|
||||
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
sp-io = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
|
||||
frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
|
||||
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
"borsh/std",
|
||||
"scale/std",
|
||||
|
||||
"sp-core/std",
|
||||
"sp-io/std",
|
||||
|
||||
"frame-system/std",
|
||||
"frame-support/std",
|
||||
|
||||
"serai-abi/std",
|
||||
]
|
||||
|
||||
runtime-benchmarks = [
|
||||
"frame-system/runtime-benchmarks",
|
||||
"frame-support/runtime-benchmarks",
|
||||
]
|
||||
|
||||
# TODO
|
||||
try-runtime = []
|
||||
|
||||
default = ["std"]
|
||||
15
substrate/core/LICENSE
Normal file
15
substrate/core/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
AGPL-3.0-only license
|
||||
|
||||
Copyright (c) 2023-2025 Luke Parker
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License Version 3 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
1
substrate/core/README.md
Normal file
1
substrate/core/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# Serai Core Pallet
|
||||
52
substrate/core/src/iumt.rs
Normal file
52
substrate/core/src/iumt.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use borsh::BorshSerialize;
|
||||
|
||||
use serai_abi::primitives::merkle::{UnbalancedMerkleTree, IncrementalUnbalancedMerkleTree as Iumt};
|
||||
|
||||
/// A wrapper around a `StorageValue` which offers a high-level API as an
|
||||
/// `IncrementalUnbalancedMerkleTree`.
|
||||
pub struct IncrementalUnbalancedMerkleTree<
|
||||
T: frame_support::StorageValue<Iumt, Query = Option<Iumt>>,
|
||||
const BRANCH_TAG: u8 = 1,
|
||||
const LEAF_TAG: u8 = 0,
|
||||
>(PhantomData<T>);
|
||||
impl<
|
||||
T: frame_support::StorageValue<Iumt, Query = Option<Iumt>>,
|
||||
const BRANCH_TAG: u8,
|
||||
const LEAF_TAG: u8,
|
||||
> IncrementalUnbalancedMerkleTree<T, BRANCH_TAG, LEAF_TAG>
|
||||
{
|
||||
/// Create a new Merkle tree, expecting there to be none already present.
|
||||
///
|
||||
/// Panics if a Merkle tree was already present.
|
||||
pub fn new_expecting_none() {
|
||||
T::mutate(|value| {
|
||||
assert!(value.is_none());
|
||||
*value = Some(Iumt::new());
|
||||
});
|
||||
}
|
||||
/// Append a leaf to the Merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
pub fn append<L: BorshSerialize>(leaf: &L) {
|
||||
let leaf = sp_core::blake2_256(&borsh::to_vec(&(LEAF_TAG, leaf)).unwrap());
|
||||
|
||||
T::mutate(|value| {
|
||||
let tree = value.as_mut().unwrap();
|
||||
tree.append(BRANCH_TAG, leaf);
|
||||
})
|
||||
}
|
||||
/// Get the unbalanced merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
pub fn get() -> UnbalancedMerkleTree {
|
||||
T::get().unwrap().calculate(BRANCH_TAG)
|
||||
}
|
||||
/// Take the Merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
pub fn take() -> UnbalancedMerkleTree {
|
||||
T::mutate(|value| value.take().unwrap().calculate(BRANCH_TAG))
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,19 @@
|
||||
use core::marker::PhantomData;
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use borsh::BorshSerialize;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use frame_support::pallet_prelude::*;
|
||||
|
||||
use serai_abi::{
|
||||
primitives::merkle::{UnbalancedMerkleTree, IncrementalUnbalancedMerkleTree as Iumt},
|
||||
primitives::{prelude::*, merkle::IncrementalUnbalancedMerkleTree as Iumt},
|
||||
*,
|
||||
};
|
||||
|
||||
/// A wrapper around a `StorageValue` which offers a high-level API as an IUMT.
|
||||
struct IncrementalUnbalancedMerkleTree<
|
||||
T: frame_support::StorageValue<Iumt, Query = Option<Iumt>>,
|
||||
const BRANCH_TAG: u8 = 1,
|
||||
const LEAF_TAG: u8 = 0,
|
||||
>(PhantomData<T>);
|
||||
impl<
|
||||
T: frame_support::StorageValue<Iumt, Query = Option<Iumt>>,
|
||||
const BRANCH_TAG: u8,
|
||||
const LEAF_TAG: u8,
|
||||
> IncrementalUnbalancedMerkleTree<T, BRANCH_TAG, LEAF_TAG>
|
||||
{
|
||||
/// Create a new Merkle tree, expecting there to be none already present.
|
||||
///
|
||||
/// Panics if a Merkle tree was already present.
|
||||
fn new_expecting_none() {
|
||||
T::mutate(|value| {
|
||||
assert!(value.is_none());
|
||||
*value = Some(Iumt::new());
|
||||
});
|
||||
}
|
||||
/// Append a leaf to the Merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
fn append<L: BorshSerialize>(leaf: &L) {
|
||||
let leaf = sp_core::blake2_256(&borsh::to_vec(&(LEAF_TAG, leaf)).unwrap());
|
||||
|
||||
T::mutate(|value| {
|
||||
let tree = value.as_mut().unwrap();
|
||||
tree.append(BRANCH_TAG, leaf);
|
||||
})
|
||||
}
|
||||
/// Get the unbalanced merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
fn get() -> UnbalancedMerkleTree {
|
||||
T::get().unwrap().calculate(BRANCH_TAG)
|
||||
}
|
||||
/// Take the Merkle tree.
|
||||
///
|
||||
/// Panics if no Merkle tree was present.
|
||||
fn take() -> UnbalancedMerkleTree {
|
||||
T::mutate(|value| value.take().unwrap().calculate(BRANCH_TAG))
|
||||
}
|
||||
}
|
||||
mod iumt;
|
||||
pub use iumt::*;
|
||||
|
||||
#[frame_support::pallet]
|
||||
mod pallet {
|
||||
@@ -61,7 +21,7 @@ mod pallet {
|
||||
|
||||
/// The set of all blocks prior added to the blockchain.
|
||||
#[pallet::storage]
|
||||
pub type Blocks<T: Config> = StorageMap<_, Identity, T::Hash, (), OptionQuery>;
|
||||
pub(super) type Blocks<T: Config> = StorageMap<_, Identity, T::Hash, (), OptionQuery>;
|
||||
/// The Merkle tree of all blocks added to the blockchain.
|
||||
#[pallet::storage]
|
||||
#[pallet::unbounded]
|
||||
@@ -96,8 +56,7 @@ mod pallet {
|
||||
|
||||
/// A mapping from an account to its next nonce.
|
||||
#[pallet::storage]
|
||||
pub type NextNonce<T: Config> =
|
||||
StorageMap<_, Blake2_128Concat, T::AccountId, T::Nonce, ValueQuery>;
|
||||
type NextNonce<T: Config> = StorageMap<_, Blake2_128Concat, SeraiAddress, T::Nonce, ValueQuery>;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config<Hash: Into<[u8; 32]>> {}
|
||||
@@ -106,15 +65,43 @@ mod pallet {
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// If a block exists on the current blockchain.
|
||||
#[must_use]
|
||||
pub fn block_exists(hash: impl scale::EncodeLike<T::Hash>) -> bool {
|
||||
Blocks::<T>::contains_key(hash)
|
||||
}
|
||||
|
||||
/// The next nonce for an account.
|
||||
#[must_use]
|
||||
pub fn next_nonce(account: &SeraiAddress) -> T::Nonce {
|
||||
NextNonce::<T>::get(account)
|
||||
}
|
||||
|
||||
/// Consume the next nonce for an account.
|
||||
///
|
||||
/// Panics if the current nonce is `<_>::MAX`.
|
||||
pub fn consume_next_nonce(signer: &SeraiAddress) {
|
||||
NextNonce::<T>::mutate(signer, |value| {
|
||||
*value = value
|
||||
.checked_add(&T::Nonce::one())
|
||||
.expect("`consume_next_nonce` called when current nonce is <_>::MAX")
|
||||
});
|
||||
}
|
||||
|
||||
/// The code to run when beginning execution of a transaction.
|
||||
///
|
||||
/// The caller MUST ensure two transactions aren't simultaneously started.
|
||||
pub fn start_transaction() {
|
||||
TransactionEventsMerkle::<T>::new_expecting_none();
|
||||
}
|
||||
/// Emit an event.
|
||||
// TODO: Have this called
|
||||
pub fn on_event(event: impl TryInto<serai_abi::Event>) {
|
||||
pub fn emit_event(event: impl TryInto<serai_abi::Event>) {
|
||||
if let Ok(event) = event.try_into() {
|
||||
TransactionEventsMerkle::<T>::append(&event);
|
||||
}
|
||||
}
|
||||
/// End execution of a transaction.
|
||||
pub fn end_transaction(transaction_hash: [u8; 32]) {
|
||||
BlockTransactionsCommitmentMerkle::<T>::append(&transaction_hash);
|
||||
|
||||
@@ -126,8 +113,9 @@ mod pallet {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(super) use pallet::*;
|
||||
pub use pallet::*;
|
||||
|
||||
/// The code to run at the start of a block for this pallet.
|
||||
pub struct StartOfBlock<T: Config>(PhantomData<T>);
|
||||
impl<T: Config> frame_support::traits::PreInherents for StartOfBlock<T> {
|
||||
fn pre_inherents() {
|
||||
@@ -145,17 +133,20 @@ impl<T: Config> frame_support::traits::PreInherents for StartOfBlock<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The code to run at the end of a block for this pallet.
|
||||
pub struct EndOfBlock<T: Config>(PhantomData<T>);
|
||||
impl<T: Config> frame_support::traits::PostTransactions for EndOfBlock<T> {
|
||||
fn post_transactions() {
|
||||
frame_system::Pallet::<T>::deposit_log(sp_runtime::generic::DigestItem::Consensus(
|
||||
SeraiExecutionDigest::CONSENSUS_ID,
|
||||
borsh::to_vec(&SeraiExecutionDigest {
|
||||
builds_upon: BlocksCommitmentMerkle::<T>::get(),
|
||||
transactions_commitment: BlockTransactionsCommitmentMerkle::<T>::take(),
|
||||
events_commitment: BlockEventsCommitmentMerkle::<T>::take(),
|
||||
})
|
||||
.unwrap(),
|
||||
));
|
||||
frame_system::Pallet::<T>::deposit_log(
|
||||
frame_support::sp_runtime::generic::DigestItem::Consensus(
|
||||
SeraiExecutionDigest::CONSENSUS_ID,
|
||||
borsh::to_vec(&SeraiExecutionDigest {
|
||||
builds_upon: BlocksCommitmentMerkle::<T>::get(),
|
||||
transactions_commitment: BlockTransactionsCommitmentMerkle::<T>::take(),
|
||||
events_commitment: BlockEventsCommitmentMerkle::<T>::take(),
|
||||
})
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ frame-system = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev =
|
||||
frame-support = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
frame-executive = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "d4624c561765c13b38eb566e435131a8c329a543", default-features = false }
|
||||
|
||||
serai-core-pallet = { path = "../core", default-features = false }
|
||||
serai-coins-pallet = { path = "../coins", default-features = false }
|
||||
serai-validator-sets-pallet = { path = "../validator-sets", default-features = false }
|
||||
serai-signals-pallet = { path = "../signals", default-features = false }
|
||||
@@ -42,6 +43,7 @@ substrate-wasm-builder = { git = "https://github.com/serai-dex/patch-polkadot-sd
|
||||
|
||||
[features]
|
||||
std = [
|
||||
"borsh/std",
|
||||
"scale/std",
|
||||
|
||||
"sp-core/std",
|
||||
@@ -55,6 +57,7 @@ std = [
|
||||
"frame-support/std",
|
||||
"frame-executive/std",
|
||||
|
||||
"serai-core-pallet/std",
|
||||
"serai-coins-pallet/std",
|
||||
"serai-validator-sets-pallet/std",
|
||||
"serai-signals-pallet/std",
|
||||
@@ -69,6 +72,7 @@ try-runtime = [
|
||||
"frame-support/try-runtime",
|
||||
"frame-executive/try-runtime",
|
||||
|
||||
"serai-core-pallet/try-runtime",
|
||||
"serai-coins-pallet/try-runtime",
|
||||
"serai-validator-sets-pallet/try-runtime",
|
||||
"serai-signals-pallet/try-runtime",
|
||||
@@ -80,6 +84,8 @@ runtime-benchmarks = [
|
||||
"frame-system/runtime-benchmarks",
|
||||
"frame-support/runtime-benchmarks",
|
||||
|
||||
"serai-core-pallet/runtime-benchmarks",
|
||||
"serai-coins-pallet/runtime-benchmarks",
|
||||
"serai-validator-sets-pallet/runtime-benchmarks",
|
||||
"serai-signals-pallet/runtime-benchmarks",
|
||||
]
|
||||
|
||||
@@ -9,7 +9,7 @@ extern crate alloc;
|
||||
use alloc::borrow::Cow;
|
||||
|
||||
use sp_core::sr25519::Public;
|
||||
use sp_runtime::{Perbill, Weight, traits::Header as _};
|
||||
use sp_runtime::{Perbill, Weight};
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
#[rustfmt::skip]
|
||||
@@ -19,8 +19,6 @@ use serai_abi::{
|
||||
|
||||
use serai_coins_pallet::{CoinsInstance, LiquidityTokensInstance};
|
||||
|
||||
mod core_pallet;
|
||||
|
||||
type Block = SubstrateBlock;
|
||||
|
||||
/// The lookup for a SeraiAddress -> Public.
|
||||
@@ -75,7 +73,7 @@ mod runtime {
|
||||
pub type System = frame_system::Pallet<Runtime>;
|
||||
|
||||
#[runtime::pallet_index(1)]
|
||||
pub type Core = core_pallet::Pallet<Runtime>;
|
||||
pub type Core = serai_core_pallet::Pallet<Runtime>;
|
||||
|
||||
#[runtime::pallet_index(2)]
|
||||
pub type Coins = serai_coins_pallet::Pallet<Runtime, CoinsInstance>;
|
||||
@@ -125,12 +123,12 @@ impl frame_system::Config for Runtime {
|
||||
type SingleBlockMigrations = ();
|
||||
type MultiBlockMigrator = ();
|
||||
|
||||
type PreInherents = core_pallet::StartOfBlock<Runtime>;
|
||||
type PreInherents = serai_core_pallet::StartOfBlock<Runtime>;
|
||||
type PostInherents = ();
|
||||
type PostTransactions = core_pallet::EndOfBlock<Runtime>;
|
||||
type PostTransactions = serai_core_pallet::EndOfBlock<Runtime>;
|
||||
}
|
||||
|
||||
impl core_pallet::Config for Runtime {}
|
||||
impl serai_core_pallet::Config for Runtime {}
|
||||
|
||||
impl serai_coins_pallet::Config<CoinsInstance> for Runtime {
|
||||
type AllowMint = serai_coins_pallet::AlwaysAllowMint; // TODO
|
||||
@@ -230,7 +228,6 @@ sp_api::impl_runtime_apis! {
|
||||
VERSION
|
||||
}
|
||||
fn initialize_block(header: &Header) -> sp_runtime::ExtrinsicInclusionMode {
|
||||
core_pallet::Blocks::<Runtime>::set(header.parent_hash(), Some(()));
|
||||
Executive::initialize_block(header)
|
||||
}
|
||||
fn execute_block(block: Block) {
|
||||
@@ -257,7 +254,7 @@ impl serai_abi::TransactionContext for Context {
|
||||
|
||||
/// If a block is present in the blockchain.
|
||||
fn block_is_present_in_blockchain(&self, hash: &serai_abi::primitives::BlockHash) -> bool {
|
||||
core_pallet::Blocks::<Runtime>::get(hash).is_some()
|
||||
serai_core_pallet::Pallet::<Runtime>::block_exists(hash)
|
||||
}
|
||||
/// The time embedded into the current block.
|
||||
fn current_time(&self) -> Option<u64> {
|
||||
@@ -265,7 +262,7 @@ impl serai_abi::TransactionContext for Context {
|
||||
}
|
||||
/// Get the next nonce for an account.
|
||||
fn next_nonce(&self, signer: &SeraiAddress) -> u32 {
|
||||
core_pallet::NextNonce::<Runtime>::get(signer)
|
||||
serai_core_pallet::Pallet::<Runtime>::next_nonce(signer)
|
||||
}
|
||||
/// If the signer can pay the SRI fee.
|
||||
fn can_pay_fee(
|
||||
@@ -284,11 +281,10 @@ impl serai_abi::TransactionContext for Context {
|
||||
}
|
||||
|
||||
fn start_transaction(&self) {
|
||||
Core::start_transaction();
|
||||
Core::start_transaction()
|
||||
}
|
||||
/// Consume the next nonce for an account.
|
||||
fn consume_next_nonce(&self, signer: &SeraiAddress) {
|
||||
core_pallet::NextNonce::<Runtime>::mutate(signer, |value| *value += 1);
|
||||
serai_core_pallet::Pallet::<Runtime>::consume_next_nonce(signer)
|
||||
}
|
||||
/// Have the transaction pay its SRI fee.
|
||||
fn pay_fee(
|
||||
|
||||
Reference in New Issue
Block a user