mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-12 14:09:25 +00:00
Compare commits
5 Commits
a2d558ee34
...
1a766ab773
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a766ab773 | ||
|
|
df2ae10d2f | ||
|
|
b92ac4a15b | ||
|
|
51bae4fedc | ||
|
|
ee8b353132 |
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -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
|
||||||
|
|||||||
2
.github/workflows/pages.yml
vendored
2
.github/workflows/pages.yml
vendored
@@ -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
316
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
32
Cargo.toml
32
Cargo.toml
@@ -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",
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
@@ -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"] }
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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 = [
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -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"] }
|
||||||
@@ -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 }
|
||||||
@@ -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"]
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -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;
|
|
||||||
@@ -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"]
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -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",
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -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",
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -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 {}
|
||||||
|
|||||||
177
substrate/primitives/src/merkle.rs
Normal file
177
substrate/primitives/src/merkle.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(())?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
172
substrate/runtime/src/core_pallet.rs
Normal file
172
substrate/runtime/src/core_pallet.rs
Normal 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(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|||||||
@@ -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",
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
@@ -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"
|
||||||
@@ -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",
|
||||||
@@ -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"]
|
|
||||||
@@ -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.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
|
|
||||||
Reference in New Issue
Block a user