5 Commits

Author SHA1 Message Date
Luke Parker
1a766ab773 Populate UnbalancedMerkleTrees in headers 2025-03-04 06:00:06 -05:00
Luke Parker
df2ae10d2f Add an UnbalancedMerkleTree primitive
The reasoning for it is documented with itself. The plan is to use it within
our header for committing to the DAG (allowing one header per epoch, yet
logarithmic proofs for any header within the epoch), the transactions
commitment (allowing logarithmic proofs of a transaction within a block,
without padding), and the events commitment (allowing logarithmic proofs of
unique events within a block, despite events not having a unique ID inherent).

This also defines transaction hashes and performs the necessary modifications
for transactions to be unique.
2025-03-04 04:00:05 -05:00
Luke Parker
b92ac4a15b Use borsh entirely in create_db 2025-02-26 14:50:59 -05:00
Luke Parker
51bae4fedc Remove now-consolidated primitives crates 2025-02-26 14:49:28 -05:00
Luke Parker
ee8b353132 Skeleton ruintime with new types 2025-02-26 14:16:04 -05:00
92 changed files with 957 additions and 1322 deletions

View File

@@ -26,7 +26,7 @@ jobs:
uses: ./.github/actions/build-dependencies uses: ./.github/actions/build-dependencies
- name: Install nightly rust - name: Install nightly rust
run: rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32-unknown-unknown -c rust-src -c clippy run: rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasmv1-none -c clippy
- name: Run Clippy - name: Run Clippy
run: cargo +${{ steps.nightly.outputs.version }} clippy --all-features --all-targets -- -D warnings -A clippy::items_after_test_module run: cargo +${{ steps.nightly.outputs.version }} clippy --all-features --all-targets -- -D warnings -A clippy::items_after_test_module

View File

@@ -69,7 +69,7 @@ jobs:
uses: ./.github/actions/build-dependencies uses: ./.github/actions/build-dependencies
- name: Buld Rust docs - name: Buld Rust docs
run: | run: |
rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32-unknown-unknown -c rust-docs rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasmv1-none -c rust-docs
RUSTDOCFLAGS="--cfg docsrs" cargo +${{ steps.nightly.outputs.version }} doc --workspace --all-features RUSTDOCFLAGS="--cfg docsrs" cargo +${{ steps.nightly.outputs.version }} doc --workspace --all-features
mv target/doc docs/_site/rust mv target/doc docs/_site/rust

