mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 13:39:25 +00:00
Get all processors to compile again
Requires splitting `serai-cosign` into `serai-cosign` and `serai-cosign-types` so the processor don't require `serai-client/serai` (not correct yet).
This commit is contained in:
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@@ -61,6 +61,7 @@ jobs:
|
|||||||
-p serai-monero-processor \
|
-p serai-monero-processor \
|
||||||
-p tendermint-machine \
|
-p tendermint-machine \
|
||||||
-p tributary-sdk \
|
-p tributary-sdk \
|
||||||
|
-p serai-cosign-types \
|
||||||
-p serai-cosign \
|
-p serai-cosign \
|
||||||
-p serai-coordinator-substrate \
|
-p serai-coordinator-substrate \
|
||||||
-p serai-coordinator-tributary \
|
-p serai-coordinator-tributary \
|
||||||
|
|||||||
32
Cargo.lock
generated
32
Cargo.lock
generated
@@ -9706,7 +9706,6 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"secp256k1 0.29.1",
|
"secp256k1 0.29.1",
|
||||||
"serai-client",
|
"serai-client",
|
||||||
@@ -9896,11 +9895,21 @@ dependencies = [
|
|||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"schnorrkel",
|
"schnorrkel",
|
||||||
"serai-client",
|
"serai-client",
|
||||||
|
"serai-cosign-types",
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-task",
|
"serai-task",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serai-cosign-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"borsh",
|
||||||
|
"schnorrkel",
|
||||||
|
"serai-primitives",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serai-db"
|
name = "serai-db"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -9999,7 +10008,6 @@ dependencies = [
|
|||||||
"k256",
|
"k256",
|
||||||
"log",
|
"log",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serai-client",
|
"serai-client",
|
||||||
"serai-db",
|
"serai-db",
|
||||||
@@ -10136,7 +10144,6 @@ dependencies = [
|
|||||||
"modular-frost",
|
"modular-frost",
|
||||||
"monero-simple-request-rpc",
|
"monero-simple-request-rpc",
|
||||||
"monero-wallet",
|
"monero-wallet",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serai-client",
|
"serai-client",
|
||||||
@@ -10258,6 +10265,7 @@ dependencies = [
|
|||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"scale-info",
|
"scale-info",
|
||||||
|
"schnorrkel",
|
||||||
"sp-core",
|
"sp-core",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@@ -10272,8 +10280,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
"serai-cosign-types",
|
||||||
"serai-cosign",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-env",
|
"serai-env",
|
||||||
"serai-message-queue",
|
"serai-message-queue",
|
||||||
@@ -10355,7 +10362,6 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"group",
|
"group",
|
||||||
"k256",
|
"k256",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"revm",
|
"revm",
|
||||||
"serai-client",
|
"serai-client",
|
||||||
@@ -10375,7 +10381,6 @@ dependencies = [
|
|||||||
"borsh",
|
"borsh",
|
||||||
"log",
|
"log",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
@@ -10392,7 +10397,6 @@ dependencies = [
|
|||||||
"dkg-evrf",
|
"dkg-evrf",
|
||||||
"flexible-transcript",
|
"flexible-transcript",
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serai-db",
|
"serai-db",
|
||||||
@@ -10408,8 +10412,7 @@ dependencies = [
|
|||||||
"borsh",
|
"borsh",
|
||||||
"dkg",
|
"dkg",
|
||||||
"hex",
|
"hex",
|
||||||
"parity-scale-codec",
|
"serai-cosign-types",
|
||||||
"serai-cosign",
|
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10420,7 +10423,6 @@ dependencies = [
|
|||||||
"borsh",
|
"borsh",
|
||||||
"group",
|
"group",
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-task",
|
"serai-task",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -10435,7 +10437,6 @@ dependencies = [
|
|||||||
"group",
|
"group",
|
||||||
"hex",
|
"hex",
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-processor-messages",
|
"serai-processor-messages",
|
||||||
@@ -10451,7 +10452,6 @@ dependencies = [
|
|||||||
"borsh",
|
"borsh",
|
||||||
"ciphersuite 0.4.2",
|
"ciphersuite 0.4.2",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -10466,9 +10466,8 @@ dependencies = [
|
|||||||
"frost-schnorrkel",
|
"frost-schnorrkel",
|
||||||
"log",
|
"log",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"parity-scale-codec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"serai-cosign",
|
"serai-cosign-types",
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-processor-frost-attempt-manager",
|
"serai-processor-frost-attempt-manager",
|
||||||
@@ -10486,7 +10485,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"group",
|
"group",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-processor-primitives",
|
"serai-processor-primitives",
|
||||||
"serai-processor-scanner",
|
"serai-processor-scanner",
|
||||||
@@ -10499,7 +10497,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"group",
|
"group",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-processor-primitives",
|
"serai-processor-primitives",
|
||||||
@@ -10514,7 +10511,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"borsh",
|
"borsh",
|
||||||
"group",
|
"group",
|
||||||
"parity-scale-codec",
|
|
||||||
"serai-db",
|
"serai-db",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-processor-primitives",
|
"serai-processor-primitives",
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ members = [
|
|||||||
|
|
||||||
"coordinator/tributary-sdk/tendermint",
|
"coordinator/tributary-sdk/tendermint",
|
||||||
"coordinator/tributary-sdk",
|
"coordinator/tributary-sdk",
|
||||||
|
"coordinator/cosign/types",
|
||||||
"coordinator/cosign",
|
"coordinator/cosign",
|
||||||
"coordinator/substrate",
|
"coordinator/substrate",
|
||||||
"coordinator/tributary",
|
"coordinator/tributary",
|
||||||
|
|||||||
@@ -31,3 +31,5 @@ tokio = { version = "1", default-features = false }
|
|||||||
|
|
||||||
serai-db = { path = "../../common/db", version = "0.1.1" }
|
serai-db = { path = "../../common/db", version = "0.1.1" }
|
||||||
serai-task = { path = "../../common/task", version = "0.1" }
|
serai-task = { path = "../../common/task", version = "0.1" }
|
||||||
|
|
||||||
|
serai-cosign-types = { path = "./types" }
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ use serai_client::{
|
|||||||
use serai_db::*;
|
use serai_db::*;
|
||||||
use serai_task::*;
|
use serai_task::*;
|
||||||
|
|
||||||
|
use serai_cosign_types::*;
|
||||||
|
|
||||||
/// The cosigns which are intended to be performed.
|
/// The cosigns which are intended to be performed.
|
||||||
mod intend;
|
mod intend;
|
||||||
/// The evaluator of the cosigns.
|
/// The evaluator of the cosigns.
|
||||||
|
|||||||
25
coordinator/cosign/types/Cargo.toml
Normal file
25
coordinator/cosign/types/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "serai-cosign-types"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Evaluator of cosigns for the Serai network"
|
||||||
|
license = "AGPL-3.0-only"
|
||||||
|
repository = "https://github.com/serai-dex/serai/tree/develop/coordinator/cosign"
|
||||||
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
|
keywords = []
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
rust-version = "1.85"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
all-features = true
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
schnorrkel = { version = "0.11", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
|
serai-primitives = { path = "../../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
15
coordinator/cosign/types/LICENSE
Normal file
15
coordinator/cosign/types/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
AGPL-3.0-only license
|
||||||
|
|
||||||
|
Copyright (c) 2023-2025 Luke Parker
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License Version 3 as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
72
coordinator/cosign/types/src/lib.rs
Normal file
72
coordinator/cosign/types/src/lib.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
//! Types used when cosigning Serai. For more info, please see `serai-cosign`.
|
||||||
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
|
use serai_primitives::{crypto::Public, network_id::ExternalNetworkId};
|
||||||
|
|
||||||
|
/// The schnorrkel context to used when signing a cosign.
|
||||||
|
pub const COSIGN_CONTEXT: &[u8] = b"/serai/coordinator/cosign";
|
||||||
|
|
||||||
|
/// An intended cosign.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
|
pub struct CosignIntent {
|
||||||
|
/// The global session this cosign is being performed under.
|
||||||
|
pub global_session: [u8; 32],
|
||||||
|
/// The number of the block to cosign.
|
||||||
|
pub block_number: u64,
|
||||||
|
/// The hash of the block to cosign.
|
||||||
|
pub block_hash: [u8; 32],
|
||||||
|
/// If this cosign must be handled before further cosigns are.
|
||||||
|
pub notable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A cosign.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
|
pub struct Cosign {
|
||||||
|
/// The global session this cosign is being performed under.
|
||||||
|
pub global_session: [u8; 32],
|
||||||
|
/// The number of the block to cosign.
|
||||||
|
pub block_number: u64,
|
||||||
|
/// The hash of the block to cosign.
|
||||||
|
pub block_hash: [u8; 32],
|
||||||
|
/// The actual cosigner.
|
||||||
|
pub cosigner: ExternalNetworkId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CosignIntent {
|
||||||
|
/// Convert this into a `Cosign`.
|
||||||
|
pub fn into_cosign(self, cosigner: ExternalNetworkId) -> Cosign {
|
||||||
|
let CosignIntent { global_session, block_number, block_hash, notable: _ } = self;
|
||||||
|
Cosign { global_session, block_number, block_hash, cosigner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cosign {
|
||||||
|
/// The message to sign to sign this cosign.
|
||||||
|
///
|
||||||
|
/// This must be signed with schnorrkel, the context set to `COSIGN_CONTEXT`.
|
||||||
|
pub fn signature_message(&self) -> Vec<u8> {
|
||||||
|
// We use a schnorrkel context to domain-separate this
|
||||||
|
borsh::to_vec(self).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A signed cosign.
|
||||||
|
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
|
pub struct SignedCosign {
|
||||||
|
/// The cosign.
|
||||||
|
pub cosign: Cosign,
|
||||||
|
/// The signature for the cosign.
|
||||||
|
pub signature: [u8; 64],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SignedCosign {
|
||||||
|
/// Verify a cosign's signature.
|
||||||
|
pub fn verify_signature(&self, signer: Public) -> bool {
|
||||||
|
let Ok(signer) = schnorrkel::PublicKey::from_bytes(&signer.0) else { return false };
|
||||||
|
let Ok(signature) = schnorrkel::Signature::from_bytes(&self.signature) else { return false };
|
||||||
|
|
||||||
|
signer.verify_simple(COSIGN_CONTEXT, &self.cosign.signature_message(), &signature).is_ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,14 +20,13 @@ workspace = true
|
|||||||
zeroize = { version = "1", default-features = false, features = ["std"] }
|
zeroize = { version = "1", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||||
dkg = { package = "dkg-evrf", path = "../../crypto/dkg/evrf", default-features = false, features = ["std", "ristretto"] }
|
dkg = { package = "dkg-evrf", path = "../../crypto/dkg/evrf", default-features = false, features = ["std", "ristretto"] }
|
||||||
|
|
||||||
serai-client = { path = "../../substrate/client", default-features = false }
|
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
serai-cosign = { path = "../../coordinator/cosign" }
|
serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" }
|
||||||
|
|
||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
env_logger = { version = "0.10", default-features = false, features = ["humantime"] }
|
env_logger = { version = "0.10", default-features = false, features = ["humantime"] }
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ use std::sync::{LazyLock, Arc, Mutex};
|
|||||||
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
use serai_client::{
|
use serai_primitives::{
|
||||||
primitives::Signature,
|
crypto::Signature,
|
||||||
validator_sets::primitives::{Session, SlashReport},
|
validator_sets::{Session, SlashReport},
|
||||||
in_instructions::primitives::SignedBatch,
|
instructions::SignedBatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serai_cosign::SignedCosign;
|
use serai_cosign::SignedCosign;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use ciphersuite::{
|
|||||||
};
|
};
|
||||||
use dkg::{Curves, Ristretto};
|
use dkg::{Curves, Ristretto};
|
||||||
|
|
||||||
use serai_client::validator_sets::primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_env as env;
|
use serai_env as env;
|
||||||
use serai_db::{Get, DbTxn, Db as DbTrait, create_db, db_channel};
|
use serai_db::{Get, DbTxn, Db as DbTrait, create_db, db_channel};
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ workspace = true
|
|||||||
rand_core = { version = "0.6", default-features = false }
|
rand_core = { version = "0.6", default-features = false }
|
||||||
|
|
||||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -10,12 +10,15 @@ use bitcoin_serai::{
|
|||||||
wallet::ReceivedOutput as WalletOutput,
|
wallet::ReceivedOutput as WalletOutput,
|
||||||
};
|
};
|
||||||
|
|
||||||
use scale::{Encode, Decode, IoReader};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::Get;
|
use serai_db::Get;
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalCoin, Amount, ExternalBalance, ExternalAddress},
|
primitives::{
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
address::ExternalAddress,
|
||||||
|
},
|
||||||
networks::bitcoin::Address,
|
networks::bitcoin::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,7 +29,7 @@ use crate::{
|
|||||||
scan::{offsets_for_key, presumed_origin, extract_serai_data},
|
scan::{offsets_for_key, presumed_origin, extract_serai_data},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Encode, Decode, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
pub(crate) struct OutputId([u8; 36]);
|
pub(crate) struct OutputId([u8; 36]);
|
||||||
impl Default for OutputId {
|
impl Default for OutputId {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@@ -139,7 +142,7 @@ impl ReceivedOutput<<Secp256k1 as Ciphersuite>::G, Address> for Output {
|
|||||||
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||||
self.kind.write(writer)?;
|
self.kind.write(writer)?;
|
||||||
let presumed_origin: Option<ExternalAddress> = self.presumed_origin.clone().map(Into::into);
|
let presumed_origin: Option<ExternalAddress> = self.presumed_origin.clone().map(Into::into);
|
||||||
writer.write_all(&presumed_origin.encode())?;
|
presumed_origin.serialize(writer)?;
|
||||||
self.output.write(writer)?;
|
self.output.write(writer)?;
|
||||||
writer.write_all(&u16::try_from(self.data.len()).unwrap().to_le_bytes())?;
|
writer.write_all(&u16::try_from(self.data.len()).unwrap().to_le_bytes())?;
|
||||||
writer.write_all(&self.data)
|
writer.write_all(&self.data)
|
||||||
@@ -149,7 +152,7 @@ impl ReceivedOutput<<Secp256k1 as Ciphersuite>::G, Address> for Output {
|
|||||||
Ok(Output {
|
Ok(Output {
|
||||||
kind: OutputType::read(reader)?,
|
kind: OutputType::read(reader)?,
|
||||||
presumed_origin: {
|
presumed_origin: {
|
||||||
Option::<ExternalAddress>::decode(&mut IoReader(&mut reader))
|
Option::<ExternalAddress>::deserialize_reader(&mut reader)
|
||||||
.map_err(|e| io::Error::other(format!("couldn't decode ExternalAddress: {e:?}")))?
|
.map_err(|e| io::Error::other(format!("couldn't decode ExternalAddress: {e:?}")))?
|
||||||
.map(|address| {
|
.map(|address| {
|
||||||
Address::try_from(address)
|
Address::try_from(address)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use core::future::Future;
|
|||||||
|
|
||||||
use bitcoin_serai::rpc::{RpcError, Rpc as BRpc};
|
use bitcoin_serai::rpc::{RpcError, Rpc as BRpc};
|
||||||
|
|
||||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
use serai_client::primitives::{network_id::ExternalNetworkId, coin::ExternalCoin, balance::Amount};
|
||||||
|
|
||||||
use serai_db::Db;
|
use serai_db::Db;
|
||||||
use scanner::ScannerFeed;
|
use scanner::ScannerFeed;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use bitcoin_serai::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalCoin, Amount},
|
primitives::{coin::ExternalCoin, balance::Amount},
|
||||||
networks::bitcoin::Address,
|
networks::bitcoin::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ rand_core = { version = "0.6", default-features = false }
|
|||||||
|
|
||||||
const-hex = { version = "1", default-features = false, features = ["std"] }
|
const-hex = { version = "1", default-features = false, features = ["std"] }
|
||||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ ethereum-primitives = { package = "serai-processor-ethereum-primitives", path =
|
|||||||
ethereum-deployer = { package = "serai-processor-ethereum-deployer", path = "../deployer", default-features = false }
|
ethereum-deployer = { package = "serai-processor-ethereum-deployer", path = "../deployer", default-features = false }
|
||||||
erc20 = { package = "serai-processor-ethereum-erc20", path = "../erc20", default-features = false }
|
erc20 = { package = "serai-processor-ethereum-erc20", path = "../erc20", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
serai-client = { path = "../../../substrate/client", default-features = false, features = ["ethereum"] }
|
serai-client = { path = "../../../substrate/client", default-features = false, features = ["ethereum"] }
|
||||||
|
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ interface IRouterWithoutCollisions {
|
|||||||
/// @param from The address which called `inInstruction` and caused this event to be emitted
|
/// @param from The address which called `inInstruction` and caused this event to be emitted
|
||||||
/// @param coin The coin transferred in
|
/// @param coin The coin transferred in
|
||||||
/// @param amount The amount of the coin transferred in
|
/// @param amount The amount of the coin transferred in
|
||||||
/// @param instruction The Shorthand-encoded InInstruction for Serai to decode and handle
|
/// @param instruction The encoded `RefundableInInstruction` for Serai to decode and handle
|
||||||
event InInstruction(
|
event InInstruction(
|
||||||
address indexed from, address indexed coin, uint256 amount, bytes instruction
|
address indexed from, address indexed coin, uint256 amount, bytes instruction
|
||||||
);
|
);
|
||||||
@@ -81,7 +81,7 @@ interface IRouterWithoutCollisions {
|
|||||||
/// @param coin The coin to transfer in (address(0) if Ether)
|
/// @param coin The coin to transfer in (address(0) if Ether)
|
||||||
/// @param amount The amount to transfer in (msg.value if Ether)
|
/// @param amount The amount to transfer in (msg.value if Ether)
|
||||||
/**
|
/**
|
||||||
* @param instruction The Shorthand-encoded InInstruction for Serai to associate with this
|
* @param instruction The encoded `RefundableInInstruction` for Serai to associate with this
|
||||||
* transfer in
|
* transfer in
|
||||||
*/
|
*/
|
||||||
// Re-entrancy doesn't bork this function
|
// Re-entrancy doesn't bork this function
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ contract Router is IRouterWithoutCollisions {
|
|||||||
/// @param coin The coin to transfer in (address(0) if Ether)
|
/// @param coin The coin to transfer in (address(0) if Ether)
|
||||||
/// @param amount The amount to transfer in (msg.value if Ether)
|
/// @param amount The amount to transfer in (msg.value if Ether)
|
||||||
/**
|
/**
|
||||||
* @param instruction The Shorthand-encoded InInstruction for Serai to associate with this
|
* @param instruction The encoded `RefundableInInstruction` for Serai to associate with this
|
||||||
* transfer in
|
* transfer in
|
||||||
*/
|
*/
|
||||||
// This function doesn't require nonReentrant as re-entrancy isn't an issue with this function
|
// This function doesn't require nonReentrant as re-entrancy isn't an issue with this function
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ use alloy_rpc_types_eth::{BlockId, Log, Filter, TransactionInput, TransactionReq
|
|||||||
use alloy_transport::{TransportErrorKind, RpcError};
|
use alloy_transport::{TransportErrorKind, RpcError};
|
||||||
use alloy_provider::{Provider, RootProvider};
|
use alloy_provider::{Provider, RootProvider};
|
||||||
|
|
||||||
use scale::Encode;
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
in_instructions::primitives::Shorthand, networks::ethereum::Address as SeraiAddress,
|
primitives::instructions::RefundableInInstruction, networks::ethereum::Address as SeraiAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ethereum_primitives::LogIndex;
|
use ethereum_primitives::LogIndex;
|
||||||
@@ -351,18 +350,27 @@ impl Router {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a transaction to send coins with an InInstruction to Serai.
|
/// Construct a transaction to send coins with an `InInstruction` to Serai.
|
||||||
///
|
///
|
||||||
/// If coin is an ERC20, this will not create a transaction calling the Router but will create a
|
/// If coin is an ERC20, this will not create a transaction calling the Router but will create a
|
||||||
/// top-level transfer of the ERC20 to the Router. This avoids needing to call `approve` before
|
/// top-level transfer of the ERC20 to the Router. This avoids needing to call `approve` before
|
||||||
/// publishing the transaction calling the Router.
|
/// publishing the transaction calling the Router.
|
||||||
///
|
///
|
||||||
/// The gas limit and gas price are not set and are left to the caller.
|
/// The gas limit and gas price are not set and are left to the caller.
|
||||||
pub fn in_instruction(&self, coin: Coin, amount: U256, in_instruction: &Shorthand) -> TxLegacy {
|
pub fn in_instruction(
|
||||||
|
&self,
|
||||||
|
coin: Coin,
|
||||||
|
amount: U256,
|
||||||
|
in_instruction: &RefundableInInstruction,
|
||||||
|
) -> TxLegacy {
|
||||||
match coin {
|
match coin {
|
||||||
Coin::Ether => TxLegacy {
|
Coin::Ether => TxLegacy {
|
||||||
to: self.address.into(),
|
to: self.address.into(),
|
||||||
input: abi::inInstructionCall::new((coin.into(), amount, in_instruction.encode().into()))
|
input: abi::inInstructionCall::new((
|
||||||
|
coin.into(),
|
||||||
|
amount,
|
||||||
|
borsh::to_vec(&in_instruction).unwrap().into(),
|
||||||
|
))
|
||||||
.abi_encode()
|
.abi_encode()
|
||||||
.into(),
|
.into(),
|
||||||
value: amount,
|
value: amount,
|
||||||
@@ -373,7 +381,7 @@ impl Router {
|
|||||||
input: erc20::transferWithInInstructionCall::new((
|
input: erc20::transferWithInInstructionCall::new((
|
||||||
self.address,
|
self.address,
|
||||||
amount,
|
amount,
|
||||||
in_instruction.encode().into(),
|
borsh::to_vec(&in_instruction).unwrap().into(),
|
||||||
))
|
))
|
||||||
.abi_encode()
|
.abi_encode()
|
||||||
.into(),
|
.into(),
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ use alloy_sol_types::SolCall;
|
|||||||
|
|
||||||
use alloy_consensus::{TxLegacy, Signed};
|
use alloy_consensus::{TxLegacy, Signed};
|
||||||
|
|
||||||
use scale::Encode;
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::SeraiAddress,
|
primitives::SeraiAddress,
|
||||||
in_instructions::primitives::{
|
primitives::instructions::{InInstruction as SeraiInInstruction, RefundableInInstruction},
|
||||||
InInstruction as SeraiInInstruction, RefundableInInstruction, Shorthand,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ethereum_primitives::LogIndex;
|
use ethereum_primitives::LogIndex;
|
||||||
@@ -18,14 +15,14 @@ use ethereum_primitives::LogIndex;
|
|||||||
use crate::{InInstruction, tests::*};
|
use crate::{InInstruction, tests::*};
|
||||||
|
|
||||||
impl Test {
|
impl Test {
|
||||||
pub(crate) fn in_instruction() -> Shorthand {
|
pub(crate) fn in_instruction() -> RefundableInInstruction {
|
||||||
Shorthand::Raw(RefundableInInstruction {
|
RefundableInInstruction {
|
||||||
origin: None,
|
origin: None,
|
||||||
instruction: SeraiInInstruction::Transfer(SeraiAddress([0xff; 32])),
|
instruction: SeraiInInstruction::Transfer(SeraiAddress([0xff; 32])),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn eth_in_instruction_tx(&self) -> (Coin, U256, Shorthand, TxLegacy) {
|
pub(crate) fn eth_in_instruction_tx(&self) -> (Coin, U256, RefundableInInstruction, TxLegacy) {
|
||||||
let coin = Coin::Ether;
|
let coin = Coin::Ether;
|
||||||
let amount = U256::from(1);
|
let amount = U256::from(1);
|
||||||
let shorthand = Self::in_instruction();
|
let shorthand = Self::in_instruction();
|
||||||
@@ -42,7 +39,7 @@ impl Test {
|
|||||||
tx: Signed<TxLegacy>,
|
tx: Signed<TxLegacy>,
|
||||||
coin: Coin,
|
coin: Coin,
|
||||||
amount: U256,
|
amount: U256,
|
||||||
shorthand: &Shorthand,
|
shorthand: &RefundableInInstruction,
|
||||||
) {
|
) {
|
||||||
let receipt = ethereum_test_primitives::publish_tx(&self.provider, tx.clone()).await;
|
let receipt = ethereum_test_primitives::publish_tx(&self.provider, tx.clone()).await;
|
||||||
assert!(receipt.status());
|
assert!(receipt.status());
|
||||||
@@ -81,7 +78,7 @@ impl Test {
|
|||||||
from: tx.recover_signer().unwrap(),
|
from: tx.recover_signer().unwrap(),
|
||||||
coin,
|
coin,
|
||||||
amount,
|
amount,
|
||||||
data: shorthand.encode(),
|
data: borsh::to_vec(&shorthand).unwrap(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -140,7 +137,11 @@ async fn test_erc20_router_in_instruction() {
|
|||||||
gas_limit: 1_000_000,
|
gas_limit: 1_000_000,
|
||||||
to: test.router.address().into(),
|
to: test.router.address().into(),
|
||||||
value: U256::ZERO,
|
value: U256::ZERO,
|
||||||
input: crate::abi::inInstructionCall::new((coin.into(), amount, shorthand.encode().into()))
|
input: crate::abi::inInstructionCall::new((
|
||||||
|
coin.into(),
|
||||||
|
amount,
|
||||||
|
borsh::to_vec(shorthand).unwrap().into(),
|
||||||
|
))
|
||||||
.abi_encode()
|
.abi_encode()
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use alloy_simple_request_transport::SimpleRequest;
|
|||||||
use alloy_rpc_client::ClientBuilder;
|
use alloy_rpc_client::ClientBuilder;
|
||||||
use alloy_provider::{Provider, RootProvider};
|
use alloy_provider::{Provider, RootProvider};
|
||||||
|
|
||||||
use serai_client::validator_sets::primitives::Session;
|
use serai_client::primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_env as env;
|
use serai_env as env;
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use alloy_core::primitives::{FixedBytes, Address};
|
use alloy_core::primitives::{FixedBytes, Address};
|
||||||
|
|
||||||
use serai_client::primitives::Amount;
|
use serai_client::primitives::balance::Amount;
|
||||||
|
|
||||||
pub(crate) mod output;
|
pub(crate) mod output;
|
||||||
pub(crate) mod transaction;
|
pub(crate) mod transaction;
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ use ciphersuite_kp256::Secp256k1;
|
|||||||
|
|
||||||
use alloy_core::primitives::U256;
|
use alloy_core::primitives::U256;
|
||||||
|
|
||||||
use scale::{Encode, Decode};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalNetworkId, ExternalCoin, Amount, ExternalBalance},
|
primitives::{
|
||||||
|
network_id::ExternalNetworkId,
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
},
|
||||||
networks::ethereum::Address,
|
networks::ethereum::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,9 +42,7 @@ fn amount_to_serai_amount(coin: ExternalCoin, amount: U256) -> Amount {
|
|||||||
Amount(u64::try_from(amount / divisor).unwrap())
|
Amount(u64::try_from(amount / divisor).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode, BorshSerialize, BorshDeserialize,
|
|
||||||
)]
|
|
||||||
pub(crate) struct OutputId(pub(crate) [u8; 40]);
|
pub(crate) struct OutputId(pub(crate) [u8; 40]);
|
||||||
impl Default for OutputId {
|
impl Default for OutputId {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use alloy_rpc_types_eth::{Header, BlockNumberOrTag};
|
|||||||
use alloy_transport::{RpcError, TransportErrorKind};
|
use alloy_transport::{RpcError, TransportErrorKind};
|
||||||
use alloy_provider::{Provider, RootProvider};
|
use alloy_provider::{Provider, RootProvider};
|
||||||
|
|
||||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
use serai_client::primitives::{network_id::ExternalNetworkId, coin::ExternalCoin, balance::Amount};
|
||||||
|
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use alloy_core::primitives::U256;
|
use alloy_core::primitives::U256;
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalNetworkId, ExternalCoin, ExternalBalance},
|
primitives::{network_id::ExternalNetworkId, coin::ExternalCoin, balance::ExternalBalance},
|
||||||
networks::ethereum::Address,
|
networks::ethereum::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
ignored = ["borsh", "scale"]
|
ignored = ["borsh"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -29,7 +29,6 @@ serai-primitives = { path = "../../substrate/primitives", default-features = fal
|
|||||||
|
|
||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
serai-db = { path = "../../common/db" }
|
serai-db = { path = "../../common/db" }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use frost::{
|
|||||||
sign::{Writable, PreprocessMachine, SignMachine, SignatureMachine},
|
sign::{Writable, PreprocessMachine, SignMachine, SignatureMachine},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, Db, create_db};
|
use serai_db::{Get, DbTxn, Db, create_db};
|
||||||
use messages::sign::{VariantSignId, SignId, ProcessorMessage};
|
use messages::sign::{VariantSignId, SignId, ProcessorMessage};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use frost::{Participant, sign::PreprocessMachine};
|
use frost::{Participant, sign::PreprocessMachine};
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
use messages::sign::{VariantSignId, ProcessorMessage, CoordinatorMessage};
|
use messages::sign::{VariantSignId, ProcessorMessage, CoordinatorMessage};
|
||||||
|
|||||||
@@ -14,9 +14,6 @@ rust-version = "1.89"
|
|||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
|
||||||
ignored = ["scale"]
|
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
@@ -38,7 +35,6 @@ dkg = { package = "dkg-evrf", path = "../../crypto/dkg/evrf", default-features =
|
|||||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
# Encoders
|
# Encoders
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
# Application
|
# Application
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use zeroize::Zeroizing;
|
|||||||
use ciphersuite::{group::GroupEncoding, Ciphersuite};
|
use ciphersuite::{group::GroupEncoding, Ciphersuite};
|
||||||
use dkg::*;
|
use dkg::*;
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::{Get, DbTxn};
|
use serai_db::{Get, DbTxn};
|
||||||
@@ -36,7 +36,7 @@ pub(crate) struct Participations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod _db {
|
mod _db {
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
|
|
||||||
use dkg::*;
|
use dkg::*;
|
||||||
|
|
||||||
use serai_validator_sets_primitives::MAX_KEY_SHARES_PER_SET;
|
use serai_primitives::constants::MAX_KEY_SHARES_PER_SET;
|
||||||
|
|
||||||
/// A cache of the generators used by the eVRF DKG.
|
/// A cache of the generators used by the eVRF DKG.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use ciphersuite::{
|
|||||||
};
|
};
|
||||||
use dkg::*;
|
use dkg::*;
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
use messages::key_gen::*;
|
use messages::key_gen::*;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn};
|
use serai_db::{Get, DbTxn};
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] }
|
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] }
|
||||||
|
|
||||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
serai-cosign = { path = "../../coordinator/cosign", default-features = false }
|
serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" }
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use scale::{Encode, Decode};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use dkg::Participant;
|
use dkg::Participant;
|
||||||
|
|
||||||
use serai_primitives::BlockHash;
|
use serai_primitives::{
|
||||||
use validator_sets_primitives::{Session, KeyPair, SlashReport};
|
BlockHash,
|
||||||
use coins_primitives::OutInstructionWithBalance;
|
crypto::KeyPair,
|
||||||
use in_instructions_primitives::SignedBatch;
|
validator_sets::{Session, SlashReport},
|
||||||
|
instructions::{SignedBatch, OutInstructionWithBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use serai_cosign::{Cosign, SignedCosign};
|
use serai_cosign::{Cosign, SignedCosign};
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ pub mod key_gen {
|
|||||||
pub mod sign {
|
pub mod sign {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Encode, Decode, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize)]
|
||||||
pub enum VariantSignId {
|
pub enum VariantSignId {
|
||||||
Cosign(u64),
|
Cosign(u64),
|
||||||
Batch([u8; 32]),
|
Batch([u8; 32]),
|
||||||
@@ -111,9 +112,7 @@ pub mod sign {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode, BorshSerialize, BorshDeserialize,
|
|
||||||
)]
|
|
||||||
pub struct SignId {
|
pub struct SignId {
|
||||||
pub session: Session,
|
pub session: Session,
|
||||||
pub id: VariantSignId,
|
pub id: VariantSignId,
|
||||||
@@ -295,7 +294,7 @@ impl CoordinatorMessage {
|
|||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
// Unique since we only have one attempt per session
|
// Unique since we only have one attempt per session
|
||||||
key_gen::CoordinatorMessage::GenerateKey { session, .. } => {
|
key_gen::CoordinatorMessage::GenerateKey { session, .. } => {
|
||||||
(0, borsh::to_vec(session).unwrap())
|
(0, borsh::to_vec(&session).unwrap())
|
||||||
}
|
}
|
||||||
// Unique since one participation per participant per session
|
// Unique since one participation per participant per session
|
||||||
key_gen::CoordinatorMessage::Participation { session, participant, .. } => {
|
key_gen::CoordinatorMessage::Participation { session, participant, .. } => {
|
||||||
@@ -316,17 +315,19 @@ impl CoordinatorMessage {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![COORDINATOR_UID, TYPE_SIGN_UID, sub];
|
let mut res = vec![COORDINATOR_UID, TYPE_SIGN_UID, sub];
|
||||||
res.extend(id.encode());
|
res.extend(borsh::to_vec(&id).unwrap());
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
CoordinatorMessage::Coordinator(msg) => {
|
CoordinatorMessage::Coordinator(msg) => {
|
||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
// We only cosign a block once, and Reattempt is a separate message
|
// We only cosign a block once, and Reattempt is a separate message
|
||||||
coordinator::CoordinatorMessage::CosignSubstrateBlock { cosign, .. } => {
|
coordinator::CoordinatorMessage::CosignSubstrateBlock { cosign, .. } => {
|
||||||
(0, cosign.block_number.encode())
|
(0, borsh::to_vec(&cosign.block_number).unwrap())
|
||||||
}
|
}
|
||||||
// We only sign one slash report, and Reattempt is a separate message
|
// We only sign one slash report, and Reattempt is a separate message
|
||||||
coordinator::CoordinatorMessage::SignSlashReport { session, .. } => (1, session.encode()),
|
coordinator::CoordinatorMessage::SignSlashReport { session, .. } => {
|
||||||
|
(1, borsh::to_vec(&session).unwrap())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![COORDINATOR_UID, TYPE_COORDINATOR_UID, sub];
|
let mut res = vec![COORDINATOR_UID, TYPE_COORDINATOR_UID, sub];
|
||||||
@@ -335,10 +336,14 @@ impl CoordinatorMessage {
|
|||||||
}
|
}
|
||||||
CoordinatorMessage::Substrate(msg) => {
|
CoordinatorMessage::Substrate(msg) => {
|
||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
substrate::CoordinatorMessage::SetKeys { session, .. } => (0, session.encode()),
|
substrate::CoordinatorMessage::SetKeys { session, .. } => {
|
||||||
substrate::CoordinatorMessage::SlashesReported { session } => (1, session.encode()),
|
(0, borsh::to_vec(&session).unwrap())
|
||||||
|
}
|
||||||
|
substrate::CoordinatorMessage::SlashesReported { session } => {
|
||||||
|
(1, borsh::to_vec(&session).unwrap())
|
||||||
|
}
|
||||||
substrate::CoordinatorMessage::Block { serai_block_number, .. } => {
|
substrate::CoordinatorMessage::Block { serai_block_number, .. } => {
|
||||||
(2, serai_block_number.encode())
|
(2, borsh::to_vec(&serai_block_number).unwrap())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -363,10 +368,10 @@ impl ProcessorMessage {
|
|||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
// Unique since we only have one participation per session (due to no re-attempts)
|
// Unique since we only have one participation per session (due to no re-attempts)
|
||||||
key_gen::ProcessorMessage::Participation { session, .. } => {
|
key_gen::ProcessorMessage::Participation { session, .. } => {
|
||||||
(0, borsh::to_vec(session).unwrap())
|
(0, borsh::to_vec(&session).unwrap())
|
||||||
}
|
}
|
||||||
key_gen::ProcessorMessage::GeneratedKeyPair { session, .. } => {
|
key_gen::ProcessorMessage::GeneratedKeyPair { session, .. } => {
|
||||||
(1, borsh::to_vec(session).unwrap())
|
(1, borsh::to_vec(&session).unwrap())
|
||||||
}
|
}
|
||||||
// Unique since we only blame a participant once (as this is fatal)
|
// Unique since we only blame a participant once (as this is fatal)
|
||||||
key_gen::ProcessorMessage::Blame { session, participant } => {
|
key_gen::ProcessorMessage::Blame { session, participant } => {
|
||||||
@@ -382,11 +387,11 @@ impl ProcessorMessage {
|
|||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
// Unique since we'll only fatally slash a a participant once
|
// Unique since we'll only fatally slash a a participant once
|
||||||
sign::ProcessorMessage::InvalidParticipant { session, participant } => {
|
sign::ProcessorMessage::InvalidParticipant { session, participant } => {
|
||||||
(0, (session, u16::from(*participant)).encode())
|
(0, borsh::to_vec(&(session, u16::from(*participant))).unwrap())
|
||||||
}
|
}
|
||||||
// Unique since SignId
|
// Unique since SignId
|
||||||
sign::ProcessorMessage::Preprocesses { id, .. } => (1, id.encode()),
|
sign::ProcessorMessage::Preprocesses { id, .. } => (1, borsh::to_vec(&id).unwrap()),
|
||||||
sign::ProcessorMessage::Shares { id, .. } => (2, id.encode()),
|
sign::ProcessorMessage::Shares { id, .. } => (2, borsh::to_vec(&id).unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![PROCESSOR_UID, TYPE_SIGN_UID, sub];
|
let mut res = vec![PROCESSOR_UID, TYPE_SIGN_UID, sub];
|
||||||
@@ -396,10 +401,14 @@ impl ProcessorMessage {
|
|||||||
ProcessorMessage::Coordinator(msg) => {
|
ProcessorMessage::Coordinator(msg) => {
|
||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
coordinator::ProcessorMessage::CosignedBlock { cosign } => {
|
coordinator::ProcessorMessage::CosignedBlock { cosign } => {
|
||||||
(0, cosign.cosign.block_hash.encode())
|
(0, borsh::to_vec(&cosign.cosign.block_hash).unwrap())
|
||||||
|
}
|
||||||
|
coordinator::ProcessorMessage::SignedBatch { batch, .. } => {
|
||||||
|
(1, borsh::to_vec(&batch.batch.id()).unwrap())
|
||||||
|
}
|
||||||
|
coordinator::ProcessorMessage::SignedSlashReport { session, .. } => {
|
||||||
|
(2, borsh::to_vec(&session).unwrap())
|
||||||
}
|
}
|
||||||
coordinator::ProcessorMessage::SignedBatch { batch, .. } => (1, batch.batch.id.encode()),
|
|
||||||
coordinator::ProcessorMessage::SignedSlashReport { session, .. } => (2, session.encode()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![PROCESSOR_UID, TYPE_COORDINATOR_UID, sub];
|
let mut res = vec![PROCESSOR_UID, TYPE_COORDINATOR_UID, sub];
|
||||||
@@ -408,7 +417,9 @@ impl ProcessorMessage {
|
|||||||
}
|
}
|
||||||
ProcessorMessage::Substrate(msg) => {
|
ProcessorMessage::Substrate(msg) => {
|
||||||
let (sub, id) = match msg {
|
let (sub, id) = match msg {
|
||||||
substrate::ProcessorMessage::SubstrateBlockAck { block, .. } => (0, block.encode()),
|
substrate::ProcessorMessage::SubstrateBlockAck { block, .. } => {
|
||||||
|
(0, borsh::to_vec(&block).unwrap())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![PROCESSOR_UID, TYPE_SUBSTRATE_UID, sub];
|
let mut res = vec![PROCESSOR_UID, TYPE_SUBSTRATE_UID, sub];
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ rand_core = { version = "0.6", default-features = false }
|
|||||||
rand_chacha = { version = "0.3", default-features = false, features = ["std"] }
|
rand_chacha = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
zeroize = { version = "1", default-features = false, features = ["std"] }
|
zeroize = { version = "1", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ use dalek_ff_group::Ed25519;
|
|||||||
|
|
||||||
use monero_wallet::WalletOutput;
|
use monero_wallet::WalletOutput;
|
||||||
|
|
||||||
use scale::{Encode, Decode};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalCoin, Amount, ExternalBalance},
|
primitives::{
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
},
|
||||||
networks::monero::Address,
|
networks::monero::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,10 +19,7 @@ use primitives::{OutputType, ReceivedOutput};
|
|||||||
|
|
||||||
use crate::{EXTERNAL_SUBADDRESS, BRANCH_SUBADDRESS, CHANGE_SUBADDRESS, FORWARDED_SUBADDRESS};
|
use crate::{EXTERNAL_SUBADDRESS, BRANCH_SUBADDRESS, CHANGE_SUBADDRESS, FORWARDED_SUBADDRESS};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[derive(Clone, Copy, PartialEq, Eq, Default, Hash, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
#[derive(
|
|
||||||
Clone, Copy, PartialEq, Eq, Default, Hash, Debug, Encode, Decode, BorshSerialize, BorshDeserialize,
|
|
||||||
)]
|
|
||||||
pub(crate) struct OutputId(pub(crate) [u8; 32]);
|
pub(crate) struct OutputId(pub(crate) [u8; 32]);
|
||||||
impl AsRef<[u8]> for OutputId {
|
impl AsRef<[u8]> for OutputId {
|
||||||
fn as_ref(&self) -> &[u8] {
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use core::future::Future;
|
|||||||
use monero_wallet::rpc::{RpcError, Rpc as RpcTrait};
|
use monero_wallet::rpc::{RpcError, Rpc as RpcTrait};
|
||||||
use monero_simple_request_rpc::SimpleRequestRpc;
|
use monero_simple_request_rpc::SimpleRequestRpc;
|
||||||
|
|
||||||
use serai_client::primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
use serai_client::primitives::{network_id::ExternalNetworkId, coin::ExternalCoin, balance::Amount};
|
||||||
|
|
||||||
use scanner::ScannerFeed;
|
use scanner::ScannerFeed;
|
||||||
use signers::TransactionPublisher;
|
use signers::TransactionPublisher;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use dalek_ff_group::Ed25519;
|
|||||||
use monero_wallet::rpc::{FeeRate, RpcError};
|
use monero_wallet::rpc::{FeeRate, RpcError};
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{ExternalCoin, Amount},
|
primitives::{coin::ExternalCoin, balance::Amount},
|
||||||
networks::monero::Address,
|
networks::monero::Address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ group = { version = "0.13", default-features = false }
|
|||||||
|
|
||||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
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"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use core::{hash::Hash, fmt::Debug};
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use scale::{Encode, Decode};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
/// A module for task-related structs and functionality.
|
/// A module for task-related structs and functionality.
|
||||||
@@ -40,8 +39,6 @@ pub trait Id:
|
|||||||
+ AsRef<[u8]>
|
+ AsRef<[u8]>
|
||||||
+ AsMut<[u8]>
|
+ AsMut<[u8]>
|
||||||
+ Debug
|
+ Debug
|
||||||
+ Encode
|
|
||||||
+ Decode
|
|
||||||
+ BorshSerialize
|
+ BorshSerialize
|
||||||
+ BorshDeserialize
|
+ BorshDeserialize
|
||||||
{
|
{
|
||||||
@@ -57,22 +54,15 @@ impl<
|
|||||||
+ AsRef<[u8]>
|
+ AsRef<[u8]>
|
||||||
+ AsMut<[u8]>
|
+ AsMut<[u8]>
|
||||||
+ Debug
|
+ Debug
|
||||||
+ Encode
|
|
||||||
+ Decode
|
|
||||||
+ BorshSerialize
|
+ BorshSerialize
|
||||||
+ BorshDeserialize,
|
+ BorshDeserialize,
|
||||||
> Id for I
|
> Id for I
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for a group element which implements the scale/borsh traits.
|
/// A wrapper for a group element which implements the `borsh` traits.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub struct EncodableG<G: GroupEncoding>(pub G);
|
pub struct EncodableG<G: GroupEncoding>(pub G);
|
||||||
impl<G: GroupEncoding> Encode for EncodableG<G> {
|
|
||||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
|
||||||
f(self.0.to_bytes().as_ref())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<G: GroupEncoding> BorshSerialize for EncodableG<G> {
|
impl<G: GroupEncoding> BorshSerialize for EncodableG<G> {
|
||||||
fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
|
fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
|
||||||
writer.write_all(self.0.to_bytes().as_ref())
|
writer.write_all(self.0.to_bytes().as_ref())
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use group::GroupEncoding;
|
|||||||
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use serai_primitives::{ExternalAddress, ExternalBalance};
|
use serai_primitives::{address::ExternalAddress, balance::ExternalBalance};
|
||||||
|
|
||||||
use crate::Id;
|
use crate::Id;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use scale::{Encode, Decode, IoReader};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use serai_primitives::ExternalBalance;
|
use serai_primitives::{
|
||||||
use serai_coins_primitives::OutInstructionWithBalance;
|
balance::ExternalBalance,
|
||||||
|
instructions::{OutInstruction, OutInstructionWithBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::Address;
|
use crate::Address;
|
||||||
|
|
||||||
@@ -18,9 +19,11 @@ pub struct Payment<A: Address> {
|
|||||||
impl<A: Address> TryFrom<OutInstructionWithBalance> for Payment<A> {
|
impl<A: Address> TryFrom<OutInstructionWithBalance> for Payment<A> {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(out_instruction_with_balance: OutInstructionWithBalance) -> Result<Self, ()> {
|
fn try_from(out_instruction_with_balance: OutInstructionWithBalance) -> Result<Self, ()> {
|
||||||
Ok(Payment {
|
Ok(match out_instruction_with_balance.instruction {
|
||||||
address: out_instruction_with_balance.instruction.address.try_into().map_err(|_| ())?,
|
OutInstruction::Transfer(address) => Payment {
|
||||||
|
address: address.try_into().map_err(|_| ())?,
|
||||||
balance: out_instruction_with_balance.balance,
|
balance: out_instruction_with_balance.balance,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,14 +46,12 @@ impl<A: Address> Payment<A> {
|
|||||||
/// Read a Payment.
|
/// Read a Payment.
|
||||||
pub fn read(reader: &mut impl io::Read) -> io::Result<Self> {
|
pub fn read(reader: &mut impl io::Read) -> io::Result<Self> {
|
||||||
let address = A::deserialize_reader(reader)?;
|
let address = A::deserialize_reader(reader)?;
|
||||||
let reader = &mut IoReader(reader);
|
let balance = ExternalBalance::deserialize_reader(reader).map_err(io::Error::other)?;
|
||||||
let balance = ExternalBalance::decode(reader).map_err(io::Error::other)?;
|
|
||||||
Ok(Self { address, balance })
|
Ok(Self { address, balance })
|
||||||
}
|
}
|
||||||
/// Write the Payment.
|
/// Write the Payment.
|
||||||
pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
||||||
self.address.serialize(writer)?;
|
self.address.serialize(writer)?;
|
||||||
self.balance.encode_to(writer);
|
self.balance.serialize(writer)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# Encoders
|
# Encoders
|
||||||
hex = { version = "0.4", default-features = false, features = ["std"] }
|
hex = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
# Cryptography
|
# Cryptography
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ use std::io::{Read, Write};
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use scale::{Encode, Decode, IoReader};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
use serai_primitives::ExternalBalance;
|
use serai_primitives::{balance::ExternalBalance, validator_sets::Session};
|
||||||
use serai_validator_sets_primitives::Session;
|
|
||||||
|
|
||||||
use primitives::EncodableG;
|
use primitives::EncodableG;
|
||||||
use crate::{ScannerFeed, KeyFor, AddressFor};
|
use crate::{ScannerFeed, KeyFor, AddressFor};
|
||||||
@@ -94,7 +92,7 @@ impl<S: ScannerFeed> BatchDb<S> {
|
|||||||
if let Some(ReturnInformation { address, balance }) = return_information {
|
if let Some(ReturnInformation { address, balance }) = return_information {
|
||||||
buf.write_all(&[1]).unwrap();
|
buf.write_all(&[1]).unwrap();
|
||||||
address.serialize(&mut buf).unwrap();
|
address.serialize(&mut buf).unwrap();
|
||||||
balance.encode_to(&mut buf);
|
balance.serialize(&mut buf).unwrap();
|
||||||
} else {
|
} else {
|
||||||
buf.write_all(&[0]).unwrap();
|
buf.write_all(&[0]).unwrap();
|
||||||
}
|
}
|
||||||
@@ -116,7 +114,7 @@ impl<S: ScannerFeed> BatchDb<S> {
|
|||||||
|
|
||||||
res.push((opt[0] == 1).then(|| {
|
res.push((opt[0] == 1).then(|| {
|
||||||
let address = AddressFor::<S>::deserialize_reader(&mut buf).unwrap();
|
let address = AddressFor::<S>::deserialize_reader(&mut buf).unwrap();
|
||||||
let balance = ExternalBalance::decode(&mut IoReader(&mut buf)).unwrap();
|
let balance = ExternalBalance::deserialize_reader(&mut buf).unwrap();
|
||||||
ReturnInformation { address, balance }
|
ReturnInformation { address, balance }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ use core::{marker::PhantomData, future::Future};
|
|||||||
|
|
||||||
use blake2::{digest::typenum::U32, Digest, Blake2b};
|
use blake2::{digest::typenum::U32, Digest, Blake2b};
|
||||||
|
|
||||||
use scale::Encode;
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
use serai_primitives::BlockHash;
|
use serai_primitives::{BlockHash, instructions::Batch};
|
||||||
use serai_in_instructions_primitives::{MAX_BATCH_SIZE, Batch};
|
|
||||||
|
|
||||||
use primitives::{
|
use primitives::{
|
||||||
EncodableG,
|
EncodableG,
|
||||||
@@ -111,12 +109,7 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for BatchTask<D, S> {
|
|||||||
let mut batch_id = BatchDb::<S>::acquire_batch_id(&mut txn);
|
let mut batch_id = BatchDb::<S>::acquire_batch_id(&mut txn);
|
||||||
|
|
||||||
// start with empty batch
|
// start with empty batch
|
||||||
let mut batches = vec![Batch {
|
let mut batches = vec![Batch::new(network, batch_id, external_network_block_hash)];
|
||||||
network,
|
|
||||||
id: batch_id,
|
|
||||||
external_network_block_hash,
|
|
||||||
instructions: vec![],
|
|
||||||
}];
|
|
||||||
// We also track the return information for the InInstructions within a Batch in case
|
// We also track the return information for the InInstructions within a Batch in case
|
||||||
// they error
|
// they error
|
||||||
let mut return_information = vec![vec![]];
|
let mut return_information = vec![vec![]];
|
||||||
@@ -125,23 +118,19 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for BatchTask<D, S> {
|
|||||||
let balance = in_instruction.balance;
|
let balance = in_instruction.balance;
|
||||||
|
|
||||||
let batch = batches.last_mut().unwrap();
|
let batch = batches.last_mut().unwrap();
|
||||||
batch.instructions.push(in_instruction);
|
|
||||||
|
|
||||||
// check if batch is over-size
|
// check if batch is over-size
|
||||||
if batch.encode().len() > MAX_BATCH_SIZE {
|
if batch.push_instruction(in_instruction.clone()).is_err() {
|
||||||
// pop the last instruction so it's back in size
|
|
||||||
let in_instruction = batch.instructions.pop().unwrap();
|
|
||||||
|
|
||||||
// bump the id for the new batch
|
// bump the id for the new batch
|
||||||
batch_id = BatchDb::<S>::acquire_batch_id(&mut txn);
|
batch_id = BatchDb::<S>::acquire_batch_id(&mut txn);
|
||||||
|
|
||||||
// make a new batch with this instruction included
|
// make a new batch with this instruction included
|
||||||
batches.push(Batch {
|
let mut batch = Batch::new(network, batch_id, external_network_block_hash);
|
||||||
network,
|
batch
|
||||||
id: batch_id,
|
.push_instruction(in_instruction)
|
||||||
external_network_block_hash,
|
.expect("single InInstruction exceeded Batch size limit");
|
||||||
instructions: vec![in_instruction],
|
batches.push(batch);
|
||||||
});
|
|
||||||
// Since we're allocating a new batch, allocate a new set of return addresses for it
|
// Since we're allocating a new batch, allocate a new set of return addresses for it
|
||||||
return_information.push(vec![]);
|
return_information.push(vec![]);
|
||||||
}
|
}
|
||||||
@@ -157,16 +146,16 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for BatchTask<D, S> {
|
|||||||
// Now that we've finalized the Batches, save the information for each to the database
|
// Now that we've finalized the Batches, save the information for each to the database
|
||||||
assert_eq!(batches.len(), return_information.len());
|
assert_eq!(batches.len(), return_information.len());
|
||||||
for (batch, return_information) in batches.iter().zip(&return_information) {
|
for (batch, return_information) in batches.iter().zip(&return_information) {
|
||||||
assert_eq!(batch.instructions.len(), return_information.len());
|
assert_eq!(batch.instructions().len(), return_information.len());
|
||||||
BatchDb::<S>::save_batch_info(
|
BatchDb::<S>::save_batch_info(
|
||||||
&mut txn,
|
&mut txn,
|
||||||
batch.id,
|
batch.id(),
|
||||||
block_number,
|
block_number,
|
||||||
session_to_sign_batch,
|
session_to_sign_batch,
|
||||||
external_key_for_session_to_sign_batch,
|
external_key_for_session_to_sign_batch,
|
||||||
Blake2b::<U32>::digest(batch.instructions.encode()).into(),
|
Blake2b::<U32>::digest(borsh::to_vec(&batch.instructions()).unwrap()).into(),
|
||||||
);
|
);
|
||||||
BatchDb::<S>::save_return_information(&mut txn, batch.id, return_information);
|
BatchDb::<S>::save_return_information(&mut txn, batch.id(), return_information);
|
||||||
}
|
}
|
||||||
|
|
||||||
for batch in batches {
|
for batch in batches {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ use std::io::{self, Read, Write};
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use scale::{Encode, Decode, IoReader};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||||
|
|
||||||
use serai_coins_primitives::OutInstructionWithBalance;
|
use serai_primitives::{
|
||||||
use serai_validator_sets_primitives::Session;
|
validator_sets::Session,
|
||||||
use serai_in_instructions_primitives::{InInstructionWithBalance, Batch};
|
instructions::{InInstructionWithBalance, Batch, OutInstructionWithBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use primitives::{EncodableG, ReceivedOutput};
|
use primitives::{EncodableG, ReceivedOutput};
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ impl<S: ScannerFeed> OutputWithInInstruction<S> {
|
|||||||
(opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(reader)).transpose()?
|
(opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(reader)).transpose()?
|
||||||
};
|
};
|
||||||
let in_instruction =
|
let in_instruction =
|
||||||
InInstructionWithBalance::decode(&mut IoReader(reader)).map_err(io::Error::other)?;
|
InInstructionWithBalance::deserialize_reader(reader).map_err(io::Error::other)?;
|
||||||
Ok(Self { output, return_address, in_instruction })
|
Ok(Self { output, return_address, in_instruction })
|
||||||
}
|
}
|
||||||
pub(crate) fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
pub(crate) fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
||||||
@@ -67,7 +67,7 @@ impl<S: ScannerFeed> OutputWithInInstruction<S> {
|
|||||||
} else {
|
} else {
|
||||||
writer.write_all(&[0])?;
|
writer.write_all(&[0])?;
|
||||||
}
|
}
|
||||||
self.in_instruction.encode_to(writer);
|
self.in_instruction.serialize(writer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,10 +76,10 @@ create_db!(
|
|||||||
ScannerGlobal {
|
ScannerGlobal {
|
||||||
StartBlock: () -> u64,
|
StartBlock: () -> u64,
|
||||||
|
|
||||||
QueuedKey: <K: Encode>(key: K) -> (),
|
QueuedKey: <K: BorshSerialize>(key: K) -> (),
|
||||||
|
|
||||||
ActiveKeys: <K: Borshy>() -> Vec<SeraiKeyDbEntry<K>>,
|
ActiveKeys: <K: Borshy>() -> Vec<SeraiKeyDbEntry<K>>,
|
||||||
RetireAt: <K: Encode>(key: K) -> u64,
|
RetireAt: <K: BorshSerialize>(key: K) -> u64,
|
||||||
|
|
||||||
// Highest acknowledged block
|
// Highest acknowledged block
|
||||||
HighestAcknowledgedBlock: () -> u64,
|
HighestAcknowledgedBlock: () -> u64,
|
||||||
@@ -294,7 +294,7 @@ impl<S: ScannerFeed> ScannerGlobalDb<S> {
|
|||||||
assert!((opt[0] == 0) || (opt[0] == 1));
|
assert!((opt[0] == 0) || (opt[0] == 1));
|
||||||
|
|
||||||
let address = (opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(&mut buf).unwrap());
|
let address = (opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(&mut buf).unwrap());
|
||||||
Some((address, InInstructionWithBalance::decode(&mut IoReader(buf)).unwrap()))
|
Some((address, InInstructionWithBalance::deserialize_reader(&mut buf).unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ impl<S: ScannerFeed> ScanToEventualityDb<S> {
|
|||||||
} else {
|
} else {
|
||||||
buf.write_all(&[0]).unwrap();
|
buf.write_all(&[0]).unwrap();
|
||||||
}
|
}
|
||||||
forward.in_instruction.encode_to(&mut buf);
|
forward.in_instruction.serialize(&mut buf).unwrap();
|
||||||
|
|
||||||
SerializedForwardedOutput::set(txn, forward.output.id().as_ref(), &buf);
|
SerializedForwardedOutput::set(txn, forward.output.id().as_ref(), &buf);
|
||||||
}
|
}
|
||||||
@@ -454,7 +454,7 @@ impl<S: ScannerFeed> Returnable<S> {
|
|||||||
(opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(reader)).transpose()?;
|
(opt[0] == 1).then(|| AddressFor::<S>::deserialize_reader(reader)).transpose()?;
|
||||||
|
|
||||||
let in_instruction =
|
let in_instruction =
|
||||||
InInstructionWithBalance::decode(&mut IoReader(reader)).map_err(io::Error::other)?;
|
InInstructionWithBalance::deserialize_reader(reader).map_err(io::Error::other)?;
|
||||||
Ok(Returnable { return_address, in_instruction })
|
Ok(Returnable { return_address, in_instruction })
|
||||||
}
|
}
|
||||||
fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
||||||
@@ -464,7 +464,7 @@ impl<S: ScannerFeed> Returnable<S> {
|
|||||||
} else {
|
} else {
|
||||||
writer.write_all(&[0])?;
|
writer.write_all(&[0])?;
|
||||||
}
|
}
|
||||||
self.in_instruction.encode_to(writer);
|
self.in_instruction.serialize(writer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,7 +494,7 @@ impl<S: ScannerFeed> ScanToBatchDb<S> {
|
|||||||
block_number: u64,
|
block_number: u64,
|
||||||
data: &InInstructionData<S>,
|
data: &InInstructionData<S>,
|
||||||
) {
|
) {
|
||||||
let mut buf = data.session_to_sign_batch.encode();
|
let mut buf = borsh::to_vec(&data.session_to_sign_batch).unwrap();
|
||||||
buf.extend(data.external_key_for_session_to_sign_batch.to_bytes().as_ref());
|
buf.extend(data.external_key_for_session_to_sign_batch.to_bytes().as_ref());
|
||||||
for returnable_in_instruction in &data.returnable_in_instructions {
|
for returnable_in_instruction in &data.returnable_in_instructions {
|
||||||
returnable_in_instruction.write(&mut buf).unwrap();
|
returnable_in_instruction.write(&mut buf).unwrap();
|
||||||
@@ -517,7 +517,7 @@ impl<S: ScannerFeed> ScanToBatchDb<S> {
|
|||||||
);
|
);
|
||||||
let mut buf = data.returnable_in_instructions.as_slice();
|
let mut buf = data.returnable_in_instructions.as_slice();
|
||||||
|
|
||||||
let session_to_sign_batch = Session::decode(&mut buf).unwrap();
|
let session_to_sign_batch = Session::deserialize_reader(&mut buf).unwrap();
|
||||||
let external_key_for_session_to_sign_batch = {
|
let external_key_for_session_to_sign_batch = {
|
||||||
let mut external_key_for_session_to_sign_batch =
|
let mut external_key_for_session_to_sign_batch =
|
||||||
<KeyFor<S> as GroupEncoding>::Repr::default();
|
<KeyFor<S> as GroupEncoding>::Repr::default();
|
||||||
@@ -595,7 +595,7 @@ impl SubstrateToEventualityDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod _public_db {
|
mod _public_db {
|
||||||
use serai_in_instructions_primitives::Batch;
|
use serai_primitives::instructions::Batch;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use scale::Encode;
|
use borsh::BorshSerialize;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
use primitives::{EncodableG, ReceivedOutput, Eventuality, EventualityTracker};
|
use primitives::{EncodableG, ReceivedOutput, Eventuality, EventualityTracker};
|
||||||
@@ -14,7 +15,7 @@ create_db!(
|
|||||||
// The latest block this task has handled which was notable
|
// The latest block this task has handled which was notable
|
||||||
LatestHandledNotableBlock: () -> u64,
|
LatestHandledNotableBlock: () -> u64,
|
||||||
|
|
||||||
SerializedEventualities: <K: Encode>(key: K) -> Vec<u8>,
|
SerializedEventualities: <K: BorshSerialize>(key: K) -> Vec<u8>,
|
||||||
|
|
||||||
AccumulatedOutput: (id: &[u8]) -> (),
|
AccumulatedOutput: (id: &[u8]) -> (),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ use group::GroupEncoding;
|
|||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::{Get, DbTxn, Db};
|
use serai_db::{Get, DbTxn, Db};
|
||||||
|
|
||||||
use serai_primitives::{ExternalNetworkId, ExternalCoin, Amount};
|
use serai_primitives::{
|
||||||
use serai_coins_primitives::OutInstructionWithBalance;
|
network_id::ExternalNetworkId, coin::ExternalCoin, balance::Amount,
|
||||||
|
instructions::OutInstructionWithBalance,
|
||||||
|
};
|
||||||
|
|
||||||
use messages::substrate::ExecutedBatch;
|
use messages::substrate::ExecutedBatch;
|
||||||
use primitives::{task::*, Address, ReceivedOutput, Block, Payment};
|
use primitives::{task::*, Address, ReceivedOutput, Block, Payment};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
create_db!(
|
create_db!(
|
||||||
ScannerBatch {
|
ScannerBatch {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use core::{marker::PhantomData, future::Future};
|
|||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use primitives::task::{DoesNotError, ContinuallyRan};
|
use primitives::task::{DoesNotError, ContinuallyRan};
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -70,12 +70,12 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ReportTask<D, S> {
|
|||||||
// Because this boolean was expanded, we lose short-circuiting. That's fine
|
// Because this boolean was expanded, we lose short-circuiting. That's fine
|
||||||
let handover_batch = last_session != session_to_sign_batch;
|
let handover_batch = last_session != session_to_sign_batch;
|
||||||
let batch_after_handover_batch =
|
let batch_after_handover_batch =
|
||||||
(last_session == session_to_sign_batch) && ((first_batch + 1) == batch.id);
|
(last_session == session_to_sign_batch) && ((first_batch + 1) == batch.id());
|
||||||
if handover_batch || batch_after_handover_batch {
|
if handover_batch || batch_after_handover_batch {
|
||||||
let verified_prior_batch = substrate::last_acknowledged_batch::<S>(&txn)
|
let verified_prior_batch = substrate::last_acknowledged_batch::<S>(&txn)
|
||||||
// Since `batch.id = 0` in the Session(0)-never-published-a-Batch case, we don't
|
// Since `batch.id() = 0` in the Session(0)-never-published-a-Batch case, we don't
|
||||||
// check `last_acknowledged_batch >= (batch.id - 1)` but instead this
|
// check `last_acknowledged_batch >= (batch.id() - 1)` but instead this
|
||||||
.map(|last_acknowledged_batch| (last_acknowledged_batch + 1) >= batch.id)
|
.map(|last_acknowledged_batch| (last_acknowledged_batch + 1) >= batch.id())
|
||||||
// We've never verified any Batches
|
// We've never verified any Batches
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if !verified_prior_batch {
|
if !verified_prior_batch {
|
||||||
@@ -90,7 +90,7 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for ReportTask<D, S> {
|
|||||||
BatchDb::set_last_session_to_sign_batch_and_first_batch(
|
BatchDb::set_last_session_to_sign_batch_and_first_batch(
|
||||||
&mut txn,
|
&mut txn,
|
||||||
session_to_sign_batch,
|
session_to_sign_batch,
|
||||||
batch.id,
|
batch.id(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use scale::Decode;
|
use borsh::BorshDeserialize;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, Db};
|
use serai_db::{Get, DbTxn, Db};
|
||||||
|
|
||||||
use serai_in_instructions_primitives::{
|
#[rustfmt::skip]
|
||||||
Shorthand, RefundableInInstruction, InInstruction, InInstructionWithBalance,
|
use serai_primitives::instructions::{RefundableInInstruction, InInstruction, InInstructionWithBalance};
|
||||||
};
|
|
||||||
|
|
||||||
use primitives::{task::ContinuallyRan, OutputType, ReceivedOutput, Block};
|
use primitives::{task::ContinuallyRan, OutputType, ReceivedOutput, Block};
|
||||||
|
|
||||||
@@ -55,26 +55,22 @@ fn in_instruction_from_output<S: ScannerFeed>(
|
|||||||
let presumed_origin = output.presumed_origin();
|
let presumed_origin = output.presumed_origin();
|
||||||
|
|
||||||
let mut data = output.data();
|
let mut data = output.data();
|
||||||
let shorthand = match Shorthand::decode(&mut data) {
|
let instruction = match RefundableInInstruction::deserialize_reader(&mut data) {
|
||||||
Ok(shorthand) => shorthand,
|
|
||||||
Err(e) => {
|
|
||||||
log::info!("data in output {} wasn't valid shorthand: {e:?}", hex::encode(output.id()));
|
|
||||||
return (presumed_origin, None);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let instruction = match RefundableInInstruction::try_from(shorthand) {
|
|
||||||
Ok(instruction) => instruction,
|
Ok(instruction) => instruction,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::info!(
|
log::info!(
|
||||||
"shorthand in output {} wasn't convertible to a RefundableInInstruction: {e:?}",
|
"data in output {} wasn't a valid `RefundableInInstruction`: {e:?}",
|
||||||
hex::encode(output.id())
|
hex::encode(output.id()),
|
||||||
);
|
);
|
||||||
return (presumed_origin, None);
|
return (presumed_origin, None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
instruction.origin.and_then(|addr| AddressFor::<S>::try_from(addr).ok()).or(presumed_origin),
|
instruction
|
||||||
|
.return_address
|
||||||
|
.and_then(|addr| AddressFor::<S>::try_from(addr).ok())
|
||||||
|
.or(presumed_origin),
|
||||||
Some(instruction.instruction),
|
Some(instruction.instruction),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use group::GroupEncoding;
|
|||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||||
|
|
||||||
use serai_coins_primitives::OutInstructionWithBalance;
|
use serai_primitives::instructions::OutInstructionWithBalance;
|
||||||
|
|
||||||
use messages::substrate::ExecutedBatch;
|
use messages::substrate::ExecutedBatch;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use core::{marker::PhantomData, future::Future};
|
|||||||
|
|
||||||
use serai_db::{Get, DbTxn, Db};
|
use serai_db::{Get, DbTxn, Db};
|
||||||
|
|
||||||
use serai_coins_primitives::{OutInstruction, OutInstructionWithBalance};
|
use serai_primitives::instructions::{OutInstruction, OutInstructionWithBalance};
|
||||||
|
|
||||||
use messages::substrate::ExecutedBatch;
|
use messages::substrate::ExecutedBatch;
|
||||||
use primitives::task::{DoesNotError, ContinuallyRan};
|
use primitives::task::{DoesNotError, ContinuallyRan};
|
||||||
@@ -150,7 +150,7 @@ impl<D: Db, S: ScannerFeed> ContinuallyRan for SubstrateTask<D, S> {
|
|||||||
|
|
||||||
if let Some(batch::ReturnInformation { address, balance }) = return_information {
|
if let Some(batch::ReturnInformation { address, balance }) = return_information {
|
||||||
burns.push(OutInstructionWithBalance {
|
burns.push(OutInstructionWithBalance {
|
||||||
instruction: OutInstruction { address: address.into() },
|
instruction: OutInstruction::Transfer(address.into()),
|
||||||
balance,
|
balance,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
ignored = ["scale", "borsh"]
|
ignored = ["borsh"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -24,7 +24,6 @@ workspace = true
|
|||||||
ciphersuite = { path = "../../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
ciphersuite = { path = "../../../crypto/ciphersuite", default-features = false, features = ["std"] }
|
||||||
frost = { package = "modular-frost", path = "../../../crypto/frost", default-features = false }
|
frost = { package = "modular-frost", path = "../../../crypto/frost", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
serai-db = { path = "../../../common/db" }
|
serai-db = { path = "../../../common/db" }
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
ignored = ["scale", "borsh"]
|
ignored = ["borsh"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -23,7 +23,6 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
group = { version = "0.13", default-features = false }
|
group = { version = "0.13", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
serai-db = { path = "../../../common/db" }
|
serai-db = { path = "../../../common/db" }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use core::{fmt::Debug, future::Future};
|
use core::{fmt::Debug, future::Future};
|
||||||
|
|
||||||
use serai_primitives::Amount;
|
use serai_primitives::balance::Amount;
|
||||||
|
|
||||||
use primitives::{ReceivedOutput, Payment};
|
use primitives::{ReceivedOutput, Payment};
|
||||||
use scanner::{ScannerFeed, KeyFor, AddressFor, OutputFor, EventualityFor, BlockFor};
|
use scanner::{ScannerFeed, KeyFor, AddressFor, OutputFor, EventualityFor, BlockFor};
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
use serai_primitives::{
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use primitives::{Address, Payment};
|
use primitives::{Address, Payment};
|
||||||
use scanner::ScannerFeed;
|
use scanner::ScannerFeed;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
ignored = ["scale", "borsh"]
|
ignored = ["borsh"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -23,7 +23,6 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
group = { version = "0.13", default-features = false }
|
group = { version = "0.13", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
serai-primitives = { path = "../../../../substrate/primitives", default-features = false, features = ["std"] }
|
serai-primitives = { path = "../../../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
use serai_primitives::{
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use borsh::BorshDeserialize;
|
use borsh::BorshDeserialize;
|
||||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use serai_primitives::{ExternalCoin, Amount, ExternalBalance};
|
use serai_primitives::{
|
||||||
|
coin::ExternalCoin,
|
||||||
|
balance::{Amount, ExternalBalance},
|
||||||
|
};
|
||||||
|
|
||||||
use serai_db::DbTxn;
|
use serai_db::DbTxn;
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[package.metadata.cargo-machete]
|
[package.metadata.cargo-machete]
|
||||||
ignored = ["scale", "borsh"]
|
ignored = ["borsh"]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
@@ -23,7 +23,6 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
group = { version = "0.13", default-features = false }
|
group = { version = "0.13", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
serai-primitives = { path = "../../../../substrate/primitives", default-features = false, features = ["std"] }
|
serai-primitives = { path = "../../../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use serai_primitives::{ExternalCoin, Amount};
|
use serai_primitives::{coin::ExternalCoin, balance::Amount};
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
|
|
||||||
use serai_primitives::{ExternalCoin, Amount};
|
use serai_primitives::{coin::ExternalCoin, balance::Amount};
|
||||||
|
|
||||||
use serai_db::DbTxn;
|
use serai_db::DbTxn;
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ dalek-ff-group = { path = "../../crypto/dalek-ff-group", default-features = fals
|
|||||||
frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false }
|
frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false }
|
||||||
frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false }
|
frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false }
|
||||||
|
|
||||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["std"] }
|
|
||||||
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
borsh = { version = "1", default-features = false, features = ["std", "derive", "de_strict_order"] }
|
||||||
|
|
||||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std"] }
|
||||||
@@ -39,7 +38,7 @@ serai-db = { path = "../../common/db" }
|
|||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "sync", "time", "macros"] }
|
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "sync", "time", "macros"] }
|
||||||
|
|
||||||
serai-cosign = { path = "../../coordinator/cosign" }
|
serai-cosign = { package = "serai-cosign-types", path = "../../coordinator/cosign/types" }
|
||||||
messages = { package = "serai-processor-messages", path = "../messages" }
|
messages = { package = "serai-processor-messages", path = "../messages" }
|
||||||
primitives = { package = "serai-processor-primitives", path = "../primitives" }
|
primitives = { package = "serai-processor-primitives", path = "../primitives" }
|
||||||
scanner = { package = "serai-processor-scanner", path = "../scanner" }
|
scanner = { package = "serai-processor-scanner", path = "../scanner" }
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::{
|
||||||
use serai_in_instructions_primitives::{Batch, SignedBatch};
|
validator_sets::Session,
|
||||||
|
instructions::{Batch, SignedBatch},
|
||||||
|
};
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,7 @@ use ciphersuite::group::GroupEncoding;
|
|||||||
use dalek_ff_group::Ristretto;
|
use dalek_ff_group::Ristretto;
|
||||||
use frost::dkg::ThresholdKeys;
|
use frost::dkg::ThresholdKeys;
|
||||||
|
|
||||||
use scale::Encode;
|
use serai_primitives::{validator_sets::Session, instructions::SignedBatch};
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
|
||||||
use serai_in_instructions_primitives::{SignedBatch, batch_message};
|
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, Db};
|
use serai_db::{Get, DbTxn, Db};
|
||||||
|
|
||||||
@@ -74,7 +71,7 @@ impl<D: Db, E: GroupEncoding> BatchSignerTask<D, E> {
|
|||||||
machines.push(WrappedSchnorrkelMachine::new(
|
machines.push(WrappedSchnorrkelMachine::new(
|
||||||
keys.clone(),
|
keys.clone(),
|
||||||
b"substrate",
|
b"substrate",
|
||||||
batch_message(&batch),
|
batch.publish_batch_message(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
attempt_manager.register(VariantSignId::Batch(id), machines);
|
attempt_manager.register(VariantSignId::Batch(id), machines);
|
||||||
@@ -100,14 +97,14 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
|
|||||||
iterated = true;
|
iterated = true;
|
||||||
|
|
||||||
// Save this to the database as a transaction to sign
|
// Save this to the database as a transaction to sign
|
||||||
let batch_hash = <[u8; 32]>::from(Blake2b::<U32>::digest(batch.encode()));
|
let batch_hash = <[u8; 32]>::from(Blake2b::<U32>::digest(borsh::to_vec(&batch).unwrap()));
|
||||||
self.active_signing_protocols.insert(batch_hash);
|
self.active_signing_protocols.insert(batch_hash);
|
||||||
ActiveSigningProtocols::set(
|
ActiveSigningProtocols::set(
|
||||||
&mut txn,
|
&mut txn,
|
||||||
self.session,
|
self.session,
|
||||||
&self.active_signing_protocols.iter().copied().collect(),
|
&self.active_signing_protocols.iter().copied().collect(),
|
||||||
);
|
);
|
||||||
BatchHash::set(&mut txn, batch.id, &batch_hash);
|
BatchHash::set(&mut txn, batch.id(), &batch_hash);
|
||||||
Batches::set(&mut txn, batch_hash, &batch);
|
Batches::set(&mut txn, batch_hash, &batch);
|
||||||
|
|
||||||
let mut machines = Vec::with_capacity(self.keys.len());
|
let mut machines = Vec::with_capacity(self.keys.len());
|
||||||
@@ -116,7 +113,7 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
|
|||||||
machines.push(WrappedSchnorrkelMachine::new(
|
machines.push(WrappedSchnorrkelMachine::new(
|
||||||
keys.clone(),
|
keys.clone(),
|
||||||
b"substrate",
|
b"substrate",
|
||||||
batch_message(&batch),
|
batch.publish_batch_message(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for msg in self.attempt_manager.register(VariantSignId::Batch(batch_hash), machines) {
|
for msg in self.attempt_manager.register(VariantSignId::Batch(batch_hash), machines) {
|
||||||
@@ -160,8 +157,8 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
|
|||||||
// Update the last acknowledged Batch
|
// Update the last acknowledged Batch
|
||||||
{
|
{
|
||||||
let last_acknowledged = LastAcknowledgedBatch::get(&txn);
|
let last_acknowledged = LastAcknowledgedBatch::get(&txn);
|
||||||
if Some(batch.id) > last_acknowledged {
|
if Some(batch.id()) > last_acknowledged {
|
||||||
LastAcknowledgedBatch::set(&mut txn, &batch.id);
|
LastAcknowledgedBatch::set(&mut txn, &batch.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +171,7 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Clean up SignedBatches
|
// Clean up SignedBatches
|
||||||
SignedBatches::del(&mut txn, batch.id);
|
SignedBatches::del(&mut txn, batch.id());
|
||||||
|
|
||||||
// We retire with a txn so we either successfully flag this Batch as acknowledged, and
|
// We retire with a txn so we either successfully flag this Batch as acknowledged, and
|
||||||
// won't re-register it (making this retire safe), or we don't flag it, meaning we will
|
// won't re-register it (making this retire safe), or we don't flag it, meaning we will
|
||||||
@@ -203,7 +200,7 @@ impl<D: Db, E: Send + GroupEncoding> ContinuallyRan for BatchSignerTask<D, E> {
|
|||||||
let batch =
|
let batch =
|
||||||
Batches::get(&txn, id).expect("signed a Batch we didn't save to the database");
|
Batches::get(&txn, id).expect("signed a Batch we didn't save to the database");
|
||||||
let signed_batch = SignedBatch { batch, signature: signature.into() };
|
let signed_batch = SignedBatch { batch, signature: signature.into() };
|
||||||
SignedBatches::set(&mut txn, signed_batch.batch.id, &signed_batch);
|
SignedBatches::set(&mut txn, signed_batch.batch.id(), &signed_batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
|
||||||
use serai_primitives::Signature;
|
use serai_primitives::crypto::Signature;
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ impl<D: Db, C: Coordinator> ContinuallyRan for CoordinatorTask<D, C> {
|
|||||||
let mut next_batch = last_batch.map(|id| id + 1).unwrap_or(0);
|
let mut next_batch = last_batch.map(|id| id + 1).unwrap_or(0);
|
||||||
while let Some(batch) = crate::batch::signed_batch(&txn, next_batch) {
|
while let Some(batch) = crate::batch::signed_batch(&txn, next_batch) {
|
||||||
iterated = true;
|
iterated = true;
|
||||||
db::LastPublishedBatch::set(&mut txn, &batch.batch.id);
|
db::LastPublishedBatch::set(&mut txn, &batch.batch.id());
|
||||||
self
|
self
|
||||||
.coordinator
|
.coordinator
|
||||||
.publish_signed_batch(batch)
|
.publish_signed_batch(batch)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ use core::future::Future;
|
|||||||
use dalek_ff_group::Ristretto;
|
use dalek_ff_group::Ristretto;
|
||||||
use frost::dkg::ThresholdKeys;
|
use frost::dkg::ThresholdKeys;
|
||||||
|
|
||||||
use scale::Encode;
|
use serai_primitives::{crypto::Signature, validator_sets::Session};
|
||||||
use serai_primitives::Signature;
|
|
||||||
use serai_validator_sets_primitives::Session;
|
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
@@ -127,7 +125,7 @@ impl<D: Db> ContinuallyRan for CosignerTask<D> {
|
|||||||
LatestCosigned::set(&mut txn, self.session, &cosign.block_number);
|
LatestCosigned::set(&mut txn, self.session, &cosign.block_number);
|
||||||
let cosign = SignedCosign {
|
let cosign = SignedCosign {
|
||||||
cosign,
|
cosign,
|
||||||
signature: Signature::from(signature).encode().try_into().unwrap(),
|
signature: borsh::to_vec(&Signature::from(signature)).unwrap().try_into().unwrap(),
|
||||||
};
|
};
|
||||||
// Send the cosign
|
// Send the cosign
|
||||||
Cosign::send(&mut txn, self.session, &cosign);
|
Cosign::send(&mut txn, self.session, &cosign);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serai_validator_sets_primitives::{Session, SlashReport as SlashReportStruct};
|
use serai_primitives::validator_sets::{Session, SlashReport as SlashReportStruct};
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db, db_channel};
|
use serai_db::{Get, DbTxn, create_db, db_channel};
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ use ciphersuite::{group::GroupEncoding, Ciphersuite};
|
|||||||
use dalek_ff_group::Ristretto;
|
use dalek_ff_group::Ristretto;
|
||||||
use frost::dkg::ThresholdKeys;
|
use frost::dkg::ThresholdKeys;
|
||||||
|
|
||||||
use serai_primitives::Signature;
|
use serai_primitives::{
|
||||||
use serai_validator_sets_primitives::{Session, SlashReport};
|
crypto::Signature,
|
||||||
use serai_in_instructions_primitives::SignedBatch;
|
validator_sets::{Session, SlashReport},
|
||||||
|
instructions::SignedBatch,
|
||||||
|
};
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ use core::{marker::PhantomData, future::Future};
|
|||||||
use dalek_ff_group::Ristretto;
|
use dalek_ff_group::Ristretto;
|
||||||
use frost::dkg::ThresholdKeys;
|
use frost::dkg::ThresholdKeys;
|
||||||
|
|
||||||
use serai_primitives::Signature;
|
use serai_primitives::{crypto::Signature, validator_sets::Session};
|
||||||
use serai_validator_sets_primitives::Session;
|
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{Get, DbTxn, create_db};
|
use serai_db::{Get, DbTxn, create_db};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
|
|
||||||
use frost::dkg::ThresholdKeys;
|
use frost::dkg::ThresholdKeys;
|
||||||
|
|
||||||
use serai_validator_sets_primitives::Session;
|
use serai_primitives::validator_sets::Session;
|
||||||
|
|
||||||
use serai_db::{DbTxn, Db};
|
use serai_db::{DbTxn, Db};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ thiserror = { version = "2", default-features = false, optional = true }
|
|||||||
bitvec = { version = "1", default-features = false, features = ["alloc", "serde"] }
|
bitvec = { version = "1", default-features = false, features = ["alloc", "serde"] }
|
||||||
|
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
scale = { package = "parity-scale-codec", version = "3" }
|
scale = { package = "parity-scale-codec", version = "3", optional = true }
|
||||||
borsh = { version = "1", features = ["derive"] }
|
borsh = { version = "1", features = ["derive"] }
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"], optional = true }
|
||||||
serde_json = { version = "1", optional = true }
|
serde_json = { version = "1", optional = true }
|
||||||
@@ -64,7 +64,7 @@ dockertest = "0.5"
|
|||||||
serai-docker-tests = { path = "../../tests/docker" }
|
serai-docker-tests = { path = "../../tests/docker" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serai = ["thiserror/std", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
|
serai = ["thiserror/std", "scale", "serde", "serde_json", "multiaddr", "sp-core", "sp-runtime", "frame-system", "simple-request"]
|
||||||
|
|
||||||
networks = []
|
networks = []
|
||||||
bitcoin = ["networks", "dep:bitcoin"]
|
bitcoin = ["networks", "dep:bitcoin"]
|
||||||
@@ -73,4 +73,4 @@ monero = ["networks", "dalek-ff-group", "ciphersuite", "monero-address"]
|
|||||||
|
|
||||||
# Assumes the default usage is to use Serai as a DEX, which doesn't actually
|
# Assumes the default usage is to use Serai as a DEX, which doesn't actually
|
||||||
# require connecting to a Serai node
|
# require connecting to a Serai node
|
||||||
default = ["bitcoin", "monero"]
|
default = ["bitcoin", "ethereum", "monero"]
|
||||||
|
|||||||
@@ -8,20 +8,6 @@ pub use serai::*;
|
|||||||
|
|
||||||
#[cfg(not(feature = "serai"))]
|
#[cfg(not(feature = "serai"))]
|
||||||
pub use serai_abi::primitives;
|
pub use serai_abi::primitives;
|
||||||
#[cfg(not(feature = "serai"))]
|
|
||||||
mod other_primitives {
|
|
||||||
pub mod coins {
|
|
||||||
pub use serai_abi::coins::primitives;
|
|
||||||
}
|
|
||||||
pub mod validator_sets {
|
|
||||||
pub use serai_abi::validator_sets::primitives;
|
|
||||||
}
|
|
||||||
pub mod in_instructions {
|
|
||||||
pub use serai_abi::in_instructions::primitives;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "serai"))]
|
|
||||||
pub use other_primitives::*;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use core::{str::FromStr, fmt};
|
use core::{str::FromStr, fmt};
|
||||||
|
|
||||||
use scale::{Encode, Decode};
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use bitcoin::{
|
use bitcoin::{
|
||||||
@@ -11,10 +10,10 @@ use bitcoin::{
|
|||||||
address::{AddressType, NetworkChecked, Address as BAddress},
|
address::{AddressType, NetworkChecked, Address as BAddress},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::primitives::ExternalAddress;
|
use crate::primitives::address::ExternalAddress;
|
||||||
|
|
||||||
// SCALE-encodable representation of Bitcoin addresses, used internally.
|
// SCALE-encodable representation of Bitcoin addresses, used internally.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, BorshSerialize, BorshDeserialize)]
|
||||||
enum EncodedAddress {
|
enum EncodedAddress {
|
||||||
P2PKH([u8; 20]),
|
P2PKH([u8; 20]),
|
||||||
P2SH([u8; 20]),
|
P2SH([u8; 20]),
|
||||||
@@ -124,7 +123,7 @@ impl TryFrom<ExternalAddress> for Address {
|
|||||||
fn try_from(data: ExternalAddress) -> Result<Address, ()> {
|
fn try_from(data: ExternalAddress) -> Result<Address, ()> {
|
||||||
// Decode as an EncodedAddress, then map to a ScriptBuf
|
// Decode as an EncodedAddress, then map to a ScriptBuf
|
||||||
let mut data = data.as_ref();
|
let mut data = data.as_ref();
|
||||||
let encoded = EncodedAddress::decode(&mut data).map_err(|_| ())?;
|
let encoded = EncodedAddress::deserialize_reader(&mut data).map_err(|_| ())?;
|
||||||
if !data.is_empty() {
|
if !data.is_empty() {
|
||||||
Err(())?
|
Err(())?
|
||||||
}
|
}
|
||||||
@@ -141,8 +140,8 @@ impl From<Address> for EncodedAddress {
|
|||||||
|
|
||||||
impl From<Address> for ExternalAddress {
|
impl From<Address> for ExternalAddress {
|
||||||
fn from(addr: Address) -> ExternalAddress {
|
fn from(addr: Address) -> ExternalAddress {
|
||||||
// Safe since all variants are fixed-length and fit into MAX_ADDRESS_LEN
|
// Safe since all variants are fixed-length and fit into `MAX_ADDRESS_LEN`
|
||||||
ExternalAddress::new(EncodedAddress::from(addr).encode()).unwrap()
|
ExternalAddress::try_from(borsh::to_vec(&EncodedAddress::from(addr)).unwrap()).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
use borsh::{BorshSerialize, BorshDeserialize};
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
|
||||||
use crate::primitives::{MAX_ADDRESS_LEN, ExternalAddress};
|
use crate::primitives::address::ExternalAddress;
|
||||||
|
|
||||||
/// THe maximum amount of gas an address is allowed to specify as its gas limit.
|
/// THe maximum amount of gas an address is allowed to specify as its gas limit.
|
||||||
///
|
///
|
||||||
@@ -33,7 +33,8 @@ impl ContractDeployment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The max address length, minus the type byte, minus the size of the gas
|
// The max address length, minus the type byte, minus the size of the gas
|
||||||
const MAX_CODE_LEN: usize = (MAX_ADDRESS_LEN as usize) - (1 + core::mem::size_of::<u32>());
|
const MAX_CODE_LEN: usize =
|
||||||
|
(ExternalAddress::MAX_LEN as usize) - (1 + core::mem::size_of::<u32>());
|
||||||
if code.len() > MAX_CODE_LEN {
|
if code.len() > MAX_CODE_LEN {
|
||||||
None?;
|
None?;
|
||||||
}
|
}
|
||||||
@@ -111,7 +112,7 @@ impl From<Address> for ExternalAddress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We only construct addresses whose code is small enough this can safely be constructed
|
// We only construct addresses whose code is small enough this can safely be constructed
|
||||||
ExternalAddress::new(res).unwrap()
|
ExternalAddress::try_from(res).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use ciphersuite::Ciphersuite;
|
|||||||
|
|
||||||
use monero_address::{Network, AddressType as MoneroAddressType, MoneroAddress};
|
use monero_address::{Network, AddressType as MoneroAddressType, MoneroAddress};
|
||||||
|
|
||||||
use crate::primitives::ExternalAddress;
|
use crate::primitives::address::ExternalAddress;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
enum AddressType {
|
enum AddressType {
|
||||||
@@ -123,7 +123,7 @@ impl TryFrom<ExternalAddress> for Address {
|
|||||||
impl From<Address> for ExternalAddress {
|
impl From<Address> for ExternalAddress {
|
||||||
fn from(address: Address) -> ExternalAddress {
|
fn from(address: Address) -> ExternalAddress {
|
||||||
// This is 65 bytes which is less than MAX_ADDRESS_LEN
|
// This is 65 bytes which is less than MAX_ADDRESS_LEN
|
||||||
ExternalAddress::new(borsh::to_vec(&address).unwrap()).unwrap()
|
ExternalAddress::try_from(borsh::to_vec(&address).unwrap()).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,16 +25,18 @@ scale-info = { version = "2", default-features = false, features = ["derive"], o
|
|||||||
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "2bfdaed4b3614de2fe7d10e4ece3e6a912833e90", default-features = false }
|
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "2bfdaed4b3614de2fe7d10e4ece3e6a912833e90", default-features = false }
|
||||||
|
|
||||||
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["alloc"] }
|
ciphersuite = { path = "../../crypto/ciphersuite", default-features = false, features = ["alloc"] }
|
||||||
dalek-ff-group = { path = "../../crypto/dalek-ff-group", default-features = false }
|
dalek-ff-group = { path = "../../crypto/dalek-ff-group", default-features = false, features = ["alloc"] }
|
||||||
dkg = { package = "dkg-musig", path = "../../crypto/dkg/musig", default-features = false }
|
dkg = { package = "dkg-musig", path = "../../crypto/dkg/musig", default-features = false }
|
||||||
|
|
||||||
|
schnorrkel = { version = "0.11", default-features = false }
|
||||||
|
|
||||||
bech32 = { version = "0.11", default-features = false }
|
bech32 = { version = "0.11", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = ["zeroize/std", "borsh/std", "bitvec/std", "scale/std", "scale-info/std", "sp-core/std", "ciphersuite/std", "dalek-ff-group/std", "dkg/std", "bech32/std"]
|
std = ["zeroize/std", "borsh/std", "bitvec/std", "scale?/std", "scale-info?/std", "sp-core/std", "ciphersuite/std", "dalek-ff-group/std", "dkg/std", "schnorrkel/std", "bech32/std"]
|
||||||
serde = []
|
serde = []
|
||||||
non_canonical_scale_derivations = ["scale", "scale-info"]
|
non_canonical_scale_derivations = ["scale", "scale-info"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use core::convert::AsRef;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
@@ -150,13 +151,18 @@ impl TryFrom<Vec<u8>> for ExternalAddress {
|
|||||||
vec.try_into().map(ExternalAddress).map_err(|_| FromVecError::TooLong)
|
vec.try_into().map(ExternalAddress).map_err(|_| FromVecError::TooLong)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExternalAddress> for Vec<u8> {
|
impl From<ExternalAddress> for Vec<u8> {
|
||||||
fn from(ext: ExternalAddress) -> Vec<u8> {
|
fn from(ext: ExternalAddress) -> Vec<u8> {
|
||||||
ext.0.into_inner()
|
ext.0.into_inner()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for ExternalAddress {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
self.0.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl zeroize::Zeroize for ExternalAddress {
|
impl zeroize::Zeroize for ExternalAddress {
|
||||||
fn zeroize(&mut self) {
|
fn zeroize(&mut self) {
|
||||||
self.0.as_mut().zeroize();
|
self.0.as_mut().zeroize();
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ impl From<Public> for sp_core::sr25519::Public {
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub struct Signature(pub [u8; 64]);
|
pub struct Signature(pub [u8; 64]);
|
||||||
|
impl From<schnorrkel::Signature> for Signature {
|
||||||
|
fn from(signature: schnorrkel::Signature) -> Self {
|
||||||
|
Self(signature.to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<sp_core::sr25519::Signature> for Signature {
|
impl From<sp_core::sr25519::Signature> for Signature {
|
||||||
fn from(signature: sp_core::sr25519::Signature) -> Self {
|
fn from(signature: sp_core::sr25519::Signature) -> Self {
|
||||||
Self(signature.0)
|
Self(signature.0)
|
||||||
@@ -71,6 +76,12 @@ pub struct ExternalKey(
|
|||||||
pub BoundedVec<u8, ConstU32<{ ExternalKey::MAX_LEN }>>,
|
pub BoundedVec<u8, ConstU32<{ ExternalKey::MAX_LEN }>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for ExternalKey {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
self.0.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Zeroize for ExternalKey {
|
impl Zeroize for ExternalKey {
|
||||||
fn zeroize(&mut self) {
|
fn zeroize(&mut self) {
|
||||||
self.0.as_mut().zeroize();
|
self.0.as_mut().zeroize();
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ impl BorshDeserialize for Batch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An error incurred while pushing an instruction onto a `Batch`.
|
/// An error incurred while pushing an instruction onto a `Batch`.
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum PushInstructionError {
|
pub enum PushInstructionError {
|
||||||
/// The Batch's max size was exceeded.
|
/// The Batch's max size was exceeded.
|
||||||
MaxSizeExceeded,
|
MaxSizeExceeded,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ pub struct RefundableInInstruction {
|
|||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, BorshSerialize, BorshDeserialize)]
|
||||||
pub struct InInstructionWithBalance {
|
pub struct InInstructionWithBalance {
|
||||||
/// The instruction on how to handle coins in.
|
/// The instruction on how to handle coins in.
|
||||||
pub instruction: OutInstruction,
|
pub instruction: InInstruction,
|
||||||
/// The coins in.
|
/// The coins in.
|
||||||
pub balance: ExternalBalance,
|
pub balance: ExternalBalance,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
mod r#in;
|
mod r#in;
|
||||||
pub use r#in::{InInstruction, InInstructionWithBalance, PushInstructionError, Batch, SignedBatch};
|
pub use r#in::{
|
||||||
|
InInstruction, InInstructionWithBalance, RefundableInInstruction, PushInstructionError, Batch,
|
||||||
|
SignedBatch,
|
||||||
|
};
|
||||||
|
|
||||||
mod out;
|
mod out;
|
||||||
pub use out::{OutInstruction, OutInstructionWithBalance};
|
pub use out::{OutInstruction, OutInstructionWithBalance};
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ impl ExternalNetworkId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The coins native to this network.
|
/// The coins native to this network.
|
||||||
pub fn coins(&self) -> &'static [ExternalCoin] {
|
pub fn coins(&self) -> impl Iterator<Item = ExternalCoin> {
|
||||||
match self {
|
match self {
|
||||||
Self::Bitcoin => &[ExternalCoin::Bitcoin],
|
Self::Bitcoin => [ExternalCoin::Bitcoin].as_slice().iter().copied(),
|
||||||
Self::Ethereum => &[ExternalCoin::Ether, ExternalCoin::Dai],
|
Self::Ethereum => [ExternalCoin::Ether, ExternalCoin::Dai].as_slice().iter().copied(),
|
||||||
Self::Monero => &[ExternalCoin::Monero],
|
Self::Monero => [ExternalCoin::Monero].as_slice().iter().copied(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,11 +119,11 @@ impl NetworkId {
|
|||||||
|
|
||||||
/// The coins native to this network.
|
/// The coins native to this network.
|
||||||
pub fn coins(self) -> impl Iterator<Item = Coin> {
|
pub fn coins(self) -> impl Iterator<Item = Coin> {
|
||||||
let (coins, external_coins): (&[Coin], &[ExternalCoin]) = match self {
|
let (coins, external_coins): (&[Coin], _) = match self {
|
||||||
NetworkId::Serai => (&[Coin::Serai], &[]),
|
NetworkId::Serai => (&[Coin::Serai], None),
|
||||||
NetworkId::External(ext) => (&[], ext.coins()),
|
NetworkId::External(ext) => (&[], Some(ext.coins())),
|
||||||
};
|
};
|
||||||
coins.iter().copied().chain(external_coins.iter().copied().map(Into::into))
|
coins.iter().copied().chain(external_coins.into_iter().flatten().map(Into::into))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user