mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +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
|
||||
|
||||
- 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
|
||||
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
|
||||
- name: Buld Rust docs
|
||||
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
|
||||
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",
|
||||
|
||||
"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/coins",
|
||||
"substrate/validator-sets",
|
||||
"substrate/signals",
|
||||
"substrate/dex",
|
||||
"substrate/genesis-liquidity",
|
||||
"substrate/economic-security",
|
||||
"substrate/emissions",
|
||||
"substrate/in-instructions",
|
||||
|
||||
"substrate/runtime",
|
||||
"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
|
||||
/// 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`.
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -54,11 +54,10 @@ macro_rules! create_db {
|
||||
)?;
|
||||
impl$(<$($generic_name: $generic_type),+>)? $field_name$(<$($generic_name),+>)? {
|
||||
pub(crate) fn key($($arg: $arg_type),*) -> Vec<u8> {
|
||||
use scale::Encode;
|
||||
$crate::serai_db_key(
|
||||
stringify!($db_name).as_bytes(),
|
||||
stringify!($field_name).as_bytes(),
|
||||
($($arg),*).encode()
|
||||
&borsh::to_vec(&($($arg),*)).unwrap(),
|
||||
)
|
||||
}
|
||||
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" }
|
||||
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"] }
|
||||
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"] }
|
||||
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"] }
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ borsh = { version = "1", default-features = false, features = ["std", "derive",
|
||||
|
||||
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" }
|
||||
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"] }
|
||||
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" }
|
||||
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"] }
|
||||
|
||||
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"] }
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, fea
|
||||
dkg = { path = "../../crypto/dkg", 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-task = { path = "../../common/task", version = "0.1" }
|
||||
|
||||
@@ -46,7 +46,7 @@ serai-db = { path = "../common/db", optional = true }
|
||||
|
||||
serai-env = { path = "../common/env" }
|
||||
|
||||
serai-primitives = { path = "../substrate/primitives", features = ["borsh"] }
|
||||
serai-primitives = { path = "../substrate/primitives", default-features = false, features = ["std"] }
|
||||
|
||||
[features]
|
||||
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
|
||||
|
||||
# Add the wasm toolchain
|
||||
RUN rustup component add rust-src
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN rustup target add wasmv1-none
|
||||
|
||||
FROM deterministic
|
||||
|
||||
|
||||
@@ -162,8 +162,7 @@ RUN apt install -y pkg-config clang
|
||||
RUN apt install -y make protobuf-compiler
|
||||
|
||||
# Add the wasm toolchain
|
||||
RUN rustup component add rust-src
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN rustup target add wasmv1-none
|
||||
|
||||
{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 }
|
||||
|
||||
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"] }
|
||||
|
||||
|
||||
@@ -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"] }
|
||||
|
||||
# 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
|
||||
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"] }
|
||||
|
||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
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-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||
|
||||
serai-cosign = { path = "../../coordinator/cosign", default-features = false }
|
||||
|
||||
@@ -20,8 +20,7 @@ workspace = true
|
||||
[dependencies]
|
||||
group = { version = "0.13", default-features = false }
|
||||
|
||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
serai-coins-primitives = { path = "../../substrate/coins/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
serai-primitives = { path = "../../substrate/primitives", 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"] }
|
||||
|
||||
@@ -36,9 +36,6 @@ serai-db = { path = "../../common/db" }
|
||||
messages = { package = "serai-processor-messages", path = "../messages" }
|
||||
|
||||
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" }
|
||||
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"] }
|
||||
|
||||
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" }
|
||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[toolchain]
|
||||
channel = "1.81"
|
||||
targets = ["wasm32-unknown-unknown"]
|
||||
channel = "1.85"
|
||||
targets = ["wasmv1-none"]
|
||||
profile = "minimal"
|
||||
components = ["rust-src", "rustfmt", "clippy"]
|
||||
components = ["rustfmt", "clippy"]
|
||||
|
||||
@@ -27,9 +27,9 @@ brew install rustup
|
||||
```
|
||||
rustup update
|
||||
rustup toolchain install stable
|
||||
rustup target add wasm32-unknown-unknown
|
||||
rustup target add wasmv1-none
|
||||
rustup toolchain install nightly
|
||||
rustup target add wasm32-unknown-unknown --toolchain nightly
|
||||
rustup target add wasmv1-none --toolchain nightly
|
||||
```
|
||||
|
||||
### Install Solidity
|
||||
|
||||
@@ -2,7 +2,20 @@ use alloc::vec::Vec;
|
||||
|
||||
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.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||
@@ -12,12 +25,28 @@ pub struct HeaderV1 {
|
||||
/// The genesis block has number 0.
|
||||
pub number: u64,
|
||||
/// 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.
|
||||
pub unix_time_in_millis: u64,
|
||||
/// 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: [u8; 32],
|
||||
pub transactions_commitment: UnbalancedMerkleTree,
|
||||
/// 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.
|
||||
pub consensus_commitment: [u8; 32],
|
||||
}
|
||||
@@ -37,17 +66,23 @@ impl Header {
|
||||
}
|
||||
}
|
||||
/// Get the commitment to the DAG this header builds upon.
|
||||
pub fn builds_upon(&self) -> BlockHash {
|
||||
pub fn builds_upon(&self) -> UnbalancedMerkleTree {
|
||||
match self {
|
||||
Header::V1(HeaderV1 { builds_upon, .. }) => *builds_upon,
|
||||
}
|
||||
}
|
||||
/// The commitment to the transactions within this block.
|
||||
pub fn transactions_commitment(&self) -> [u8; 32] {
|
||||
pub fn transactions_commitment(&self) -> UnbalancedMerkleTree {
|
||||
match self {
|
||||
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.
|
||||
pub fn hash(&self) -> BlockHash {
|
||||
BlockHash(sp_core::blake2_256(&borsh::to_vec(self).unwrap()))
|
||||
@@ -81,19 +116,33 @@ mod substrate {
|
||||
|
||||
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)]
|
||||
pub struct SeraiDigest {
|
||||
/// The commitment to the DAG this header builds upon.
|
||||
pub builds_upon: BlockHash,
|
||||
pub struct SeraiPreExecutionDigest {
|
||||
/// The UNIX time in milliseconds this block was created at.
|
||||
pub unix_time_in_millis: u64,
|
||||
/// The commitment to the transactions within this block.
|
||||
pub transactions_commitment: [u8; 32],
|
||||
}
|
||||
|
||||
impl SeraiDigest {
|
||||
const CONSENSUS_ID: [u8; 4] = *b"SRID";
|
||||
/// The digest for all of the Serai-specific header fields determined during execution of the
|
||||
/// 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.
|
||||
@@ -132,29 +181,43 @@ mod substrate {
|
||||
fn from(header: &SubstrateHeader) -> Self {
|
||||
match header {
|
||||
SubstrateHeader::V1(header) => {
|
||||
let digest =
|
||||
header.consensus.digest.logs().iter().find_map(|digest_item| match digest_item {
|
||||
let mut pre_execution_digest = None;
|
||||
let mut execution_digest = None;
|
||||
for log in header.consensus.digest.logs() {
|
||||
match log {
|
||||
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 {
|
||||
number: header.number,
|
||||
builds_upon: digest
|
||||
builds_upon: execution_digest
|
||||
.as_ref()
|
||||
.map(|digest| digest.builds_upon)
|
||||
.unwrap_or(BlockHash::from([0; 32])),
|
||||
unix_time_in_millis: digest
|
||||
.unwrap_or(UnbalancedMerkleTree::EMPTY),
|
||||
unix_time_in_millis: pre_execution_digest
|
||||
.as_ref()
|
||||
.map(|digest| digest.unix_time_in_millis)
|
||||
.unwrap_or(0),
|
||||
transactions_commitment: digest
|
||||
transactions_commitment: execution_digest
|
||||
.as_ref()
|
||||
.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()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -204,6 +204,26 @@ impl Transaction {
|
||||
explicit_context.serialize(&mut message).unwrap();
|
||||
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")]
|
||||
@@ -268,7 +288,7 @@ mod substrate {
|
||||
>;
|
||||
|
||||
/// The implicit context to verify transactions with.
|
||||
fn implicit_context() -> &'static ImplicitContext;
|
||||
fn implicit_context() -> ImplicitContext;
|
||||
|
||||
/// If a block is present in the blockchain.
|
||||
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.
|
||||
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;
|
||||
/// If the signer can pay the SRI fee.
|
||||
fn can_pay_fee(
|
||||
@@ -284,8 +304,15 @@ mod substrate {
|
||||
signer: &SeraiAddress,
|
||||
fee: Amount,
|
||||
) -> 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.
|
||||
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.
|
||||
@@ -339,7 +366,7 @@ mod substrate {
|
||||
contextualized_signature: ContextualizedSignature { explicit_context, signature },
|
||||
} => {
|
||||
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(),
|
||||
&sp_core::sr25519::Public::from(explicit_context.signer),
|
||||
) {
|
||||
@@ -454,6 +481,7 @@ mod substrate {
|
||||
self.1.can_pay_fee(signer, *fee)?;
|
||||
|
||||
// Prioritize transactions by their fees
|
||||
// TODO: Re-evaluate this
|
||||
{
|
||||
let fee = fee.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
|
||||
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 } => {
|
||||
let call = Context::RuntimeCall::from(call.0);
|
||||
V::pre_dispatch(&call)?;
|
||||
@@ -486,7 +519,9 @@ mod substrate {
|
||||
contextualized_signature:
|
||||
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)?;
|
||||
|
||||
let _res = frame_support::storage::transactional::with_storage_layer(|| {
|
||||
@@ -513,7 +548,14 @@ mod substrate {
|
||||
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 {
|
||||
/// Set the keys for a validator set.
|
||||
set_keys {
|
||||
/// The network whose latest validator set is setting their keys.
|
||||
network: ExternalNetworkId,
|
||||
/// The validator set which is setting their keys.
|
||||
validator_set: ExternalValidatorSet,
|
||||
/// The keys being set.
|
||||
key_pair: KeyPair,
|
||||
/// 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_slashes {
|
||||
/// The network whose retiring validator set is setting their keys.
|
||||
network: ExternalNetworkId,
|
||||
/// The validator set which is setting their keys.
|
||||
validator_set: ExternalValidatorSet,
|
||||
/// The slashes they're reporting.
|
||||
slashes: SlashReport,
|
||||
/// The signature confirming the validity of this slash report.
|
||||
|
||||
@@ -61,7 +61,6 @@ serai-docker-tests = { path = "../../tests/docker" }
|
||||
|
||||
[features]
|
||||
serai = ["thiserror/std", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
|
||||
borsh = []
|
||||
|
||||
networks = []
|
||||
bitcoin = ["networks", "dep:bitcoin"]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "serai-coins-pallet"
|
||||
version = "0.1.0"
|
||||
description = "Coins pallet for Serai"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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 }
|
||||
|
||||
serai-primitives = { path = "../../primitives", default-features = false, features = ["serde"] }
|
||||
coins-primitives = { package = "serai-coins-primitives", path = "../primitives", default-features = false }
|
||||
serai-primitives = { path = "../primitives", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
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",
|
||||
|
||||
"serai-primitives/std",
|
||||
"coins-primitives/std",
|
||||
]
|
||||
|
||||
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"
|
||||
description = "DEX pallet for Serai"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-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]
|
||||
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }
|
||||
@@ -3,7 +3,7 @@ name = "serai-economic-security-pallet"
|
||||
version = "0.1.0"
|
||||
description = "Economic Security pallet for Serai"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-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 }
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../dex", 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]
|
||||
@@ -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-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-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"
|
||||
description = "Emissions pallet for Serai"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-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 }
|
||||
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false }
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
|
||||
genesis-liquidity-pallet = { package = "serai-genesis-liquidity-pallet", path = "../../genesis-liquidity/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", 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", 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 }
|
||||
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 }
|
||||
serai-primitives = { path = "../primitives", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
@@ -58,8 +56,6 @@ std = [
|
||||
"economic-security-pallet/std",
|
||||
|
||||
"serai-primitives/std",
|
||||
"emissions-primitives/std",
|
||||
]
|
||||
fast-epoch = []
|
||||
try-runtime = [] # TODO
|
||||
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"
|
||||
description = "Genesis liquidity pallet for Serai"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-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 }
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
||||
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false }
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../dex", 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", 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 }
|
||||
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 }
|
||||
serai-primitives = { path = "../primitives", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
@@ -58,10 +56,7 @@ std = [
|
||||
"economic-security-pallet/std",
|
||||
|
||||
"serai-primitives/std",
|
||||
"genesis-liquidity-primitives/std",
|
||||
"validator-sets-primitives/std",
|
||||
]
|
||||
try-runtime = [] # TODO
|
||||
fast-epoch = []
|
||||
|
||||
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"
|
||||
description = "Execute calls via In Instructions from unsigned transactions"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/genesis-liquidity"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
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-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
|
||||
|
||||
serai-primitives = { path = "../../primitives", default-features = false }
|
||||
in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../primitives", default-features = false }
|
||||
serai-primitives = { path = "../primitives", 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 }
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../coins", 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", 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", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
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-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]
|
||||
std = [
|
||||
@@ -64,7 +64,6 @@ std = [
|
||||
"frame-support/std",
|
||||
|
||||
"serai-primitives/std",
|
||||
"in-instructions-primitives/std",
|
||||
|
||||
"coins-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]
|
||||
default = []
|
||||
fast-epoch = ["serai-runtime/fast-epoch"]
|
||||
runtime-benchmarks = [
|
||||
"frame-benchmarking/runtime-benchmarks",
|
||||
|
||||
|
||||
@@ -28,8 +28,9 @@ dkg = { path = "../../crypto/dkg", default-features = false }
|
||||
|
||||
bech32 = { version = "0.11", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
||||
|
||||
[features]
|
||||
std = ["zeroize/std", "borsh/std", "ciphersuite/std", "dkg/std", "sp-core/std", "bech32/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
|
||||
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 {
|
||||
/// Generate an address for use by the system.
|
||||
///
|
||||
|
||||
@@ -43,14 +43,15 @@ pub mod signals;
|
||||
/// Instruction types.
|
||||
pub mod instructions;
|
||||
|
||||
/// Merkle trees.
|
||||
pub mod merkle;
|
||||
|
||||
/// 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.
|
||||
/// For non-linear structures, this would presumably be the zero-indexed position within some
|
||||
/// topological order.
|
||||
#[derive(
|
||||
Clone, Copy, Default, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize,
|
||||
)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
|
||||
pub struct BlockNumber(pub u64);
|
||||
impl From<u64> for 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.
|
||||
*/
|
||||
#[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]);
|
||||
impl From<[u8; 32]> for BlockHash {
|
||||
fn from(hash: [u8; 32]) -> BlockHash {
|
||||
@@ -77,3 +80,7 @@ impl From<sp_core::H256> for BlockHash {
|
||||
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]
|
||||
name = "serai-runtime"
|
||||
version = "0.1.0"
|
||||
description = "Serai network node runtime, built over Substrate"
|
||||
description = "Serai's on-chain logic"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/runtime"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
@@ -19,61 +19,21 @@ ignored = ["scale", "scale-info"]
|
||||
workspace = true
|
||||
|
||||
[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-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 }
|
||||
|
||||
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-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-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-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-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]
|
||||
substrate-wasm-builder = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next" }
|
||||
@@ -84,21 +44,7 @@ std = [
|
||||
"scale-info/std",
|
||||
|
||||
"sp-core/std",
|
||||
"sp-std/std",
|
||||
|
||||
"sp-offchain/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-api/std",
|
||||
|
||||
@@ -106,50 +52,10 @@ std = [
|
||||
"frame-support/std",
|
||||
"frame-executive/std",
|
||||
|
||||
"serai-primitives/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 = [
|
||||
"genesis-liquidity-pallet/fast-epoch",
|
||||
"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",
|
||||
]
|
||||
try-runtime = ["sp-runtime/try-runtime", "serai-abi/try-runtime", "frame-system/try-runtime", "frame-support/try-runtime", "frame-executive/try-runtime"]
|
||||
runtime-benchmarks = ["sp-runtime/runtime-benchmarks", "frame-system/runtime-benchmarks", "frame-support/runtime-benchmarks"]
|
||||
|
||||
default = ["std"]
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
use substrate_wasm_builder::WasmBuilder;
|
||||
|
||||
fn main() {
|
||||
WasmBuilder::new()
|
||||
.with_current_project()
|
||||
// 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()
|
||||
#[cfg(feature = "std")]
|
||||
substrate_wasm_builder::WasmBuilder::build_using_defaults();
|
||||
}
|
||||
|
||||
@@ -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(not(feature = "std"), no_std)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
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;
|
||||
|
||||
// Re-export all components
|
||||
@@ -73,29 +327,14 @@ use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
||||
use babe::AuthorityId as BabeId;
|
||||
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.
|
||||
pub type Hash = sp_core::H256;
|
||||
|
||||
pub type SignedExtra = (
|
||||
system::CheckNonZeroSender<Runtime>,
|
||||
system::CheckSpecVersion<Runtime>,
|
||||
system::CheckTxVersion<Runtime>,
|
||||
system::CheckGenesis<Runtime>,
|
||||
system::CheckEra<Runtime>,
|
||||
system::CheckNonce<Runtime>,
|
||||
system::CheckWeight<Runtime>,
|
||||
transaction_payment::ChargeTransactionPayment<Runtime>,
|
||||
system::CheckWeight<Runtime>, TODO
|
||||
);
|
||||
|
||||
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 {
|
||||
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 BABE_GENESIS_EPOCH_CONFIG: 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);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: BlockNumber = 2400;
|
||||
pub const Version: RuntimeVersion = VERSION;
|
||||
|
||||
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 {
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = Babe;
|
||||
@@ -319,14 +503,6 @@ impl grandpa::Config for Runtime {
|
||||
grandpa::EquivocationReportSystem<Self, ValidatorSets, ValidatorSets, ReportLongevity>;
|
||||
}
|
||||
|
||||
pub type Executive = frame_executive::Executive<
|
||||
Runtime,
|
||||
Block,
|
||||
system::ChainContext<Runtime>,
|
||||
Runtime,
|
||||
AllPalletsWithSystem,
|
||||
>;
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Runtime {
|
||||
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"
|
||||
description = "Signals pallet"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-support = { git = "https://github.com/serai-dex/polkadot-sdk", branch = "serai-next", default-features = false }
|
||||
|
||||
serai-primitives = { path = "../../primitives", default-features = false }
|
||||
serai-signals-primitives = { path = "../primitives", default-features = false }
|
||||
serai-primitives = { path = "../primitives", default-features = false }
|
||||
|
||||
validator-sets-pallet = { package = "serai-validator-sets-pallet", path = "../../validator-sets/pallet", default-features = false }
|
||||
in-instructions-pallet = { package = "serai-in-instructions-pallet", path = "../../in-instructions/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", default-features = false }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
@@ -46,7 +45,6 @@ std = [
|
||||
"frame-support/std",
|
||||
|
||||
"serai-primitives/std",
|
||||
"serai-signals-primitives/std",
|
||||
|
||||
"validator-sets-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"
|
||||
description = "Validator sets pallet"
|
||||
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>"]
|
||||
edition = "2021"
|
||||
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-grandpa = { 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 = "../primitives", default-features = false }
|
||||
serai-primitives = { path = "../primitives", 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 }
|
||||
coins-pallet = { package = "serai-coins-pallet", path = "../coins", default-features = false }
|
||||
dex-pallet = { package = "serai-dex-pallet", path = "../dex", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
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 }
|
||||
|
||||
ciphersuite = { path = "../../../crypto/ciphersuite", features = ["ristretto"] }
|
||||
frost = { package = "modular-frost", path = "../../../crypto/frost", features = ["tests"] }
|
||||
schnorrkel = { path = "../../../crypto/schnorrkel", package = "frost-schnorrkel" }
|
||||
ciphersuite = { path = "../../crypto/ciphersuite", features = ["ristretto"] }
|
||||
frost = { package = "modular-frost", path = "../../crypto/frost", features = ["tests"] }
|
||||
schnorrkel = { path = "../../crypto/schnorrkel", package = "frost-schnorrkel" }
|
||||
|
||||
zeroize = "^1.5"
|
||||
rand_core = "0.6"
|
||||
@@ -82,7 +81,6 @@ std = [
|
||||
"pallet-timestamp/std",
|
||||
|
||||
"serai-primitives/std",
|
||||
"validator-sets-primitives/std",
|
||||
|
||||
"coins-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