316
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -103,31 +103,17 @@ members = [
"coordinator", "coordinator",
"substrate/primitives", "substrate/primitives",
"substrate/coins/primitives",
"substrate/coins/pallet",
"substrate/dex/pallet",
"substrate/validator-sets/primitives",
"substrate/validator-sets/pallet",
"substrate/genesis-liquidity/primitives",
"substrate/genesis-liquidity/pallet",
"substrate/emissions/primitives",
"substrate/emissions/pallet",
"substrate/economic-security/pallet",
"substrate/in-instructions/primitives",
"substrate/in-instructions/pallet",
"substrate/signals/primitives",
"substrate/signals/pallet",
"substrate/abi", "substrate/abi",
"substrate/coins",
"substrate/validator-sets",
"substrate/signals",
"substrate/dex",
"substrate/genesis-liquidity",
"substrate/economic-security",
"substrate/emissions",
"substrate/in-instructions",
"substrate/runtime", "substrate/runtime",
"substrate/node", "substrate/node",

View File

@@ -15,7 +15,7 @@ pub fn serai_db_key(
/// ///
/// Creates a unit struct and a default implementation for the `key`, `get`, and `set`. The macro /// Creates a unit struct and a default implementation for the `key`, `get`, and `set`. The macro
/// uses a syntax similar to defining a function. Parameters are concatenated to produce a key, /// uses a syntax similar to defining a function. Parameters are concatenated to produce a key,
/// they must be `scale` encodable. The return type is used to auto encode and decode the database /// they must be `borsh` serializable. The return type is used to auto (de)serialize the database
/// value bytes using `borsh`. /// value bytes using `borsh`.
/// ///
/// # Arguments /// # Arguments
@@ -54,11 +54,10 @@ macro_rules! create_db {
)?; )?;
impl$(<$($generic_name: $generic_type),+>)? $field_name$(<$($generic_name),+>)? { impl$(<$($generic_name: $generic_type),+>)? $field_name$(<$($generic_name),+>)? {
pub(crate) fn key($($arg: $arg_type),*) -> Vec<u8> { pub(crate) fn key($($arg: $arg_type),*) -> Vec<u8> {
use scale::Encode;
$crate::serai_db_key( $crate::serai_db_key(
stringify!($db_name).as_bytes(), stringify!($db_name).as_bytes(),
stringify!($field_name).as_bytes(), stringify!($field_name).as_bytes(),
($($arg),*).encode() &borsh::to_vec(&($($arg),*)).unwrap(),
) )
} }
pub(crate) fn set( pub(crate) fn set(

View File

@@ -42,7 +42,7 @@ messages = { package = "serai-processor-messages", path = "../processor/messages
message-queue = { package = "serai-message-queue", path = "../message-queue" } message-queue = { package = "serai-message-queue", path = "../message-queue" }
tributary-sdk = { path = "./tributary-sdk" } tributary-sdk = { path = "./tributary-sdk" }
serai-client = { path = "../substrate/client", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../substrate/client", default-features = false, features = ["serai"] }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }
env_logger = { version = "0.10", default-features = false, features = ["humantime"] } env_logger = { version = "0.10", default-features = false, features = ["humantime"] }

View File

@@ -23,7 +23,7 @@ schnorrkel = { version = "0.11", default-features = false, features = ["std"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std", "derive"] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std", "derive"] }
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
serai-client = { path = "../../substrate/client", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../../substrate/client", default-features = false, features = ["serai"] }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }

View File

@@ -22,7 +22,7 @@ borsh = { version = "1", default-features = false, features = ["std", "derive",
serai-db = { path = "../../common/db", version = "0.1" } serai-db = { path = "../../common/db", version = "0.1" }
serai-client = { path = "../../substrate/client", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../../substrate/client", default-features = false, features = ["serai"] }
serai-cosign = { path = "../cosign" } serai-cosign = { path = "../cosign" }
tributary-sdk = { path = "../tributary-sdk" } tributary-sdk = { path = "../tributary-sdk" }

View File

@@ -29,7 +29,7 @@ schnorrkel = { version = "0.11", default-features = false, features = ["std"] }
hex = { version = "0.4", default-features = false, features = ["std"] } hex = { version = "0.4", default-features = false, features = ["std"] }
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
serai-client = { path = "../../../substrate/client", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../../../substrate/client", default-features = false, features = ["serai"] }
serai-cosign = { path = "../../cosign" } serai-cosign = { path = "../../cosign" }
tributary-sdk = { path = "../../tributary-sdk" } tributary-sdk = { path = "../../tributary-sdk" }

View File

@@ -25,7 +25,7 @@ borsh = { version = "1", default-features = false, features = ["std", "derive",
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] } dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] }
serai-client = { path = "../../substrate/client", version = "0.1", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../../substrate/client", version = "0.1", default-features = false, features = ["serai"] }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }

View File

@@ -29,7 +29,7 @@ ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, fea
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] } dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] }
schnorr = { package = "schnorr-signatures", path = "../../crypto/schnorr", default-features = false, features = ["std"] } schnorr = { package = "schnorr-signatures", path = "../../crypto/schnorr", default-features = false, features = ["std"] }
serai-client = { path = "../../substrate/client", default-features = false, features = ["serai", "borsh"] } serai-client = { path = "../../substrate/client", default-features = false, features = ["serai"] }
serai-db = { path = "../../common/db" } serai-db = { path = "../../common/db" }
serai-task = { path = "../../common/task", version = "0.1" } serai-task = { path = "../../common/task", version = "0.1" }

View File

@@ -46,7 +46,7 @@ serai-db = { path = "../common/db", optional = true }
serai-env = { path = "../common/env" } serai-env = { path = "../common/env" }
serai-primitives = { path = "../substrate/primitives", features = ["borsh"] } serai-primitives = { path = "../substrate/primitives", default-features = false, features = ["std"] }
[features] [features]
parity-db = ["serai-db/parity-db"] parity-db = ["serai-db/parity-db"]

View File

@@ -11,8 +11,7 @@ RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
RUN apt update && apt upgrade && apt install clang -y RUN apt update && apt upgrade && apt install clang -y
# Add the wasm toolchain # Add the wasm toolchain
RUN rustup component add rust-src RUN rustup target add wasmv1-none
RUN rustup target add wasm32-unknown-unknown
FROM deterministic FROM deterministic

View File

@@ -162,8 +162,7 @@ RUN apt install -y pkg-config clang
RUN apt install -y make protobuf-compiler RUN apt install -y make protobuf-compiler
# Add the wasm toolchain # Add the wasm toolchain
RUN rustup component add rust-src RUN rustup target add wasmv1-none
RUN rustup target add wasm32-unknown-unknown
{prelude} {prelude}

View File

@@ -25,7 +25,7 @@ rand_core = { version = "0.6", default-features = false, features = ["std", "get
frost = { package = "modular-frost", path = "../../crypto/frost", version = "^0.8.1", default-features = false } frost = { package = "modular-frost", path = "../../crypto/frost", version = "^0.8.1", default-features = false }
serai-validator-sets-primitives = { path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }

View File

@@ -36,7 +36,7 @@ ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, fea
dkg = { package = "dkg", path = "../../crypto/dkg", default-features = false, features = ["std", "evrf-ristretto"] } dkg = { package = "dkg", path = "../../crypto/dkg", default-features = false, features = ["std", "evrf-ristretto"] }
# Substrate # Substrate
serai-validator-sets-primitives = { path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
# Encoders # Encoders
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }

View File

@@ -25,9 +25,6 @@ borsh = { version = "1", default-features = false, features = ["std", "derive",
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] } dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] }
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std", "borsh"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std", "borsh"] }
coins-primitives = { package = "serai-coins-primitives", path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] }
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std", "borsh"] }
serai-cosign = { path = "../../coordinator/cosign", default-features = false } serai-cosign = { path = "../../coordinator/cosign", default-features = false }

View File

@@ -20,8 +20,7 @@ workspace = true
[dependencies] [dependencies]
group = { version = "0.13", default-features = false } group = { version = "0.13", default-features = false }
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std", "borsh"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }

View File

@@ -36,9 +36,6 @@ serai-db = { path = "../../common/db" }
messages = { package = "serai-processor-messages", path = "../messages" } messages = { package = "serai-processor-messages", path = "../messages" }
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
serai-validator-sets-primitives = { path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std", "borsh"] }
serai-in-instructions-primitives = { path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std", "borsh"] }
serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] }
primitives = { package = "serai-processor-primitives", path = "../primitives" } primitives = { package = "serai-processor-primitives", path = "../primitives" }
scheduler-primitives = { package = "serai-processor-scheduler-primitives", path = "../scheduler/primitives" } scheduler-primitives = { package = "serai-processor-scheduler-primitives", path = "../scheduler/primitives" }

View File

@@ -33,8 +33,6 @@ scale = { package = "parity-scale-codec", version = "3", default-features = fals
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] } borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] } serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
serai-validator-sets-primitives = { path = "../../substrate/validator-sets/primitives", default-features = false, features = ["std"] }
serai-in-instructions-primitives = { path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std"] }
serai-db = { path = "../../common/db" } serai-db = { path = "../../common/db" }
log = { version = "0.4", default-features = false, features = ["std"] } log = { version = "0.4", default-features = false, features = ["std"] }

View File

@@ -1,5 +1,5 @@
[toolchain] [toolchain]
channel = "1.81" channel = "1.85"
targets = ["wasm32-unknown-unknown"] targets = ["wasmv1-none"]
profile = "minimal" profile = "minimal"
components = ["rust-src", "rustfmt", "clippy"] components = ["rustfmt", "clippy"]

View File

@@ -27,9 +27,9 @@ brew install rustup
``` ```
rustup update rustup update
rustup toolchain install stable rustup toolchain install stable
rustup target add wasm32-unknown-unknown rustup target add wasmv1-none
rustup toolchain install nightly rustup toolchain install nightly
rustup target add wasm32-unknown-unknown --toolchain nightly rustup target add wasmv1-none --toolchain nightly
``` ```
### Install Solidity ### Install Solidity

View File

@@ -2,7 +2,20 @@ use alloc::vec::Vec;
use borsh::{BorshSerialize, BorshDeserialize}; use borsh::{BorshSerialize, BorshDeserialize};
use crate::{primitives::BlockHash, Transaction}; use crate::{
primitives::{BlockHash, merkle::UnbalancedMerkleTree},
Transaction,
};
/// The tag for the hash of a transaction's event, forming a leaf of the Merkle tree of its events.
pub const TRANSACTION_EVENTS_COMMITMENT_LEAF_TAG: u8 = 0;
/// The tag for the branch hashes of transaction events.
pub const TRANSACTION_EVENTS_COMMITMENT_BRANCH_TAG: u8 = 1;
/// The tag for the hash of a transaction's hash and its events' Merkle root, forming a leaf of the
/// Merkle tree which is the events commitment.
pub const EVENTS_COMMITMENT_LEAF_TAG: u8 = 2;
/// The tag for for the branch hashes of the Merkle tree which is the events commitments.
pub const EVENTS_COMMITMENT_BRANCH_TAG: u8 = 3;
/// A V1 header for a block. /// A V1 header for a block.
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)] #[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
@@ -12,12 +25,28 @@ pub struct HeaderV1 {
/// The genesis block has number 0. /// The genesis block has number 0.
pub number: u64, pub number: u64,
/// The commitment to the DAG this header builds upon. /// The commitment to the DAG this header builds upon.
pub builds_upon: BlockHash, ///
/// This is defined as an unbalanced Merkle tree so light clients may sync one header per epoch,
/// and then may prove the inclusion of any header in logarithmic depth (without providing the
/// entire header chain).
///
/// Alternative popular options would be a Merkle Mountain Range, which makes more recent blocks
/// cheaper to prove at the sacrifice of older blocks being more expensive to prove. An MMR isn't
/// used in order to minimize the protocol's surface area. Additionally, even though the
/// unbalanced Merkle tree doesn't achieve such notably short paths for recent blocks, it does
/// inherently provide lower-depth paths to more recent items *on imbalance*.
pub builds_upon: UnbalancedMerkleTree,
/// The UNIX time in milliseconds this block was created at. /// The UNIX time in milliseconds this block was created at.
pub unix_time_in_millis: u64, pub unix_time_in_millis: u64,
/// The commitment to the transactions within this block. /// The commitment to the transactions within this block.
// TODO: Some transactions don't have unique hashes due to assuming validators set unique keys pub transactions_commitment: UnbalancedMerkleTree,
pub transactions_commitment: [u8; 32], /// The commitment to the events within this block.
///
/// The leaves of this tree will be of the form
/// `(EVENTS_COMMITMENT_LEAF_TAG, transaction hash, transaction's events' Merkle tree root)`.
/// A transaction may have the same event multiple times, yet an event may be uniquely identified
/// by its path within the tree.
pub events_commitment: UnbalancedMerkleTree,
/// A commitment to the consensus data used to justify adding this block to the blockchain. /// A commitment to the consensus data used to justify adding this block to the blockchain.
pub consensus_commitment: [u8; 32], pub consensus_commitment: [u8; 32],
} }
@@ -37,17 +66,23 @@ impl Header {
} }
} }
/// Get the commitment to the DAG this header builds upon. /// Get the commitment to the DAG this header builds upon.
pub fn builds_upon(&self) -> BlockHash { pub fn builds_upon(&self) -> UnbalancedMerkleTree {
match self { match self {
Header::V1(HeaderV1 { builds_upon, .. }) => *builds_upon, Header::V1(HeaderV1 { builds_upon, .. }) => *builds_upon,
} }
} }
/// The commitment to the transactions within this block. /// The commitment to the transactions within this block.
pub fn transactions_commitment(&self) -> [u8; 32] { pub fn transactions_commitment(&self) -> UnbalancedMerkleTree {
match self { match self {
Header::V1(HeaderV1 { transactions_commitment, .. }) => *transactions_commitment, Header::V1(HeaderV1 { transactions_commitment, .. }) => *transactions_commitment,
} }
} }
/// The commitment to the events within this block.
pub fn events_commitment(&self) -> UnbalancedMerkleTree {
match self {
Header::V1(HeaderV1 { events_commitment, .. }) => *events_commitment,
}
}
/// Get the hash of the header. /// Get the hash of the header.
pub fn hash(&self) -> BlockHash { pub fn hash(&self) -> BlockHash {
BlockHash(sp_core::blake2_256(&borsh::to_vec(self).unwrap())) BlockHash(sp_core::blake2_256(&borsh::to_vec(self).unwrap()))
@@ -81,19 +116,33 @@ mod substrate {
use super::*; use super::*;
/// The digest for all of the Serai-specific header fields. /// The digest for all of the Serai-specific header fields added before execution of the block.
#[derive(Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)] #[derive(Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct SeraiDigest { pub struct SeraiPreExecutionDigest {
/// The commitment to the DAG this header builds upon.
pub builds_upon: BlockHash,
/// The UNIX time in milliseconds this block was created at. /// The UNIX time in milliseconds this block was created at.
pub unix_time_in_millis: u64, pub unix_time_in_millis: u64,
/// The commitment to the transactions within this block.
pub transactions_commitment: [u8; 32],
} }
impl SeraiDigest { /// The digest for all of the Serai-specific header fields determined during execution of the
const CONSENSUS_ID: [u8; 4] = *b"SRID"; /// block.
#[derive(Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct SeraiExecutionDigest {
/// The commitment to the DAG this header builds upon.
pub builds_upon: UnbalancedMerkleTree,
/// The commitment to the transactions within this block.
pub transactions_commitment: UnbalancedMerkleTree,
/// The commitment to the events within this block.
pub events_commitment: UnbalancedMerkleTree,
}
impl SeraiPreExecutionDigest {
/// The consensus ID for a Serai pre-execution digest.
pub const CONSENSUS_ID: [u8; 4] = *b"SRIP";
}
impl SeraiExecutionDigest {
/// The consensus ID for a Serai execution digest.
pub const CONSENSUS_ID: [u8; 4] = *b"SRIE";
} }
/// The consensus data for a V1 header. /// The consensus data for a V1 header.
@@ -132,29 +181,43 @@ mod substrate {
fn from(header: &SubstrateHeader) -> Self { fn from(header: &SubstrateHeader) -> Self {
match header { match header {
SubstrateHeader::V1(header) => { SubstrateHeader::V1(header) => {
let digest = let mut pre_execution_digest = None;
header.consensus.digest.logs().iter().find_map(|digest_item| match digest_item { let mut execution_digest = None;
for log in header.consensus.digest.logs() {
match log {
DigestItem::PreRuntime(consensus, encoded) DigestItem::PreRuntime(consensus, encoded)
if *consensus == SeraiDigest::CONSENSUS_ID => if *consensus == SeraiExecutionDigest::CONSENSUS_ID =>
{ {
SeraiDigest::deserialize_reader(&mut encoded.as_slice()).ok() pre_execution_digest =
SeraiPreExecutionDigest::deserialize_reader(&mut encoded.as_slice()).ok();
} }
_ => None, DigestItem::Consensus(consensus, encoded)
}); if *consensus == SeraiExecutionDigest::CONSENSUS_ID =>
{
execution_digest =
SeraiExecutionDigest::deserialize_reader(&mut encoded.as_slice()).ok();
}
_ => {}
}
}
Header::V1(HeaderV1 { Header::V1(HeaderV1 {
number: header.number, number: header.number,
builds_upon: digest builds_upon: execution_digest
.as_ref() .as_ref()
.map(|digest| digest.builds_upon) .map(|digest| digest.builds_upon)
.unwrap_or(BlockHash::from([0; 32])), .unwrap_or(UnbalancedMerkleTree::EMPTY),
unix_time_in_millis: digest unix_time_in_millis: pre_execution_digest
.as_ref() .as_ref()
.map(|digest| digest.unix_time_in_millis) .map(|digest| digest.unix_time_in_millis)
.unwrap_or(0), .unwrap_or(0),
transactions_commitment: digest transactions_commitment: execution_digest
.as_ref() .as_ref()
.map(|digest| digest.transactions_commitment) .map(|digest| digest.transactions_commitment)
.unwrap_or([0; 32]), .unwrap_or(UnbalancedMerkleTree::EMPTY),
events_commitment: execution_digest
.as_ref()
.map(|digest| digest.events_commitment)
.unwrap_or(UnbalancedMerkleTree::EMPTY),
consensus_commitment: sp_core::blake2_256(&header.consensus.encode()), consensus_commitment: sp_core::blake2_256(&header.consensus.encode()),
}) })
} }

View File

@@ -204,6 +204,26 @@ impl Transaction {
explicit_context.serialize(&mut message).unwrap(); explicit_context.serialize(&mut message).unwrap();
message message
} }
/// The unique hash of this transaction.
///
/// No two transactions on the blockchain will share a hash, making this a unique identifier.
/// For signed transactions, this is due to the `(signer, nonce)` pair present within the
/// `ExplicitContext`. For unsigned transactions, this is due to inherent properties of their
/// execution (e.g. only being able to set a `ValidatorSet`'s keys once).
pub fn hash(&self) -> [u8; 32] {
sp_core::blake2_256(&match self {
Transaction::Unsigned { call } => borsh::to_vec(&call).unwrap(),
Transaction::Signed {
calls,
contextualized_signature: ContextualizedSignature { explicit_context, signature: _ },
} => {
// We explicitly don't hash the signature, so signatures can be replaced in the future if
// desired (such as with half-aggregated Schnorr signatures)
borsh::to_vec(&(calls, explicit_context)).unwrap()
}
})
}
} }
#[cfg(feature = "substrate")] #[cfg(feature = "substrate")]
@@ -268,7 +288,7 @@ mod substrate {
>; >;
/// The implicit context to verify transactions with. /// The implicit context to verify transactions with.
fn implicit_context() -> &'static ImplicitContext; fn implicit_context() -> ImplicitContext;
/// If a block is present in the blockchain. /// If a block is present in the blockchain.
fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool; fn block_is_present_in_blockchain(&self, hash: &BlockHash) -> bool;
@@ -276,7 +296,7 @@ mod substrate {
/// ///
/// Returns `None` if the time has yet to be set. /// Returns `None` if the time has yet to be set.
fn current_time(&self) -> Option<u64>; fn current_time(&self) -> Option<u64>;
/// The next nonce for an account. /// Get the next nonce for an account.
fn next_nonce(&self, signer: &SeraiAddress) -> u32; fn next_nonce(&self, signer: &SeraiAddress) -> u32;
/// If the signer can pay the SRI fee. /// If the signer can pay the SRI fee.
fn can_pay_fee( fn can_pay_fee(
@@ -284,8 +304,15 @@ mod substrate {
signer: &SeraiAddress, signer: &SeraiAddress,
fee: Amount, fee: Amount,
) -> Result<(), TransactionValidityError>; ) -> Result<(), TransactionValidityError>;
/// Begin execution of a transaction.
fn start_transaction(&self);
/// Consume the next nonce for an account.
fn consume_next_nonce(&self, signer: &SeraiAddress);
/// Have the transaction pay its SRI fee. /// Have the transaction pay its SRI fee.
fn pay_fee(&self, signer: &SeraiAddress, fee: Amount) -> Result<(), TransactionValidityError>; fn pay_fee(&self, signer: &SeraiAddress, fee: Amount) -> Result<(), TransactionValidityError>;
/// End execution of a transaction.
fn end_transaction(&self, transaction_hash: [u8; 32]);
} }
/// A transaction with the context necessary to evaluate it within Substrate. /// A transaction with the context necessary to evaluate it within Substrate.
@@ -339,7 +366,7 @@ mod substrate {
contextualized_signature: ContextualizedSignature { explicit_context, signature }, contextualized_signature: ContextualizedSignature { explicit_context, signature },
} => { } => {
if !sp_core::sr25519::Signature::from(*signature).verify( if !sp_core::sr25519::Signature::from(*signature).verify(
Transaction::signature_message(calls, Context::implicit_context(), explicit_context) Transaction::signature_message(calls, &Context::implicit_context(), explicit_context)
.as_slice(), .as_slice(),
&sp_core::sr25519::Public::from(explicit_context.signer), &sp_core::sr25519::Public::from(explicit_context.signer),
) { ) {
@@ -454,6 +481,7 @@ mod substrate {
self.1.can_pay_fee(signer, *fee)?; self.1.can_pay_fee(signer, *fee)?;
// Prioritize transactions by their fees // Prioritize transactions by their fees
// TODO: Re-evaluate this
{ {
let fee = fee.0; let fee = fee.0;
Weight::from_all(fee).checked_div_per_component(&info.call_weight).unwrap_or(0) Weight::from_all(fee).checked_div_per_component(&info.call_weight).unwrap_or(0)
@@ -471,7 +499,12 @@ mod substrate {
// We use 0 for the mempool priority, as this is no longer in the mempool so it's irrelevant // We use 0 for the mempool priority, as this is no longer in the mempool so it's irrelevant
self.validate_except_fee::<V>(TransactionSource::InBlock, 0)?; self.validate_except_fee::<V>(TransactionSource::InBlock, 0)?;
match self.0 { // Start the transaction
self.1.start_transaction();
let transaction_hash = self.0.hash();
let res = match self.0 {
Transaction::Unsigned { call } => { Transaction::Unsigned { call } => {
let call = Context::RuntimeCall::from(call.0); let call = Context::RuntimeCall::from(call.0);
V::pre_dispatch(&call)?; V::pre_dispatch(&call)?;
@@ -486,7 +519,9 @@ mod substrate {
contextualized_signature: contextualized_signature:
ContextualizedSignature { explicit_context: ExplicitContext { signer, fee, .. }, .. }, ContextualizedSignature { explicit_context: ExplicitContext { signer, fee, .. }, .. },
} => { } => {
// Start by paying the fee // Consume the signer's next nonce
self.1.consume_next_nonce(&signer);
// Pay the fee
self.1.pay_fee(&signer, fee)?; self.1.pay_fee(&signer, fee)?;
let _res = frame_support::storage::transactional::with_storage_layer(|| { let _res = frame_support::storage::transactional::with_storage_layer(|| {
@@ -513,7 +548,14 @@ mod substrate {
pays_fee: Pays::Yes, pays_fee: Pays::Yes,
})) }))
} }
} };
// TODO: TransactionSuccess/TransactionFailure event?
// End the transaction
self.1.end_transaction(transaction_hash);
res
} }
} }
} }

View File

@@ -15,8 +15,8 @@ use serai_primitives::{
pub enum Call { pub enum Call {
/// Set the keys for a validator set. /// Set the keys for a validator set.
set_keys { set_keys {
/// The network whose latest validator set is setting their keys. /// The validator set which is setting their keys.
network: ExternalNetworkId, validator_set: ExternalValidatorSet,
/// The keys being set. /// The keys being set.
key_pair: KeyPair, key_pair: KeyPair,
/// The participants in the validator set who signed off on these keys. /// The participants in the validator set who signed off on these keys.
@@ -31,8 +31,8 @@ pub enum Call {
}, },
/// Report a validator set's slashes onto Serai. /// Report a validator set's slashes onto Serai.
report_slashes { report_slashes {
/// The network whose retiring validator set is setting their keys. /// The validator set which is setting their keys.
network: ExternalNetworkId, validator_set: ExternalValidatorSet,
/// The slashes they're reporting. /// The slashes they're reporting.
slashes: SlashReport, slashes: SlashReport,
/// The signature confirming the validity of this slash report. /// The signature confirming the validity of this slash report.

View File

@@ -61,7 +61,6 @@ serai-docker-tests = { path = "../../tests/docker" }
[features] [features]
serai = ["thiserror/std", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"] serai = ["thiserror/std", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
borsh = []
networks = [] networks = []
bitcoin = ["networks", "dep:bitcoin"] bitcoin = ["networks", "dep:bitcoin"]

View File

@@ -3,7 +3,7 @@ name = "serai-coins-pallet"
version = "0.1.0" version = "0.1.0"
description = "Coins pallet for Serai" description = "Coins pallet for Serai"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/coins/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/coins"
authors = ["Akil Demir <akildemir72@gmail.com>"] authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -31,8 +31,7 @@ sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "sera
pallet-transaction-payment = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-transaction-payment = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false, features = ["serde"] } serai-primitives = { path = "../primitives", default-features = false }
coins-primitives = { package = "serai-coins-primitives", path = "../primitives", default-features = false }
[dev-dependencies] [dev-dependencies]
sp-io = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, features = ["std"] } sp-io = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, features = ["std"] }
@@ -49,7 +48,6 @@ std = [
"pallet-transaction-payment/std", "pallet-transaction-payment/std",
"serai-primitives/std", "serai-primitives/std",
"coins-primitives/std",
] ]
try-runtime = [ try-runtime = [

View File

@@ -1,35 +0,0 @@
[package]
name = "serai-coins-primitives"
version = "0.1.0"
description = "Serai coins primitives"
license = "MIT"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
zeroize = { version = "^1.5", features = ["derive"], optional = true }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
serai-primitives = { path = "../../primitives", default-features = false }
[dev-dependencies]
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
[features]
std = ["zeroize", "borsh?/std", "serde?/std", "scale/std", "scale-info/std", "sp-runtime/std", "serai-primitives/std"]
borsh = ["dep:borsh", "serai-primitives/borsh"]
serde = ["dep:serde", "serai-primitives/serde"]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1 +0,0 @@

View File

@@ -3,7 +3,7 @@ name = "serai-dex-pallet"
version = "0.1.0" version = "0.1.0"
description = "DEX pallet for Serai" description = "DEX pallet for Serai"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/dex/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/dex"
authors = ["Parity Technologies <admin@parity.io>, Akil Demir <akildemir72@gmail.com>"] authors = ["Parity Technologies <admin@parity.io>, Akil Demir <akildemir72@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -32,9 +32,9 @@ frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "se
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-benchmarking = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, optional = true } frame-benchmarking = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, optional = true }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
[dev-dependencies] [dev-dependencies]
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] } rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }

View File

@@ -3,7 +3,7 @@ name = "serai-economic-security-pallet"
version = "0.1.0" version = "0.1.0"
description = "Economic Security pallet for Serai" description = "Economic Security pallet for Serai"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/economic-security/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/economic-security"
authors = ["Akil Demir <akildemir72@gmail.com>"] authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -25,10 +25,10 @@ scale-info = { version = "2", default-features = false, features = ["derive"] }
frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
[dev-dependencies] [dev-dependencies]
@@ -36,7 +36,7 @@ pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "ser
pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false } validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
sp-io = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-io = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }

View File

@@ -3,7 +3,7 @@ name = "serai-emissions-pallet"
version = "0.1.0" version = "0.1.0"
description = "Emissions pallet for Serai" description = "Emissions pallet for Serai"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/emissions/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/emissions"
authors = ["Akil Demir <akildemir72@gmail.com>"] authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -28,16 +28,14 @@ frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "s
sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false } validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../../genesis-liquidity/pallet", default-features = false } genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../genesis-liquidity", default-features = false }
economic-security-pallet = { package = "serai-economic-security-pallet", path = "../../economic-security/pallet", default-features = false } economic-security-pallet = { package = "serai-economic-security-pallet", path = "../economic-security", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../validator-sets/primitives", default-features = false }
emissions-primitives = { package = "serai-emissions-primitives", path = "../primitives", default-features = false }
[features] [features]
std = [ std = [
@@ -58,8 +56,6 @@ std = [
"economic-security-pallet/std", "economic-security-pallet/std",
"serai-primitives/std", "serai-primitives/std",
"emissions-primitives/std",
] ]
fast-epoch = []
try-runtime = [] # TODO try-runtime = [] # TODO
default = ["std"] default = ["std"]

View File

@@ -1,23 +0,0 @@
[package]
name = "serai-emissions-primitives"
version = "0.1.0"
description = "Serai emissions primitives"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/emissions/primitives"
authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
serai-primitives = { path = "../../primitives", default-features = false }
[features]
std = ["serai-primitives/std"]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,26 +0,0 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
use serai_primitives::{DAYS, YEARS, SeraiAddress, system_address};
// Protocol owned liquidity account.
pub const POL_ACCOUNT: SeraiAddress = system_address(b"Serai-protocol_owned_liquidity");
/// INITIAL_REWARD = 100,000 SRI / BLOCKS_PER_DAY for 60 days
pub const INITIAL_REWARD_PER_BLOCK: u64 = (100_000 * 10u64.pow(8)) / DAYS;
/// REWARD = 20M SRI / BLOCKS_PER_YEAR
pub const REWARD_PER_BLOCK: u64 = (20_000_000 * 10u64.pow(8)) / YEARS;
/// 20% of all stake desired to be for Serai network
pub const SERAI_VALIDATORS_DESIRED_PERCENTAGE: u64 = 20;
/// Desired unused capacity ratio for a network assuming capacity is 10,000.
pub const DESIRED_DISTRIBUTION: u64 = 1_000;
/// Percentage scale for the validator vs. pool reward distribution.
pub const ACCURACY_MULTIPLIER: u64 = 10_000;
/// The block to target for economic security
pub const SECURE_BY: u64 = YEARS;

View File

@@ -3,7 +3,7 @@ name = "serai-genesis-liquidity-pallet"
version = "0.1.0" version = "0.1.0"
description = "Genesis liquidity pallet for Serai" description = "Genesis liquidity pallet for Serai"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity"
authors = ["Akil Demir <akildemir72@gmail.com>"] authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -29,15 +29,13 @@ sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-ne
sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-application-crypto = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false } validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
economic-security-pallet = { package = "serai-economic-security-pallet", path = "../../economic-security/pallet", default-features = false } economic-security-pallet = { package = "serai-economic-security-pallet", path = "../economic-security", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
genesis-liquidity-primitives = { package = "serai-genesis-liquidity-primitives", path = "../primitives", default-features = false }
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../validator-sets/primitives", default-features = false }
[features] [features]
std = [ std = [
@@ -58,10 +56,7 @@ std = [
"economic-security-pallet/std", "economic-security-pallet/std",
"serai-primitives/std", "serai-primitives/std",
"genesis-liquidity-primitives/std",
"validator-sets-primitives/std",
] ]
try-runtime = [] # TODO try-runtime = [] # TODO
fast-epoch = []
default = ["std"] default = ["std"]

View File

@@ -1,45 +0,0 @@
[package]
name = "serai-genesis-liquidity-primitives"
version = "0.1.0"
description = "Serai genesis liquidity primitives"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity/primitives"
authors = ["Akil Demir <akildemir72@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
zeroize = { version = "^1.5", features = ["derive"], optional = true }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false }
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../validator-sets/primitives", default-features = false }
[features]
std = [
"zeroize",
"scale/std",
"borsh?/std",
"serde?/std",
"scale-info/std",
"serai-primitives/std",
"validator-sets-primitives/std",
"sp-std/std"
]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -3,6 +3,7 @@ name = "serai-in-instructions-pallet"
version = "0.1.0" version = "0.1.0"
description = "Execute calls via In Instructions from unsigned transactions" description = "Execute calls via In Instructions from unsigned transactions"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity"
authors = ["Luke Parker <lukeparker5132@gmail.com>"] authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021" edition = "2021"
publish = false publish = false
@@ -33,21 +34,20 @@ sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-n
frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../primitives", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false } validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../../genesis-liquidity/pallet", default-features = false } genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../genesis-liquidity", default-features = false }
emissions-pallet = { package = "serai-emissions-pallet", path = "../../emissions/pallet", default-features = false } emissions-pallet = { package = "serai-emissions-pallet", path = "../emissions", default-features = false }
[dev-dependencies] [dev-dependencies]
pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
economic-security-pallet = { package = "serai-economic-security-pallet", path = "../../economic-security/pallet", default-features = false } economic-security-pallet = { package = "serai-economic-security-pallet", path = "../economic-security", default-features = false }
[features] [features]
std = [ std = [
@@ -64,7 +64,6 @@ std = [
"frame-support/std", "frame-support/std",
"serai-primitives/std", "serai-primitives/std",
"in-instructions-primitives/std",
"coins-pallet/std", "coins-pallet/std",
"dex-pallet/std", "dex-pallet/std",

View File

@@ -1,52 +0,0 @@
[package]
name = "serai-in-instructions-primitives"
version = "0.1.0"
description = "Serai instructions library, enabling encoding and decoding"
license = "MIT"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
zeroize = { version = "^1.5", features = ["derive"], optional = true }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false }
coins-primitives = { package = "serai-coins-primitives", path = "../../coins/primitives", default-features = false }
[features]
std = [
"zeroize",
"borsh?/std",
"serde?/std",
"scale/std",
"scale-info/std",
"sp-std/std",
"sp-application-crypto/std",
"sp-runtime/std",
"serai-primitives/std",
"coins-primitives/std",
]
borsh = ["dep:borsh", "serai-primitives/borsh", "coins-primitives/borsh"]
serde = ["dep:serde", "serai-primitives/serde", "coins-primitives/serde"]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022-2023 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -88,7 +88,6 @@ substrate-build-script-utils = { git = "https://github.com/serai-dex/polkadot-sd
[features] [features]
default = [] default = []
fast-epoch = ["serai-runtime/fast-epoch"]
runtime-benchmarks = [ runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks",

View File

@@ -28,8 +28,9 @@ dkg = { path = "../../crypto/dkg", default-features = false }
bech32 = { version = "0.11", default-features = false } bech32 = { version = "0.11", default-features = false }
[dev-dependencies]
rand_core = { version = "0.6", default-features = false, features = ["std"] }
[features] [features]
std = ["zeroize/std", "borsh/std", "ciphersuite/std", "dkg/std", "sp-core/std", "bech32/std"] std = ["zeroize/std", "borsh/std", "ciphersuite/std", "dkg/std", "sp-core/std", "bech32/std"]
default = ["std"] default = ["std"]
borsh = [] # TODO
serde = [] # TODO

View File

@@ -27,6 +27,10 @@ const HUMAN_READABLE_PART: bech32::Hrp = bech32::Hrp::parse_unchecked("sri");
#[derive(scale::Encode, scale::Decode)] // This is safe as scale and borsh share an encoding here #[derive(scale::Encode, scale::Decode)] // This is safe as scale and borsh share an encoding here
pub struct SeraiAddress(pub [u8; 32]); pub struct SeraiAddress(pub [u8; 32]);
// These share encodings as 32-byte arrays
impl scale::EncodeLike<Public> for SeraiAddress {}
impl scale::EncodeLike<Public> for &SeraiAddress {}
impl SeraiAddress { impl SeraiAddress {
/// Generate an address for use by the system. /// Generate an address for use by the system.
/// ///

View File

@@ -43,14 +43,15 @@ pub mod signals;
/// Instruction types. /// Instruction types.
pub mod instructions; pub mod instructions;
/// Merkle trees.
pub mod merkle;
/// The type used to identify block numbers. /// The type used to identify block numbers.
/// ///
/// A block's number is its zero-indexed position on the list of blocks which form a blockchain. /// A block's number is its zero-indexed position on the list of blocks which form a blockchain.
/// For non-linear structures, this would presumably be the zero-indexed position within some /// For non-linear structures, this would presumably be the zero-indexed position within some
/// topological order. /// topological order.
#[derive( #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize,
)]
pub struct BlockNumber(pub u64); pub struct BlockNumber(pub u64);
impl From<u64> for BlockNumber { impl From<u64> for BlockNumber {
fn from(number: u64) -> BlockNumber { fn from(number: u64) -> BlockNumber {
@@ -66,6 +67,8 @@ impl From<u64> for BlockNumber {
hash it into a 32-byte hash or truncate it. hash it into a 32-byte hash or truncate it.
*/ */
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize)] #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
#[rustfmt::skip]
#[derive(scale::Encode, scale::Decode)] // This is safe as scale and borsh share an encoding here
pub struct BlockHash(pub [u8; 32]); pub struct BlockHash(pub [u8; 32]);
impl From<[u8; 32]> for BlockHash { impl From<[u8; 32]> for BlockHash {
fn from(hash: [u8; 32]) -> BlockHash { fn from(hash: [u8; 32]) -> BlockHash {
@@ -77,3 +80,7 @@ impl From<sp_core::H256> for BlockHash {
BlockHash(hash.into()) BlockHash(hash.into())
} }
} }
// These share encodings as 32-byte arrays
impl scale::EncodeLike<sp_core::H256> for BlockHash {}
impl scale::EncodeLike<sp_core::H256> for &BlockHash {}

View File

@@ -0,0 +1,177 @@
use alloc::vec::Vec;
use borsh::{BorshSerialize, BorshDeserialize};
/// An unbalanced Merkle tree.
///
/// This Merkle tree represents its leaves once and only once (distinct from a balanced Merkle
/// tree, which would require padding its leaves to a power of two). Accordingly, leaves have
/// canonical paths. This is useful for anyone who wants to index leaves which don't inherently
/// have indexes.
///
/// `[0; 32]` is used to represent an empty tree.
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub struct UnbalancedMerkleTree {
/// The root of the tree represented.
pub root: [u8; 32],
}
impl UnbalancedMerkleTree {
/// An empty Merkle tree.
pub const EMPTY: Self = Self { root: [0; 32] };
/// If this tree is empty of leaves.
pub fn is_empty(self) -> bool {
self == Self::EMPTY
}
fn branch_hash(tag: u8, left: &[u8; 32], right: &[u8; 32]) -> [u8; 32] {
let mut preimage = [tag; 65];
preimage[1 .. 33].copy_from_slice(left);
preimage[33 ..].copy_from_slice(right);
sp_core::blake2_256(&preimage)
}
/// Create a new Merkle tree from a set of leaves.
///
/// Each branch hash will be prefixed by the specified tag. To ensure branches are not argued
/// leaves, and vice-versa, the hashes present in the list MUST never have preimages whose first
/// byte may be the specified tag byte.
///
/// This method performs intermediary allocations necessary to calculate the root.
pub fn new(tag: u8, leaves: Vec<[u8; 32]>) -> Self {
if leaves.is_empty() {
return Self::EMPTY;
}
let mut current = leaves;
let mut next = Vec::with_capacity(current.len().div_ceil(2));
// Iterate until the root hash
while current.len() != 1 {
let mut iter = current.iter();
while let Some(a) = iter.next() {
match iter.next() {
// If we have a pair of hashes, create a branch hash
Some(b) => {
next.push(Self::branch_hash(tag, a, b));
}
// If we don't, propagate this hash
None => next.push(*a),
}
}
core::mem::swap(&mut current, &mut next);
next.clear();
}
Self { root: current[0] }
}
}
/// An unbalanced Merkle tree which is incrementally created.
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
pub struct IncrementalUnbalancedMerkleTree {
/// (number of children under branch, branch hash)
branches: Vec<(u64, [u8; 32])>,
}
impl IncrementalUnbalancedMerkleTree {
/// Create a new incrementally-created unbalanced merkle tree.
pub fn new() -> Self {
Self { branches: Vec::new() }
}
/// Reduce the incremental tree.
///
/// We prune the descendants of fully-populated branches.
fn reduce(&mut self, tag: u8) {
while {
// If we have two branches eligible to be merged, and they're of equal depth
let len = self.branches.len();
(len >= 2) && (self.branches[len - 2].0 == self.branches[len - 1].0)
} {
// Merge them, as the two descendants of this branch, pruning themselves
let right = self.branches.pop().unwrap();
let left = self.branches.last_mut().unwrap();
left.0 *= 2;
left.1 = UnbalancedMerkleTree::branch_hash(tag, &left.1, &right.1);
}
}
/// Append a leaf to this merkle tree.
///
/// The conditions on this leaf are the same as defined by `UnbalancedMerkleTree::new`.
///
/// This will not calculate any hashes not necessary for the eventual root.
pub fn append(&mut self, tag: u8, leaf: [u8; 32]) {
self.branches.push((1, leaf));
self.reduce(tag);
}
/// Calculate the `UnbalancedMerkleTree` for this tree.
pub fn calculate(mut self, tag: u8) -> UnbalancedMerkleTree {
if self.branches.is_empty() {
return UnbalancedMerkleTree::EMPTY;
}
while self.branches.len() > 1 {
// The left-most list elements will have already be hashed at the layer simulated for the
// right-most list elements. We emulate the hashes upon carries for right-most elements
{
let right = self.branches.pop().unwrap();
let left = self.branches.last_mut().unwrap();
left.0 *= 2;
left.1 = UnbalancedMerkleTree::branch_hash(tag, &left.1, &right.1);
}
// And then we perform any hashes due to being of equal depth
self.reduce(tag);
}
UnbalancedMerkleTree { root: self.branches[0].1 }
}
}
#[cfg(feature = "std")]
#[test]
fn unbalanced_merkle_tree() {
use sp_core::Encode;
use rand_core::{RngCore, OsRng};
let tag = u8::try_from(OsRng.next_u64() % u64::from(u8::MAX)).unwrap();
let mut list_of_hashes = vec![];
let mut incremental = IncrementalUnbalancedMerkleTree::new();
for i in 0 ..= 257 {
assert_eq!(list_of_hashes.len(), i);
// Calculate the root of the tree
let with_new = UnbalancedMerkleTree::new(tag, list_of_hashes.clone());
// Check `is_empty` works
assert_eq!(with_new.is_empty(), i == 0);
// The reference method, easy to audit, should have identical behavior to the optimized method
assert_eq!(
with_new,
UnbalancedMerkleTree::from_scale_encoded_list_of_hashes(tag, list_of_hashes.encode())
);
// The encoding of a slice should work the same as the encoding of a list
assert_eq!(
with_new,
UnbalancedMerkleTree::from_scale_encoded_list_of_hashes(
tag,
list_of_hashes.as_slice().encode()
)
);
// Check the incremental method produces an identical result
assert_eq!(incremental.clone().calculate(tag), with_new, "{i}");
// If the tree has branches...
if i > 1 {
// Changing the tag should change the root hash
assert!(with_new != UnbalancedMerkleTree::new(tag.wrapping_add(1), list_of_hashes.clone()));
}
// Push a new hash onto the list for the next iteration
{
let mut hash = [0; 32];
OsRng.fill_bytes(&mut hash);
list_of_hashes.push(hash);
incremental.append(tag, hash);
}
}
}

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "serai-runtime" name = "serai-runtime"
version = "0.1.0" version = "0.1.0"
description = "Serai network node runtime, built over Substrate" description = "Serai's on-chain logic"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/runtime" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/runtime"
authors = ["Luke Parker <lukeparker5132@gmail.com>"] authors = ["Luke Parker <lukeparker5132@gmail.com>"]
@@ -19,61 +19,21 @@ ignored = ["scale", "scale-info"]
workspace = true workspace = true
[dependencies] [dependencies]
hashbrown = { version = "0.15", default-features = false, features = ["default-hasher", "inline-more"] } borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"] }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] } scale-info = { version = "2", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-offchain = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-version = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-version = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-inherents = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-session = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-consensus-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-consensus-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-authority-discovery = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-transaction-pool = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-block-builder = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-runtime = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-api = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-api = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-abi = { path = "../abi", default-features = false, features = ["substrate"] }
frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-executive = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-executive = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-benchmarking = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false, optional = true }
serai-primitives = { path = "../primitives", default-features = false }
serai-abi = { path = "../abi", default-features = false }
pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-authorship = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-transaction-payment = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../coins/pallet", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../dex/pallet", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets/pallet", default-features = false }
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../genesis-liquidity/pallet", default-features = false }
emissions-pallet = { package = "serai-emissions-pallet", path = "../emissions/pallet", default-features = false }
economic-security-pallet = { package = "serai-economic-security-pallet", path = "../economic-security/pallet", default-features = false }
in-instructions-pallet = { package = "serai-in-instructions-pallet", path = "../in-instructions/pallet", default-features = false }
signals-pallet = { package = "serai-signals-pallet", path = "../signals/pallet", default-features = false }
pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
[build-dependencies] [build-dependencies]
substrate-wasm-builder = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next" } substrate-wasm-builder = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next" }
@@ -84,21 +44,7 @@ std = [
"scale-info/std", "scale-info/std",
"sp-core/std", "sp-core/std",
"sp-std/std",
"sp-offchain/std",
"sp-version/std", "sp-version/std",
"sp-inherents/std",
"sp-session/std",
"sp-consensus-babe/std",
"sp-consensus-grandpa/std",
"sp-authority-discovery/std",
"sp-transaction-pool/std",
"sp-block-builder/std",
"sp-runtime/std", "sp-runtime/std",
"sp-api/std", "sp-api/std",
@@ -106,50 +52,10 @@ std = [
"frame-support/std", "frame-support/std",
"frame-executive/std", "frame-executive/std",
"serai-primitives/std",
"serai-abi/std", "serai-abi/std",
"pallet-timestamp/std",
"pallet-authorship/std",
"pallet-transaction-payment/std",
"coins-pallet/std",
"dex-pallet/std",
"validator-sets-pallet/std",
"genesis-liquidity-pallet/std",
"emissions-pallet/std",
"economic-security-pallet/std",
"in-instructions-pallet/std",
"signals-pallet/std",
"pallet-babe/std",
"pallet-grandpa/std",
"frame-system-rpc-runtime-api/std",
"pallet-transaction-payment-rpc-runtime-api/std",
] ]
fast-epoch = [ try-runtime = ["sp-runtime/try-runtime", "serai-abi/try-runtime", "frame-system/try-runtime", "frame-support/try-runtime", "frame-executive/try-runtime"]
"genesis-liquidity-pallet/fast-epoch", runtime-benchmarks = ["sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", "frame-support/runtime-benchmarks"]
"emissions-pallet/fast-epoch",
]
runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-grandpa/runtime-benchmarks",
]
default = ["std"] default = ["std"]

View File

@@ -1,12 +1,4 @@
use substrate_wasm_builder::WasmBuilder;
fn main() { fn main() {
WasmBuilder::new() #[cfg(feature = "std")]
.with_current_project() substrate_wasm_builder::WasmBuilder::build_using_defaults();
// https://substrate.stackexchange.com/questions/12124
// TODO: Remove once we've moved to polkadot-sdk
.disable_runtime_version_section_check()
.export_heap_base()
.import_memory()
.build()
} }

View File

@@ -1,372 +0,0 @@
use core::marker::PhantomData;
use scale::{Encode, Decode};
use serai_abi::Call;
use crate::{
timestamp, coins, dex, genesis_liquidity,
validator_sets::{self, MembershipProof},
in_instructions, signals, babe, grandpa, RuntimeCall,
};
impl From<Call> for RuntimeCall {
fn from(call: Call) -> RuntimeCall {
match call {
Call::Timestamp(serai_abi::timestamp::Call::set { now }) => {
RuntimeCall::Timestamp(timestamp::Call::set { now })
}
Call::Coins(coins) => match coins {
serai_abi::coins::Call::transfer { to, balance } => {
RuntimeCall::Coins(coins::Call::transfer { to: to.into(), balance })
}
serai_abi::coins::Call::burn { balance } => {
RuntimeCall::Coins(coins::Call::burn { balance })
}
serai_abi::coins::Call::burn_with_instruction { instruction } => {
RuntimeCall::Coins(coins::Call::burn_with_instruction { instruction })
}
},
Call::LiquidityTokens(lt) => match lt {
serai_abi::liquidity_tokens::Call::transfer { to, balance } => {
RuntimeCall::LiquidityTokens(coins::Call::transfer { to: to.into(), balance })
}
serai_abi::liquidity_tokens::Call::burn { balance } => {
RuntimeCall::LiquidityTokens(coins::Call::burn { balance })
}
},
Call::Dex(dex) => match dex {
serai_abi::dex::Call::add_liquidity {
coin,
coin_desired,
sri_desired,
coin_min,
sri_min,
mint_to,
} => RuntimeCall::Dex(dex::Call::add_liquidity {
coin,
coin_desired,
sri_desired,
coin_min,
sri_min,
mint_to: mint_to.into(),
}),
serai_abi::dex::Call::remove_liquidity {
coin,
lp_token_burn,
coin_min_receive,
sri_min_receive,
withdraw_to,
} => RuntimeCall::Dex(dex::Call::remove_liquidity {
coin,
lp_token_burn,
coin_min_receive,
sri_min_receive,
withdraw_to: withdraw_to.into(),
}),
serai_abi::dex::Call::swap_exact_tokens_for_tokens {
path,
amount_in,
amount_out_min,
send_to,
} => RuntimeCall::Dex(dex::Call::swap_exact_tokens_for_tokens {
path,
amount_in,
amount_out_min,
send_to: send_to.into(),
}),
serai_abi::dex::Call::swap_tokens_for_exact_tokens {
path,
amount_out,
amount_in_max,
send_to,
} => RuntimeCall::Dex(dex::Call::swap_tokens_for_exact_tokens {
path,
amount_out,
amount_in_max,
send_to: send_to.into(),
}),
},
Call::ValidatorSets(vs) => match vs {
serai_abi::validator_sets::Call::set_keys {
network,
key_pair,
signature_participants,
signature,
} => RuntimeCall::ValidatorSets(validator_sets::Call::set_keys {
network,
key_pair,
signature_participants,
signature,
}),
serai_abi::validator_sets::Call::set_embedded_elliptic_curve_key {
embedded_elliptic_curve,
key,
} => RuntimeCall::ValidatorSets(validator_sets::Call::set_embedded_elliptic_curve_key {
embedded_elliptic_curve,
key,
}),
serai_abi::validator_sets::Call::report_slashes { network, slashes, signature } => {
RuntimeCall::ValidatorSets(validator_sets::Call::report_slashes {
network,
slashes,
signature,
})
}
serai_abi::validator_sets::Call::allocate { network, amount } => {
RuntimeCall::ValidatorSets(validator_sets::Call::allocate { network, amount })
}
serai_abi::validator_sets::Call::deallocate { network, amount } => {
RuntimeCall::ValidatorSets(validator_sets::Call::deallocate { network, amount })
}
serai_abi::validator_sets::Call::claim_deallocation { network, session } => {
RuntimeCall::ValidatorSets(validator_sets::Call::claim_deallocation { network, session })
}
},
Call::GenesisLiquidity(gl) => match gl {
serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance } => {
RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::remove_coin_liquidity { balance })
}
serai_abi::genesis_liquidity::Call::oraclize_values { values, signature } => {
RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::oraclize_values {
values,
signature,
})
}
},
Call::InInstructions(ii) => match ii {
serai_abi::in_instructions::Call::execute_batch { batch } => {
RuntimeCall::InInstructions(in_instructions::Call::execute_batch { batch })
}
},
Call::Signals(signals) => match signals {
serai_abi::signals::Call::register_retirement_signal { in_favor_of } => {
RuntimeCall::Signals(signals::Call::register_retirement_signal { in_favor_of })
}
serai_abi::signals::Call::revoke_retirement_signal { retirement_signal_id } => {
RuntimeCall::Signals(signals::Call::revoke_retirement_signal { retirement_signal_id })
}
serai_abi::signals::Call::favor { signal_id, for_network } => {
RuntimeCall::Signals(signals::Call::favor { signal_id, for_network })
}
serai_abi::signals::Call::revoke_favor { signal_id, for_network } => {
RuntimeCall::Signals(signals::Call::revoke_favor { signal_id, for_network })
}
serai_abi::signals::Call::stand_against { signal_id, for_network } => {
RuntimeCall::Signals(signals::Call::stand_against { signal_id, for_network })
}
},
Call::Babe(babe) => match babe {
serai_abi::babe::Call::report_equivocation(report) => {
RuntimeCall::Babe(babe::Call::report_equivocation {
// TODO: Find a better way to go from Proof<[u8; 32]> to Proof<H256>
equivocation_proof: <_>::decode(&mut report.equivocation_proof.encode().as_slice())
.unwrap(),
key_owner_proof: MembershipProof(report.key_owner_proof.into(), PhantomData),
})
}
serai_abi::babe::Call::report_equivocation_unsigned(report) => {
RuntimeCall::Babe(babe::Call::report_equivocation_unsigned {
// TODO: Find a better way to go from Proof<[u8; 32]> to Proof<H256>
equivocation_proof: <_>::decode(&mut report.equivocation_proof.encode().as_slice())
.unwrap(),
key_owner_proof: MembershipProof(report.key_owner_proof.into(), PhantomData),
})
}
},
Call::Grandpa(grandpa) => match grandpa {
serai_abi::grandpa::Call::report_equivocation(report) => {
RuntimeCall::Grandpa(grandpa::Call::report_equivocation {
// TODO: Find a better way to go from Proof<[u8; 32]> to Proof<H256>
equivocation_proof: <_>::decode(&mut report.equivocation_proof.encode().as_slice())
.unwrap(),
key_owner_proof: MembershipProof(report.key_owner_proof.into(), PhantomData),
})
}
serai_abi::grandpa::Call::report_equivocation_unsigned(report) => {
RuntimeCall::Grandpa(grandpa::Call::report_equivocation_unsigned {
// TODO: Find a better way to go from Proof<[u8; 32]> to Proof<H256>
equivocation_proof: <_>::decode(&mut report.equivocation_proof.encode().as_slice())
.unwrap(),
key_owner_proof: MembershipProof(report.key_owner_proof.into(), PhantomData),
})
}
},
}
}
}
impl TryInto<Call> for RuntimeCall {
type Error = ();
fn try_into(self) -> Result<Call, ()> {
Ok(match self {
RuntimeCall::Timestamp(timestamp::Call::set { now }) => {
Call::Timestamp(serai_abi::timestamp::Call::set { now })
}
RuntimeCall::Coins(call) => Call::Coins(match call {
coins::Call::transfer { to, balance } => {
serai_abi::coins::Call::transfer { to: to.into(), balance }
}
coins::Call::burn { balance } => serai_abi::coins::Call::burn { balance },
coins::Call::burn_with_instruction { instruction } => {
serai_abi::coins::Call::burn_with_instruction { instruction }
}
_ => Err(())?,
}),
RuntimeCall::LiquidityTokens(call) => Call::LiquidityTokens(match call {
coins::Call::transfer { to, balance } => {
serai_abi::liquidity_tokens::Call::transfer { to: to.into(), balance }
}
coins::Call::burn { balance } => serai_abi::liquidity_tokens::Call::burn { balance },
_ => Err(())?,
}),
RuntimeCall::Dex(call) => Call::Dex(match call {
dex::Call::add_liquidity {
coin,
coin_desired,
sri_desired,
coin_min,
sri_min,
mint_to,
} => serai_abi::dex::Call::add_liquidity {
coin,
coin_desired,
sri_desired,
coin_min,
sri_min,
mint_to: mint_to.into(),
},
dex::Call::remove_liquidity {
coin,
lp_token_burn,
coin_min_receive,
sri_min_receive,
withdraw_to,
} => serai_abi::dex::Call::remove_liquidity {
coin,
lp_token_burn,
coin_min_receive,
sri_min_receive,
withdraw_to: withdraw_to.into(),
},
dex::Call::swap_exact_tokens_for_tokens { path, amount_in, amount_out_min, send_to } => {
serai_abi::dex::Call::swap_exact_tokens_for_tokens {
path,
amount_in,
amount_out_min,
send_to: send_to.into(),
}
}
dex::Call::swap_tokens_for_exact_tokens { path, amount_out, amount_in_max, send_to } => {
serai_abi::dex::Call::swap_tokens_for_exact_tokens {
path,
amount_out,
amount_in_max,
send_to: send_to.into(),
}
}
_ => Err(())?,
}),
RuntimeCall::GenesisLiquidity(call) => Call::GenesisLiquidity(match call {
genesis_liquidity::Call::remove_coin_liquidity { balance } => {
serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance }
}
genesis_liquidity::Call::oraclize_values { values, signature } => {
serai_abi::genesis_liquidity::Call::oraclize_values { values, signature }
}
_ => Err(())?,
}),
RuntimeCall::ValidatorSets(call) => Call::ValidatorSets(match call {
validator_sets::Call::set_keys { network, key_pair, signature_participants, signature } => {
serai_abi::validator_sets::Call::set_keys {
network,
key_pair,
signature_participants,
signature,
}
}
validator_sets::Call::set_embedded_elliptic_curve_key { embedded_elliptic_curve, key } => {
serai_abi::validator_sets::Call::set_embedded_elliptic_curve_key {
embedded_elliptic_curve,
key,
}
}
validator_sets::Call::report_slashes { network, slashes, signature } => {
serai_abi::validator_sets::Call::report_slashes { network, slashes, signature }
}
validator_sets::Call::allocate { network, amount } => {
serai_abi::validator_sets::Call::allocate { network, amount }
}
validator_sets::Call::deallocate { network, amount } => {
serai_abi::validator_sets::Call::deallocate { network, amount }
}
validator_sets::Call::claim_deallocation { network, session } => {
serai_abi::validator_sets::Call::claim_deallocation { network, session }
}
_ => Err(())?,
}),
RuntimeCall::InInstructions(call) => Call::InInstructions(match call {
in_instructions::Call::execute_batch { batch } => {
serai_abi::in_instructions::Call::execute_batch { batch }
}
_ => Err(())?,
}),
RuntimeCall::Signals(call) => Call::Signals(match call {
signals::Call::register_retirement_signal { in_favor_of } => {
serai_abi::signals::Call::register_retirement_signal { in_favor_of }
}
signals::Call::revoke_retirement_signal { retirement_signal_id } => {
serai_abi::signals::Call::revoke_retirement_signal { retirement_signal_id }
}
signals::Call::favor { signal_id, for_network } => {
serai_abi::signals::Call::favor { signal_id, for_network }
}
signals::Call::revoke_favor { signal_id, for_network } => {
serai_abi::signals::Call::revoke_favor { signal_id, for_network }
}
signals::Call::stand_against { signal_id, for_network } => {
serai_abi::signals::Call::stand_against { signal_id, for_network }
}
_ => Err(())?,
}),
RuntimeCall::Babe(call) => Call::Babe(match call {
babe::Call::report_equivocation { equivocation_proof, key_owner_proof } => {
serai_abi::babe::Call::report_equivocation(serai_abi::babe::ReportEquivocation {
// TODO: Find a better way to go from Proof<H256> to Proof<[u8; 32]>
equivocation_proof: <_>::decode(&mut equivocation_proof.encode().as_slice()).unwrap(),
key_owner_proof: key_owner_proof.0.into(),
})
}
babe::Call::report_equivocation_unsigned { equivocation_proof, key_owner_proof } => {
serai_abi::babe::Call::report_equivocation_unsigned(serai_abi::babe::ReportEquivocation {
// TODO: Find a better way to go from Proof<H256> to Proof<[u8; 32]>
equivocation_proof: <_>::decode(&mut equivocation_proof.encode().as_slice()).unwrap(),
key_owner_proof: key_owner_proof.0.into(),
})
}
_ => Err(())?,
}),
RuntimeCall::Grandpa(call) => Call::Grandpa(match call {
grandpa::Call::report_equivocation { equivocation_proof, key_owner_proof } => {
serai_abi::grandpa::Call::report_equivocation(serai_abi::grandpa::ReportEquivocation {
// TODO: Find a better way to go from Proof<H256> to Proof<[u8; 32]>
equivocation_proof: <_>::decode(&mut equivocation_proof.encode().as_slice()).unwrap(),
key_owner_proof: key_owner_proof.0.into(),
})
}
grandpa::Call::report_equivocation_unsigned { equivocation_proof, key_owner_proof } => {
serai_abi::grandpa::Call::report_equivocation_unsigned(
serai_abi::grandpa::ReportEquivocation {
// TODO: Find a better way to go from Proof<H256> to Proof<[u8; 32]>
equivocation_proof: <_>::decode(&mut equivocation_proof.encode().as_slice()).unwrap(),
key_owner_proof: key_owner_proof.0.into(),
},
)
}
_ => Err(())?,
}),
_ => Err(())?,
})
}
}

View File

@@ -0,0 +1,172 @@
use core::marker::PhantomData;
use alloc::{vec, vec::Vec};
use borsh::{BorshSerialize, BorshDeserialize};
use frame_support::pallet_prelude::*;
use serai_abi::{
primitives::merkle::{UnbalancedMerkleTree, IncrementalUnbalancedMerkleTree as Iumt},
*,
};
struct IncrementalUnbalancedMerkleTree<
T: frame_support::StorageValue<Vec<u8>, Query = Option<Vec<u8>>>,
const BRANCH_TAG: u8 = 1,
const LEAF_TAG: u8 = 0,
>(PhantomData<T>);
impl<
T: frame_support::StorageValue<Vec<u8>, Query = Option<Vec<u8>>>,
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(borsh::to_vec(&Iumt::new()).unwrap());
});
}
/// 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 mut tree = Iumt::deserialize_reader(&mut value.as_ref().unwrap().as_slice()).unwrap();
tree.append(BRANCH_TAG, leaf);
*value = Some(borsh::to_vec(&tree).unwrap());
})
}
/// Get the unbalanced merkle tree.
///
/// Panics if no Merkle tree was present.
fn get() -> UnbalancedMerkleTree {
Iumt::deserialize_reader(&mut T::get().unwrap().as_slice()).unwrap().calculate(BRANCH_TAG)
}
/// Take the Merkle tree.
///
/// Panics if no Merkle tree was present.
fn take() -> UnbalancedMerkleTree {
T::mutate(|value| {
let tree = Iumt::deserialize_reader(&mut value.as_ref().unwrap().as_slice()).unwrap();
*value = None;
tree.calculate(BRANCH_TAG)
})
}
}
#[frame_support::pallet]
mod pallet {
use super::*;
/// The set of all blocks prior added to the blockchain.
#[pallet::storage]
pub type Blocks<T: Config> = StorageMap<_, Identity, T::Hash, (), OptionQuery>;
/// The Merkle tree of all blocks added to the blockchain.
#[pallet::storage]
#[pallet::unbounded]
pub(super) type BlocksCommitment<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
pub(super) type BlocksCommitmentMerkle<T> = IncrementalUnbalancedMerkleTree<BlocksCommitment<T>>;
/// The Merkle tree of all transactions within the current block.
#[pallet::storage]
#[pallet::unbounded]
pub(super) type BlockTransactionsCommitment<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
pub(super) type BlockTransactionsCommitmentMerkle<T> =
IncrementalUnbalancedMerkleTree<BlockTransactionsCommitment<T>>;
/// The hashes of events caused by the current transaction.
#[pallet::storage]
#[pallet::unbounded]
pub(super) type TransactionEvents<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
pub(super) type TransactionEventsMerkle<T> = IncrementalUnbalancedMerkleTree<
TransactionEvents<T>,
TRANSACTION_EVENTS_COMMITMENT_BRANCH_TAG,
TRANSACTION_EVENTS_COMMITMENT_LEAF_TAG,
>;
/// The roots of the Merkle trees of each transaction's events.
#[pallet::storage]
#[pallet::unbounded]
pub(super) type BlockEventsCommitment<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>;
pub(super) type BlockEventsCommitmentMerkle<T> = IncrementalUnbalancedMerkleTree<
BlockEventsCommitment<T>,
EVENTS_COMMITMENT_BRANCH_TAG,
EVENTS_COMMITMENT_LEAF_TAG,
>;
/// A mapping from an account to its next nonce.
#[pallet::storage]
pub type NextNonce<T: Config> =
StorageMap<_, Blake2_128Concat, T::AccountId, T::Nonce, ValueQuery>;
#[pallet::config]
pub trait Config:
frame_system::Config<
Block: sp_runtime::traits::Block<Header: sp_runtime::traits::Header<Hash: Into<[u8; 32]>>>,
>
{
}
#[pallet::pallet]
pub struct Pallet<T>(_);
impl<T: Config> Pallet<T> {
pub fn start_transaction() {
TransactionEventsMerkle::<T>::new_expecting_none();
}
// TODO: Have this called
pub fn on_event(event: impl TryInto<serai_abi::Event>) {
if let Ok(event) = event.try_into() {
TransactionEventsMerkle::<T>::append(&event);
}
}
pub fn end_transaction(transaction_hash: [u8; 32]) {
BlockTransactionsCommitmentMerkle::<T>::append(&transaction_hash);
let transaction_events_root = TransactionEventsMerkle::<T>::take().root;
// Append the leaf (the transaction's hash and its events' root) to the block's events'
// commitment
BlockEventsCommitmentMerkle::<T>::append(&(&transaction_hash, &transaction_events_root));
}
}
}
pub(super) use pallet::*;
pub struct StartOfBlock<T: Config>(PhantomData<T>);
impl<T: Config> frame_support::traits::PreInherents for StartOfBlock<T> {
fn pre_inherents() {
let parent_hash = frame_system::Pallet::<T>::parent_hash();
Blocks::<T>::set(parent_hash, Some(()));
// TODO: Better detection of genesis
if parent_hash == Default::default() {
BlocksCommitmentMerkle::<T>::new_expecting_none();
} else {
let parent_hash: [u8; 32] = parent_hash.into();
BlocksCommitmentMerkle::<T>::append(&parent_hash);
}
BlockTransactionsCommitmentMerkle::<T>::new_expecting_none();
BlockEventsCommitmentMerkle::<T>::new_expecting_none();
}
}
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(),
));
}
}

View File

@@ -1,11 +1,265 @@
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![recursion_limit = "256"]
#[cfg(feature = "std")] #[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
extern crate alloc;
use alloc::borrow::Cow;
use sp_core::sr25519::Public;
use sp_runtime::{Perbill, Weight, traits::Header as _};
use sp_version::RuntimeVersion;
#[rustfmt::skip]
use serai_abi::{
primitives::address::SeraiAddress, SubstrateHeader as Header, SubstrateBlock,
};
mod core_pallet;
type Block = SubstrateBlock;
/// The lookup for a SeraiAddress -> Public.
pub struct Lookup;
impl sp_runtime::traits::StaticLookup for Lookup {
type Source = SeraiAddress;
type Target = Public;
fn lookup(source: SeraiAddress) -> Result<Public, sp_runtime::traits::LookupError> {
Ok(source.into())
}
fn unlookup(source: Public) -> SeraiAddress {
source.into()
}
}
// TODO: Remove
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: Cow::Borrowed("serai"),
impl_name: Cow::Borrowed("core"),
authoring_version: 0,
spec_version: 0,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 0,
system_version: 0,
};
frame_support::parameter_types! {
pub const Version: RuntimeVersion = VERSION;
// TODO
pub BlockLength: frame_system::limits::BlockLength =
frame_system::limits::BlockLength::max_with_normal_ratio(0, Perbill::from_percent(0));
// TODO
pub BlockWeights: frame_system::limits::BlockWeights =
frame_system::limits::BlockWeights::with_sensible_defaults(
Weight::from_parts(0, 0),
Perbill::from_percent(0),
);
}
#[frame_support::runtime]
mod runtime {
use super::*;
#[runtime::runtime]
#[runtime::derive(RuntimeCall, RuntimeEvent, RuntimeError, RuntimeOrigin)]
pub struct Runtime;
#[runtime::pallet_index(0)]
pub type System = frame_system::Pallet<Runtime>;
#[runtime::pallet_index(1)]
pub type Core = core_pallet::Pallet<Runtime>;
}
impl frame_system::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = BlockWeights;
type BlockLength = BlockLength;
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type RuntimeTask = ();
type Nonce = u32;
type Hash = <Self::Block as sp_runtime::traits::Block>::Hash;
type Hashing = sp_runtime::traits::BlakeTwo256;
type AccountId = sp_core::sr25519::Public;
type Lookup = Lookup;
type Block = Block;
// Don't track old block hashes within the System pallet
// We use not a number -> hash index, but a hash -> () index, in our own pallet
type BlockHashCount = sp_core::ConstU64<1>;
type DbWeight = frame_support::weights::constants::RocksDbWeight;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = ();
type OnNewAccount = ();
type OnKilledAccount = ();
// We use the default weights as we never expose/call any of these methods
type SystemWeightInfo = ();
// We also don't use the provided extensions framework
type ExtensionsWeightInfo = ();
// We don't invoke any hooks on-set-code as we don't perform upgrades via the blockchain yet via
// nodes, ensuring everyone who upgrades consents to the rules they upgrade to
type OnSetCode = ();
type MaxConsumers = sp_core::ConstU32<{ u32::MAX }>;
// No migrations set
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
type PreInherents = core_pallet::StartOfBlock<Runtime>;
type PostInherents = ();
type PostTransactions = core_pallet::EndOfBlock<Runtime>;
}
impl core_pallet::Config for Runtime {}
impl From<Option<SeraiAddress>> for RuntimeOrigin {
fn from(signer: Option<SeraiAddress>) -> Self {
match signer {
None => RuntimeOrigin::none(),
Some(signer) => RuntimeOrigin::signed(signer.into()),
}
}
}
impl From<serai_abi::Call> for RuntimeCall {
fn from(call: serai_abi::Call) -> Self {
match call {
serai_abi::Call::Coins(call) => {
use serai_abi::coins::Call;
match call {
Call::transfer { .. } | Call::burn { .. } | Call::burn_with_instruction { .. } => {
todo!("TODO")
}
}
}
serai_abi::Call::ValidatorSets(call) => {
use serai_abi::validator_sets::Call;
match call {
Call::set_keys { .. } |
Call::report_slashes { .. } |
Call::set_embedded_elliptic_curve_keys { .. } |
Call::allocate { .. } |
Call::deallocate { .. } |
Call::claim_deallocation { .. } => todo!("TODO"),
}
}
serai_abi::Call::Signals(call) => {
use serai_abi::signals::Call;
match call {
Call::register_retirement_signal { .. } |
Call::revoke_retirement_signal { .. } |
Call::favor { .. } |
Call::revoke_favor { .. } |
Call::stand_against { .. } => todo!("TODO"),
}
}
serai_abi::Call::Dex(call) => {
use serai_abi::dex::Call;
match call {
Call::add_liquidity { .. } |
Call::transfer_liquidity { .. } |
Call::remove_liquidity { .. } |
Call::swap_exact { .. } |
Call::swap_for_exact { .. } => todo!("TODO"),
}
}
serai_abi::Call::GenesisLiquidity(call) => {
use serai_abi::genesis_liquidity::Call;
match call {
Call::oraclize_values { .. } | Call::remove_liquidity { .. } => todo!("TODO"),
}
}
serai_abi::Call::InInstructions(call) => {
use serai_abi::in_instructions::Call;
match call {
Call::execute_batch { .. } => todo!("TODO"),
}
}
}
}
}
type Executive = frame_executive::Executive<Runtime, Block, Context, Runtime, AllPalletsWithSystem>;
sp_api::impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
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) {
Executive::execute_block(block);
}
}
}
#[derive(Clone, Default, PartialEq, Eq, Debug)]
struct Context;
impl serai_abi::TransactionContext for Context {
// TODO
const SIGNED_WEIGHT: Weight = Weight::zero();
type RuntimeCall = RuntimeCall;
/// The implicit context to verify transactions with.
fn implicit_context() -> serai_abi::ImplicitContext {
serai_abi::ImplicitContext {
genesis: System::block_hash(0).into(),
protocol_id: [0; 32], // TODO via build script
}
}
/// 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()
}
/// The time embedded into the current block.
fn current_time(&self) -> Option<u64> {
todo!("TODO")
}
/// Get the next nonce for an account.
fn next_nonce(&self, signer: &SeraiAddress) -> u32 {
core_pallet::NextNonce::<Runtime>::get(signer)
}
/// If the signer can pay the SRI fee.
fn can_pay_fee(
&self,
signer: &SeraiAddress,
fee: serai_abi::primitives::balance::Amount,
) -> Result<(), sp_runtime::transaction_validity::TransactionValidityError> {
todo!("TODO")
}
fn start_transaction(&self) {
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);
}
/// Have the transaction pay its SRI fee.
fn pay_fee(
&self,
signer: &SeraiAddress,
fee: serai_abi::primitives::balance::Amount,
) -> Result<(), sp_runtime::transaction_validity::TransactionValidityError> {
todo!("TODO")
}
fn end_transaction(&self, transaction_hash: [u8; 32]) {
Core::end_transaction(transaction_hash);
}
}
/* TODO
use core::marker::PhantomData; use core::marker::PhantomData;
// Re-export all components // Re-export all components
@@ -73,29 +327,14 @@ use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
use babe::AuthorityId as BabeId; use babe::AuthorityId as BabeId;
use grandpa::AuthorityId as GrandpaId; use grandpa::AuthorityId as GrandpaId;
mod abi;
/// Nonce of a transaction in the chain, for a given account.
pub type Nonce = u32;
/// A hash of some data used by the chain. /// A hash of some data used by the chain.
pub type Hash = sp_core::H256; pub type Hash = sp_core::H256;
pub type SignedExtra = ( pub type SignedExtra = (
system::CheckNonZeroSender<Runtime>, system::CheckNonZeroSender<Runtime>,
system::CheckSpecVersion<Runtime>, system::CheckWeight<Runtime>, TODO
system::CheckTxVersion<Runtime>,
system::CheckGenesis<Runtime>,
system::CheckEra<Runtime>,
system::CheckNonce<Runtime>,
system::CheckWeight<Runtime>,
transaction_payment::ChargeTransactionPayment<Runtime>,
); );
pub type Transaction = serai_abi::tx::Transaction<RuntimeCall, SignedExtra>;
pub type Block = generic::Block<Header, Transaction>;
pub type BlockId = generic::BlockId<Block>;
pub mod opaque { pub mod opaque {
use super::*; use super::*;
@@ -107,22 +346,6 @@ pub mod opaque {
} }
} }
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("serai"),
impl_name: create_runtime_str!("core"),
spec_version: 1,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
};
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}
pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration = pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
sp_consensus_babe::BabeEpochConfiguration { sp_consensus_babe::BabeEpochConfiguration {
@@ -133,7 +356,6 @@ pub const BABE_GENESIS_EPOCH_CONFIG: sp_consensus_babe::BabeEpochConfiguration =
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
parameter_types! { parameter_types! {
pub const BlockHashCount: BlockNumber = 2400;
pub const Version: RuntimeVersion = VERSION; pub const Version: RuntimeVersion = VERSION;
pub const SS58Prefix: u8 = 42; // TODO: Remove for Bech32m pub const SS58Prefix: u8 = 42; // TODO: Remove for Bech32m
@@ -148,44 +370,6 @@ parameter_types! {
); );
} }
pub struct CallFilter;
impl Contains<RuntimeCall> for CallFilter {
fn contains(call: &RuntimeCall) -> bool {
// If the call is defined in our ABI, it's allowed
let call: Result<serai_abi::Call, ()> = call.clone().try_into();
call.is_ok()
}
}
impl system::Config for Runtime {
type BaseCallFilter = CallFilter;
type BlockWeights = BlockWeights;
type BlockLength = BlockLength;
type AccountId = PublicKey;
type RuntimeCall = RuntimeCall;
type Lookup = AccountLookup;
type Hash = Hash;
type Hashing = BlakeTwo256;
type Nonce = Nonce;
type Block = Block;
type RuntimeOrigin = RuntimeOrigin;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type DbWeight = RocksDbWeight;
type Version = Version;
type PalletInfo = PalletInfo;
type OnNewAccount = ();
type OnKilledAccount = ();
type OnSetCode = ();
type AccountData = ();
type SystemWeightInfo = ();
type SS58Prefix = SS58Prefix; // TODO: Remove for Bech32m
type MaxConsumers = support::traits::ConstU32<16>;
}
impl timestamp::Config for Runtime { impl timestamp::Config for Runtime {
type Moment = u64; type Moment = u64;
type OnTimestampSet = Babe; type OnTimestampSet = Babe;
@@ -319,14 +503,6 @@ impl grandpa::Config for Runtime {
grandpa::EquivocationReportSystem<Self, ValidatorSets, ValidatorSets, ReportLongevity>; grandpa::EquivocationReportSystem<Self, ValidatorSets, ValidatorSets, ReportLongevity>;
} }
pub type Executive = frame_executive::Executive<
Runtime,
Block,
system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
>;
construct_runtime!( construct_runtime!(
pub enum Runtime { pub enum Runtime {
System: system exclude_parts { Call }, System: system exclude_parts { Call },
@@ -627,3 +803,4 @@ sp_api::impl_runtime_apis! {
} }
} }
} }
*/

View File

@@ -3,7 +3,7 @@ name = "serai-signals-pallet"
version = "0.1.0" version = "0.1.0"
description = "Signals pallet" description = "Signals pallet"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/signals/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/signals"
authors = ["Luke Parker <lukeparker5132@gmail.com>"] authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -28,11 +28,10 @@ sp-io = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-nex
frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-system = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
serai-signals-primitives = { path = "../primitives", default-features = false }
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false } validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../validator-sets", default-features = false }
in-instructions-pallet = { package = "serai-in-instructions-pallet", path = "../../in-instructions/pallet", default-features = false } in-instructions-pallet = { package = "serai-in-instructions-pallet", path = "../in-instructions", default-features = false }
[features] [features]
std = [ std = [
@@ -46,7 +45,6 @@ std = [
"frame-support/std", "frame-support/std",
"serai-primitives/std", "serai-primitives/std",
"serai-signals-primitives/std",
"validator-sets-pallet/std", "validator-sets-pallet/std",
"in-instructions-pallet/std", "in-instructions-pallet/std",

View File

@@ -1,45 +0,0 @@
[package]
name = "serai-signals-primitives"
version = "0.1.0"
description = "Signals primitives"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/signals/primitives"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
zeroize = { version = "^1.5", features = ["derive"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
serai-primitives = { path = "../../primitives", version = "0.1", default-features = false }
[features]
std = [
"zeroize",
"scale/std",
"scale-info/std",
"borsh?/std",
"serde?/std",
"serai-primitives/std",
]
borsh = ["dep:borsh"]
serde = ["dep:serde"]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1 +0,0 @@

View File

@@ -3,7 +3,7 @@ name = "serai-validator-sets-pallet"
version = "0.1.0" version = "0.1.0"
description = "Validator sets pallet" description = "Validator sets pallet"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/pallet" repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets"
authors = ["Luke Parker <lukeparker5132@gmail.com>"] authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021" edition = "2021"
rust-version = "1.80" rust-version = "1.80"
@@ -38,20 +38,19 @@ frame-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "s
pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-grandpa = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../primitives", default-features = false }
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../primitives", default-features = false }
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false } coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
[dev-dependencies] [dev-dependencies]
pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } pallet-timestamp = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-consensus-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false } sp-consensus-babe = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
ciphersuite = { path = "../../../crypto/ciphersuite", features = ["ristretto"] } ciphersuite = { path = "../../crypto/ciphersuite", features = ["ristretto"] }
frost = { package = "modular-frost", path = "../../../crypto/frost", features = ["tests"] } frost = { package = "modular-frost", path = "../../crypto/frost", features = ["tests"] }
schnorrkel = { path = "../../../crypto/schnorrkel", package = "frost-schnorrkel" } schnorrkel = { path = "../../crypto/schnorrkel", package = "frost-schnorrkel" }
zeroize = "^1.5" zeroize = "^1.5"
rand_core = "0.6" rand_core = "0.6"
@@ -71,7 +70,7 @@ std = [
"sp-runtime/std", "sp-runtime/std",
"sp-session/std", "sp-session/std",
"sp-staking/std", "sp-staking/std",
"sp-consensus-babe/std", "sp-consensus-babe/std",
"frame-system/std", "frame-system/std",
@@ -82,7 +81,6 @@ std = [
"pallet-timestamp/std", "pallet-timestamp/std",
"serai-primitives/std", "serai-primitives/std",
"validator-sets-primitives/std",
"coins-pallet/std", "coins-pallet/std",
"dex-pallet/std", "dex-pallet/std",

View File

@@ -1,39 +0,0 @@
[package]
name = "serai-validator-sets-primitives"
version = "0.1.0"
description = "Primitives for validator sets"
license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/primitives"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021"
rust-version = "1.80"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
zeroize = { version = "^1.5", features = ["derive"], optional = true }
ciphersuite = { path = "../../../crypto/ciphersuite", version = "0.4", default-features = false, features = ["alloc", "ristretto"] }
dkg = { path = "../../../crypto/dkg", version = "0.5", default-features = false }
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "max-encoded-len"] }
scale-info = { version = "2", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
sp-std = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
serai-primitives = { path = "../../primitives", default-features = false }
[features]
std = ["zeroize", "ciphersuite/std", "dkg/std", "borsh?/std", "serde?/std", "scale/std", "scale-info/std", "sp-core/std", "sp-std/std", "serai-primitives/std"]
borsh = ["dep:borsh", "serai-primitives/borsh"]
serde = ["dep:serde", "serai-primitives/serde"]
default = ["std"]

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022-2023 Luke Parker
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.