mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-07 19:59:23 +00:00
Compare commits
16 Commits
9c47ef2658
...
ca93c82156
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca93c82156 | ||
|
|
5b1875dae6 | ||
|
|
bcd68441be | ||
|
|
4ebf9ad9c7 | ||
|
|
807572199c | ||
|
|
3cdc1536c5 | ||
|
|
9e13e5ebff | ||
|
|
9b2c254eee | ||
|
|
0883479068 | ||
|
|
c5480c63be | ||
|
|
4280ee6987 | ||
|
|
91673d7ae3 | ||
|
|
927f07b62b | ||
|
|
7e774d6d2d | ||
|
|
fccd06b376 | ||
|
|
e3edc0a7fc |
2
.github/actions/bitcoin/action.yml
vendored
2
.github/actions/bitcoin/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
||||
version:
|
||||
description: "Version to download and run"
|
||||
required: false
|
||||
default: "29.1"
|
||||
default: "30.0"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
@@ -52,9 +52,9 @@ runs:
|
||||
- name: Install solc
|
||||
shell: bash
|
||||
run: |
|
||||
cargo +1.90 install svm-rs --version =0.5.19
|
||||
svm install 0.8.26
|
||||
svm use 0.8.26
|
||||
cargo +1.91 install svm-rs --version =0.5.19
|
||||
svm install 0.8.29
|
||||
svm use 0.8.29
|
||||
|
||||
- name: Remove preinstalled Docker
|
||||
shell: bash
|
||||
|
||||
2
.github/actions/monero-wallet-rpc/action.yml
vendored
2
.github/actions/monero-wallet-rpc/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
||||
version:
|
||||
description: "Version to download and run"
|
||||
required: false
|
||||
default: v0.18.3.4
|
||||
default: v0.18.4.3
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
2
.github/actions/monero/action.yml
vendored
2
.github/actions/monero/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
||||
version:
|
||||
description: "Version to download and run"
|
||||
required: false
|
||||
default: v0.18.3.4
|
||||
default: v0.18.4.3
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
4
.github/actions/test-dependencies/action.yml
vendored
4
.github/actions/test-dependencies/action.yml
vendored
@@ -5,12 +5,12 @@ inputs:
|
||||
monero-version:
|
||||
description: "Monero version to download and run as a regtest node"
|
||||
required: false
|
||||
default: v0.18.3.4
|
||||
default: v0.18.4.3
|
||||
|
||||
bitcoin-version:
|
||||
description: "Bitcoin version to download and run as a regtest node"
|
||||
required: false
|
||||
default: "29.1"
|
||||
default: "30.0"
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
||||
2
.github/nightly-version
vendored
2
.github/nightly-version
vendored
@@ -1 +1 @@
|
||||
nightly-2025-11-01
|
||||
nightly-2025-11-11
|
||||
|
||||
2
.github/workflows/daily-deny.yml
vendored
2
.github/workflows/daily-deny.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
key: rust-advisory-db
|
||||
|
||||
- name: Install cargo deny
|
||||
run: cargo +1.90 install cargo-deny --version =0.18.4
|
||||
run: cargo +1.91 install cargo-deny --version =0.18.5
|
||||
|
||||
- name: Run cargo deny
|
||||
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
||||
|
||||
20
.github/workflows/lint.yml
vendored
20
.github/workflows/lint.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
uses: ./.github/actions/build-dependencies
|
||||
|
||||
- name: Install nightly rust
|
||||
run: rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32v1-none -c rust-src -c clippy
|
||||
run: rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32v1-none -c clippy
|
||||
|
||||
- name: Run Clippy
|
||||
run: cargo +${{ steps.nightly.outputs.version }} clippy --all-features --all-targets -- -D warnings -A clippy::items_after_test_module
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
key: rust-advisory-db
|
||||
|
||||
- name: Install cargo deny
|
||||
run: cargo +1.90 install cargo-deny --version =0.18.4
|
||||
run: cargo +1.91 install cargo-deny --version =0.18.5
|
||||
|
||||
- name: Run cargo deny
|
||||
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
||||
@@ -88,8 +88,8 @@ jobs:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
- name: Verify all dependencies are in use
|
||||
run: |
|
||||
cargo +1.90 install cargo-machete --version =0.9.1
|
||||
cargo +1.90 machete
|
||||
cargo +1.91 install cargo-machete --version =0.9.1
|
||||
cargo +1.91 machete
|
||||
|
||||
msrv:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
- name: Verify claimed `rust-version`
|
||||
shell: bash
|
||||
run: |
|
||||
cargo +1.90 install cargo-msrv --version =0.18.4
|
||||
cargo +1.91 install cargo-msrv --version =0.18.4
|
||||
|
||||
function check_msrv {
|
||||
# We `cd` into the directory passed as the first argument, but will return to the
|
||||
@@ -155,8 +155,6 @@ jobs:
|
||||
# Correct the last line, which was malleated to "],"
|
||||
members=$(echo "$members" | sed "$(echo "$members" | wc -l)s/\]\,/\]/")
|
||||
|
||||
# Don't check the patches
|
||||
members=$(echo "$members" | grep -v "patches")
|
||||
# Don't check the following
|
||||
# Most of these are binaries, with the exception of the Substrate runtime which has a
|
||||
# bespoke build pipeline
|
||||
@@ -192,12 +190,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||
|
||||
- name: Build Dependencies
|
||||
uses: ./.github/actions/build-dependencies
|
||||
|
||||
- name: Slither
|
||||
run: |
|
||||
python3 -m pip install solc-select
|
||||
solc-select install 0.8.26
|
||||
solc-select use 0.8.26
|
||||
|
||||
python3 -m pip install slither-analyzer
|
||||
|
||||
slither --include-paths ./networks/ethereum/schnorr/contracts/Schnorr.sol
|
||||
|
||||
762
Cargo.lock
generated
762
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
24
Cargo.toml
24
Cargo.toml
@@ -172,6 +172,12 @@ panic = "unwind"
|
||||
overflow-checks = true
|
||||
|
||||
[patch.crates-io]
|
||||
# Point to empty crates for unused crates in our tree
|
||||
ark-ff-3 = { package = "ark-ff", path = "patches/ethereum/ark-ff-0.3" }
|
||||
ark-ff-4 = { package = "ark-ff", path = "patches/ethereum/ark-ff-0.4" }
|
||||
c-kzg = { path = "patches/ethereum/c-kzg" }
|
||||
secp256k1-30 = { package = "secp256k1", path = "patches/ethereum/secp256k1-30" }
|
||||
|
||||
# Dependencies from monero-oxide which originate from within our own tree
|
||||
std-shims = { path = "patches/std-shims" }
|
||||
simple-request = { path = "patches/simple-request" }
|
||||
@@ -182,12 +188,16 @@ dalek-ff-group = { path = "patches/dalek-ff-group" }
|
||||
minimal-ed448 = { path = "crypto/ed448" }
|
||||
modular-frost = { path = "crypto/frost" }
|
||||
|
||||
# This has a non-deprecated `std` alternative since Rust's 2024 edition
|
||||
home = { path = "patches/home" }
|
||||
|
||||
# Updates to the latest version
|
||||
darling = { path = "patches/darling" }
|
||||
thiserror = { path = "patches/thiserror" }
|
||||
|
||||
# https://github.com/rust-lang-nursery/lazy-static.rs/issues/201
|
||||
lazy_static = { git = "https://github.com/rust-lang-nursery/lazy-static.rs", rev = "5735630d46572f1e5377c8f2ba0f79d18f53b10c" }
|
||||
|
||||
# These has an `std` alternative since Rust's 2024 edition
|
||||
home = { path = "patches/home" }
|
||||
|
||||
# directories-next was created because directories was unmaintained
|
||||
# directories-next is now unmaintained while directories is maintained
|
||||
# The directories author pulls in ridiculously pointless crates and prefers
|
||||
@@ -196,10 +206,16 @@ home = { path = "patches/home" }
|
||||
option-ext = { path = "patches/option-ext" }
|
||||
directories-next = { path = "patches/directories-next" }
|
||||
|
||||
# Patch to include `FromUniformBytes<64>` over Scalar
|
||||
# Patch from a fork back to upstream
|
||||
parity-bip39 = { path = "patches/parity-bip39" }
|
||||
|
||||
# Patch to include `FromUniformBytes<64>` over `Scalar`
|
||||
k256 = { git = "https://github.com/kayabaNerve/elliptic-curves", rev = "4994c9ab163781a88cd4a49beae812a89a44e8c3" }
|
||||
p256 = { git = "https://github.com/kayabaNerve/elliptic-curves", rev = "4994c9ab163781a88cd4a49beae812a89a44e8c3" }
|
||||
|
||||
# `jemalloc` conflicts with `mimalloc`, so patch to a `rocksdb` which never uses `jemalloc`
|
||||
librocksdb-sys = { path = "patches/librocksdb-sys" }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_or_default = "allow"
|
||||
map_unwrap_or = "allow"
|
||||
|
||||
@@ -35,6 +35,9 @@ mod mutex_shim {
|
||||
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
|
||||
|
||||
#[rustversion::before(1.80)]
|
||||
pub use spin::Lazy as LazyLock;
|
||||
|
||||
#[rustversion::since(1.80)]
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub use spin::Lazy as LazyLock;
|
||||
#[rustversion::since(1.80)]
|
||||
|
||||
@@ -103,7 +103,7 @@ mod _internal_db {
|
||||
// Tributary transactions to publish from the DKG confirmation task
|
||||
TributaryTransactionsFromDkgConfirmation: (set: ExternalValidatorSet) -> Transaction,
|
||||
// Participants to remove
|
||||
RemoveParticipant: (set: ExternalValidatorSet) -> Participant,
|
||||
RemoveParticipant: (set: ExternalValidatorSet) -> u16,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,10 +139,11 @@ impl RemoveParticipant {
|
||||
pub(crate) fn send(txn: &mut impl DbTxn, set: ExternalValidatorSet, participant: Participant) {
|
||||
// If this set has yet to be retired, send this transaction
|
||||
if RetiredTributary::get(txn, set.network).map(|session| session.0) < Some(set.session.0) {
|
||||
_internal_db::RemoveParticipant::send(txn, set, &participant);
|
||||
_internal_db::RemoveParticipant::send(txn, set, &u16::from(participant));
|
||||
}
|
||||
}
|
||||
pub(crate) fn try_recv(txn: &mut impl DbTxn, set: ExternalValidatorSet) -> Option<Participant> {
|
||||
_internal_db::RemoveParticipant::try_recv(txn, set)
|
||||
.map(|i| Participant::new(i).expect("sent invalid participant index for removal"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,19 +23,12 @@ thiserror = { version = "2", default-features = false }
|
||||
|
||||
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
|
||||
|
||||
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
|
||||
|
||||
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] }
|
||||
|
||||
[features]
|
||||
std = [
|
||||
"thiserror/std",
|
||||
|
||||
"std-shims/std",
|
||||
|
||||
"borsh?/std",
|
||||
|
||||
"ciphersuite/std",
|
||||
]
|
||||
borsh = ["dep:borsh"]
|
||||
default = ["std"]
|
||||
|
||||
@@ -22,7 +22,6 @@ use ciphersuite::{
|
||||
|
||||
/// The ID of a participant, defined as a non-zero u16.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)]
|
||||
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
|
||||
pub struct Participant(u16);
|
||||
impl Participant {
|
||||
/// Create a new Participant identifier from a u16.
|
||||
@@ -129,18 +128,8 @@ pub enum DkgError {
|
||||
NotParticipating,
|
||||
}
|
||||
|
||||
// Manually implements BorshDeserialize so we can enforce it's a valid index
|
||||
#[cfg(feature = "borsh")]
|
||||
impl borsh::BorshDeserialize for Participant {
|
||||
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
Participant::new(u16::deserialize_reader(reader)?)
|
||||
.ok_or_else(|| io::Error::other("invalid participant"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameters for a multisig.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
|
||||
pub struct ThresholdParams {
|
||||
/// Participants needed to sign on behalf of the group.
|
||||
t: u16,
|
||||
@@ -210,16 +199,6 @@ impl ThresholdParams {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "borsh")]
|
||||
impl borsh::BorshDeserialize for ThresholdParams {
|
||||
fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
let t = u16::deserialize_reader(reader)?;
|
||||
let n = u16::deserialize_reader(reader)?;
|
||||
let i = Participant::deserialize_reader(reader)?;
|
||||
ThresholdParams::new(t, n, i).map_err(|e| io::Error::other(format!("{e:?}")))
|
||||
}
|
||||
}
|
||||
|
||||
/// A method of interpolation.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||
pub enum Interpolation<F: Zeroize + PrimeField> {
|
||||
|
||||
@@ -141,5 +141,7 @@ allow-git = [
|
||||
"https://github.com/kayabaNerve/elliptic-curves",
|
||||
"https://github.com/monero-oxide/monero-oxide",
|
||||
"https://github.com/kayabaNerve/monero-oxide",
|
||||
"https://github.com/rust-bitcoin/rust-bip39",
|
||||
"https://github.com/rust-rocksdb/rust-rocksdb",
|
||||
"https://github.com/serai-dex/patch-polkadot-sdk",
|
||||
]
|
||||
|
||||
@@ -30,8 +30,8 @@ k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic"
|
||||
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"] }
|
||||
|
||||
hex = { version = "0.4", default-features = false, optional = true }
|
||||
serde = { version = "1", default-features = false, features = ["derive"], optional = true }
|
||||
serde_json = { version = "1", default-features = false, optional = true }
|
||||
core-json-traits = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
|
||||
core-json-derive = { version = "0.4", default-features = false, optional = true }
|
||||
simple-request = { path = "../../common/request", version = "0.3", default-features = false, features = ["tokio", "tls", "basic-auth"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
@@ -52,15 +52,16 @@ std = [
|
||||
"rand_core/std",
|
||||
|
||||
"bitcoin/std",
|
||||
"bitcoin/serde",
|
||||
|
||||
"k256/std",
|
||||
"frost/std",
|
||||
|
||||
]
|
||||
rpc = [
|
||||
"std",
|
||||
"hex/std",
|
||||
"serde/std",
|
||||
"serde_json/std",
|
||||
"core-json-traits",
|
||||
"core-json-derive",
|
||||
"simple-request",
|
||||
]
|
||||
hazmat = []
|
||||
default = ["std"]
|
||||
default = ["std", "rpc"]
|
||||
|
||||
@@ -14,7 +14,7 @@ pub(crate) mod crypto;
|
||||
/// Wallet functionality to create transactions.
|
||||
pub mod wallet;
|
||||
/// A minimal asynchronous Bitcoin RPC client.
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(feature = "rpc")]
|
||||
pub mod rpc;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
use core::fmt::Debug;
|
||||
use std::collections::HashSet;
|
||||
use core::{str::FromStr, fmt::Debug};
|
||||
use std::{io::Read, collections::HashSet};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use serde::{Deserialize, de::DeserializeOwned};
|
||||
use serde_json::json;
|
||||
|
||||
use simple_request::{hyper, Request, TokioClient as Client};
|
||||
|
||||
use bitcoin::{
|
||||
@@ -14,19 +11,12 @@ use bitcoin::{
|
||||
Txid, Transaction, BlockHash, Block,
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Error {
|
||||
code: isize,
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum RpcResponse<T> {
|
||||
Ok { result: T },
|
||||
Err { error: Error },
|
||||
}
|
||||
|
||||
/// A minimal asynchronous Bitcoin RPC client.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Rpc {
|
||||
@@ -34,14 +24,14 @@ pub struct Rpc {
|
||||
url: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum RpcError {
|
||||
#[error("couldn't connect to node")]
|
||||
ConnectionError,
|
||||
#[error("request had an error: {0:?}")]
|
||||
RequestError(Error),
|
||||
#[error("node replied with invalid JSON")]
|
||||
InvalidJson(serde_json::error::Category),
|
||||
InvalidJson,
|
||||
#[error("node sent an invalid response ({0})")]
|
||||
InvalidResponse(&'static str),
|
||||
#[error("node was missing expected methods")]
|
||||
@@ -66,7 +56,7 @@ impl Rpc {
|
||||
Rpc { client: Client::with_connection_pool().map_err(|_| RpcError::ConnectionError)?, url };
|
||||
|
||||
// Make an RPC request to verify the node is reachable and sane
|
||||
let res: String = rpc.rpc_call("help", json!([])).await?;
|
||||
let res: String = rpc.call("help", "[]").await?;
|
||||
|
||||
// Verify all methods we expect are present
|
||||
// If we had a more expanded RPC, due to differences in RPC versions, it wouldn't make sense to
|
||||
@@ -103,18 +93,16 @@ impl Rpc {
|
||||
}
|
||||
|
||||
/// Perform an arbitrary RPC call.
|
||||
pub async fn rpc_call<Response: DeserializeOwned + Debug>(
|
||||
pub async fn call<Response: 'static + Default + core_json_traits::JsonDeserialize>(
|
||||
&self,
|
||||
method: &str,
|
||||
params: serde_json::Value,
|
||||
params: &str,
|
||||
) -> Result<Response, RpcError> {
|
||||
let mut request = Request::from(
|
||||
hyper::Request::post(&self.url)
|
||||
.header("Content-Type", "application/json")
|
||||
.body(
|
||||
serde_json::to_vec(&json!({ "jsonrpc": "2.0", "method": method, "params": params }))
|
||||
.unwrap()
|
||||
.into(),
|
||||
format!(r#"{{ "method": "{method}", "params": {params} }}"#).as_bytes().to_vec().into(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
@@ -129,11 +117,52 @@ impl Rpc {
|
||||
.await
|
||||
.map_err(|_| RpcError::ConnectionError)?;
|
||||
|
||||
let res: RpcResponse<Response> =
|
||||
serde_json::from_reader(&mut res).map_err(|e| RpcError::InvalidJson(e.classify()))?;
|
||||
#[derive(Default, core_json_derive::JsonDeserialize)]
|
||||
struct InternalError {
|
||||
code: Option<i64>,
|
||||
message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(core_json_derive::JsonDeserialize)]
|
||||
struct RpcResponse<T: core_json_traits::JsonDeserialize> {
|
||||
result: Option<T>,
|
||||
error: Option<InternalError>,
|
||||
}
|
||||
impl<T: core_json_traits::JsonDeserialize> Default for RpcResponse<T> {
|
||||
fn default() -> Self {
|
||||
Self { result: None, error: None }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: `core_json::ReadAdapter`
|
||||
let mut res_vec = vec![];
|
||||
res.read_to_end(&mut res_vec).map_err(|_| RpcError::ConnectionError)?;
|
||||
let res = <RpcResponse<Response> as core_json_traits::JsonStructure>::deserialize_structure::<
|
||||
_,
|
||||
core_json_traits::ConstStack<32>,
|
||||
>(res_vec.as_slice())
|
||||
.map_err(|_| RpcError::InvalidJson)?;
|
||||
|
||||
match res {
|
||||
RpcResponse::Ok { result } => Ok(result),
|
||||
RpcResponse::Err { error } => Err(RpcError::RequestError(error)),
|
||||
RpcResponse { result: Some(result), error: None } => Ok(result),
|
||||
RpcResponse { result: None, error: Some(error) } => {
|
||||
let code =
|
||||
error.code.ok_or_else(|| RpcError::InvalidResponse("error was missing `code`"))?;
|
||||
let code = isize::try_from(code)
|
||||
.map_err(|_| RpcError::InvalidResponse("error code exceeded isize::MAX"))?;
|
||||
let message =
|
||||
error.message.ok_or_else(|| RpcError::InvalidResponse("error was missing `message`"))?;
|
||||
Err(RpcError::RequestError(Error { code, message }))
|
||||
}
|
||||
// `invalidateblock` yields this edge case
|
||||
RpcResponse { result: None, error: None } => {
|
||||
if core::any::TypeId::of::<Response>() == core::any::TypeId::of::<()>() {
|
||||
Ok(Default::default())
|
||||
} else {
|
||||
Err(RpcError::InvalidResponse("response lacked both a result and an error"))
|
||||
}
|
||||
}
|
||||
_ => Err(RpcError::InvalidResponse("response contained both a result and an error")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,16 +175,17 @@ impl Rpc {
|
||||
// tip block of the current chain. The "height" of a block is defined as the amount of blocks
|
||||
// present when the block was created. Accordingly, the genesis block has height 0, and
|
||||
// getblockcount will return 0 when it's only the only block, despite their being one block.
|
||||
self.rpc_call("getblockcount", json!([])).await
|
||||
usize::try_from(self.call::<u64>("getblockcount", "[]").await?)
|
||||
.map_err(|_| RpcError::InvalidResponse("latest block number exceeded usize::MAX"))
|
||||
}
|
||||
|
||||
/// Get the hash of a block by the block's number.
|
||||
pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> {
|
||||
let mut hash = self
|
||||
.rpc_call::<BlockHash>("getblockhash", json!([number]))
|
||||
.await?
|
||||
.as_raw_hash()
|
||||
.to_byte_array();
|
||||
let mut hash =
|
||||
BlockHash::from_str(&self.call::<String>("getblockhash", &format!("[{number}]")).await?)
|
||||
.map_err(|_| RpcError::InvalidResponse("block hash was not valid hex"))?
|
||||
.as_raw_hash()
|
||||
.to_byte_array();
|
||||
// bitcoin stores the inner bytes in reverse order.
|
||||
hash.reverse();
|
||||
Ok(hash)
|
||||
@@ -163,16 +193,25 @@ impl Rpc {
|
||||
|
||||
/// Get a block's number by its hash.
|
||||
pub async fn get_block_number(&self, hash: &[u8; 32]) -> Result<usize, RpcError> {
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Default, core_json_derive::JsonDeserialize)]
|
||||
struct Number {
|
||||
height: usize,
|
||||
height: Option<u64>,
|
||||
}
|
||||
Ok(self.rpc_call::<Number>("getblockheader", json!([hex::encode(hash)])).await?.height)
|
||||
usize::try_from(
|
||||
self
|
||||
.call::<Number>("getblockheader", &format!(r#"["{}"]"#, hex::encode(hash)))
|
||||
.await?
|
||||
.height
|
||||
.ok_or_else(|| {
|
||||
RpcError::InvalidResponse("`getblockheader` did not include `height` field")
|
||||
})?,
|
||||
)
|
||||
.map_err(|_| RpcError::InvalidResponse("block number exceeded usize::MAX"))
|
||||
}
|
||||
|
||||
/// Get a block by its hash.
|
||||
pub async fn get_block(&self, hash: &[u8; 32]) -> Result<Block, RpcError> {
|
||||
let hex = self.rpc_call::<String>("getblock", json!([hex::encode(hash), 0])).await?;
|
||||
let hex = self.call::<String>("getblock", &format!(r#"["{}", 0]"#, hex::encode(hash))).await?;
|
||||
let bytes: Vec<u8> = FromHex::from_hex(&hex)
|
||||
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the block"))?;
|
||||
let block: Block = encode::deserialize(&bytes)
|
||||
@@ -189,8 +228,13 @@ impl Rpc {
|
||||
|
||||
/// Publish a transaction.
|
||||
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<Txid, RpcError> {
|
||||
let txid = match self.rpc_call("sendrawtransaction", json!([encode::serialize_hex(tx)])).await {
|
||||
Ok(txid) => txid,
|
||||
let txid = match self
|
||||
.call::<String>("sendrawtransaction", &format!(r#"["{}"]"#, encode::serialize_hex(tx)))
|
||||
.await
|
||||
{
|
||||
Ok(txid) => {
|
||||
Txid::from_str(&txid).map_err(|_| RpcError::InvalidResponse("TXID was not valid hex"))?
|
||||
}
|
||||
Err(e) => {
|
||||
// A const from Bitcoin's bitcoin/src/rpc/protocol.h
|
||||
const RPC_VERIFY_ALREADY_IN_CHAIN: isize = -27;
|
||||
@@ -211,7 +255,8 @@ impl Rpc {
|
||||
|
||||
/// Get a transaction by its hash.
|
||||
pub async fn get_transaction(&self, hash: &[u8; 32]) -> Result<Transaction, RpcError> {
|
||||
let hex = self.rpc_call::<String>("getrawtransaction", json!([hex::encode(hash)])).await?;
|
||||
let hex =
|
||||
self.call::<String>("getrawtransaction", &format!(r#"["{}"]"#, hex::encode(hash))).await?;
|
||||
let bytes: Vec<u8> = FromHex::from_hex(&hex)
|
||||
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the transaction"))?;
|
||||
let tx: Transaction = encode::deserialize(&bytes)
|
||||
|
||||
@@ -14,9 +14,9 @@ pub(crate) async fn rpc() -> Rpc {
|
||||
// If this node has already been interacted with, clear its chain
|
||||
if rpc.get_latest_block_number().await.unwrap() > 0 {
|
||||
rpc
|
||||
.rpc_call(
|
||||
.call(
|
||||
"invalidateblock",
|
||||
serde_json::json!([hex::encode(rpc.get_block_hash(1).await.unwrap())]),
|
||||
&format!(r#"["{}"]"#, hex::encode(rpc.get_block_hash(1).await.unwrap())),
|
||||
)
|
||||
.await
|
||||
.unwrap()
|
||||
|
||||
@@ -41,21 +41,21 @@ async fn send_and_get_output(rpc: &Rpc, scanner: &Scanner, key: ProjectivePoint)
|
||||
let block_number = rpc.get_latest_block_number().await.unwrap() + 1;
|
||||
|
||||
rpc
|
||||
.rpc_call::<Vec<String>>(
|
||||
.call::<Vec<String>>(
|
||||
"generatetoaddress",
|
||||
serde_json::json!([
|
||||
1,
|
||||
&format!(
|
||||
r#"[1, "{}"]"#,
|
||||
Address::from_script(&p2tr_script_buf(key).unwrap(), Network::Regtest).unwrap()
|
||||
]),
|
||||
),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Mine until maturity
|
||||
rpc
|
||||
.rpc_call::<Vec<String>>(
|
||||
.call::<Vec<String>>(
|
||||
"generatetoaddress",
|
||||
serde_json::json!([100, Address::p2sh(Script::new(), Network::Regtest).unwrap()]),
|
||||
&format!(r#"[100, "{}"]"#, Address::p2sh(Script::new(), Network::Regtest).unwrap()),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{path::PathBuf, fs, process::Command};
|
||||
|
||||
/// Build contracts from the specified path, outputting the artifacts to the specified path.
|
||||
///
|
||||
/// Requires solc 0.8.26.
|
||||
/// Requires solc 0.8.29.
|
||||
pub fn build(
|
||||
include_paths: &[&str],
|
||||
contracts_path: &str,
|
||||
@@ -35,8 +35,8 @@ pub fn build(
|
||||
if let Some(version) = line.strip_prefix("Version: ") {
|
||||
let version =
|
||||
version.split('+').next().ok_or_else(|| "no value present on line".to_string())?;
|
||||
if version != "0.8.26" {
|
||||
Err(format!("version was {version}, 0.8.26 required"))?
|
||||
if version != "0.8.29" {
|
||||
Err(format!("version was {version}, 0.8.29 required"))?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@ rustdoc-args = ["--cfg", "docsrs"]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
subtle = { version = "2", default-features = false, features = ["std"] }
|
||||
sha3 = { version = "0.10", default-features = false, features = ["std"] }
|
||||
group = { version = "0.13", default-features = false, features = ["alloc"] }
|
||||
k256 = { version = "^0.13.1", default-features = false, features = ["std", "arithmetic"] }
|
||||
std-shims = { path = "../../../common/std-shims", version = "0.1", default-features = false }
|
||||
|
||||
subtle = { version = "2", default-features = false }
|
||||
sha3 = { version = "0.10", default-features = false }
|
||||
group = { version = "0.13", default-features = false }
|
||||
k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic"] }
|
||||
|
||||
[build-dependencies]
|
||||
build-solidity-contracts = { path = "../build-contracts", version = "0.1" }
|
||||
@@ -40,3 +42,8 @@ alloy-provider = { version = "1", default-features = false }
|
||||
alloy-node-bindings = { version = "1", default-features = false }
|
||||
|
||||
tokio = { version = "1", default-features = false, features = ["macros"] }
|
||||
|
||||
[features]
|
||||
alloc = ["std-shims/alloc", "group/alloc"]
|
||||
std = ["alloc", "std-shims/std", "subtle/std", "sha3/std", "k256/std"]
|
||||
default = ["std"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
/// @title A library for verifying Schnorr signatures
|
||||
/// @author Luke Parker <lukeparker@serai.exchange>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
import "../Schnorr.sol";
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![deny(missing_docs)]
|
||||
#![allow(non_snake_case)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
mod public_key;
|
||||
pub use public_key::PublicKey;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io;
|
||||
use std_shims::io;
|
||||
|
||||
use sha3::{Digest, Keccak256};
|
||||
|
||||
@@ -77,6 +77,7 @@ impl Signature {
|
||||
}
|
||||
|
||||
/// Write the signature.
|
||||
#[cfg(feature = "alloc")]
|
||||
pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
||||
writer.write_all(&self.to_bytes())
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
|
||||
#
|
||||
# Please verify the signature against the key for binaryFate in the
|
||||
# source code repository (/utils/gpg_keys).
|
||||
#
|
||||
#
|
||||
## CLI
|
||||
6122f0bcaca12d5badd92002338847d16032f6d52d86155c203bcb67d4fe1518 monero-android-armv7-v0.18.4.2.tar.bz2
|
||||
3b248c3201f028205915403b4b2f173df0dd8bf47eeb268fd67a4661251469d3 monero-android-armv8-v0.18.4.2.tar.bz2
|
||||
b4e2b7de80107a1b4613b878d8e2114244b3fb16397821d69baa72d9b0f8c8d5 monero-freebsd-x64-v0.18.4.2.tar.bz2
|
||||
ecb2577499a3b0901d731e11d462d3fadcd70095f3ab0def0c27ee64dc56b061 monero-linux-armv7-v0.18.4.2.tar.bz2
|
||||
a39530054dac348b219f1048a24ca629da26990f72cf9c1f6b6853e3d8c39a79 monero-linux-armv8-v0.18.4.2.tar.bz2
|
||||
18492ace80bf8ef2f44aa9a99b4f20adf00fd59c675a6a496211a720088d5d1a monero-linux-riscv64-v0.18.4.2.tar.bz2
|
||||
41d023f2357244ea43ee0a74796f5705ce75ce7373a5865d4959fefa13ecab06 monero-linux-x64-v0.18.4.2.tar.bz2
|
||||
03e77a4836861a47430664fa703dd149a355b3b214bc400b04ed38eb064a3ef0 monero-linux-x86-v0.18.4.2.tar.bz2
|
||||
9b98da6911b4769abef229c20e21f29d919b11db156965d6f139d2e1ad6625c2 monero-mac-armv8-v0.18.4.2.tar.bz2
|
||||
b1b1b580320118d3b6eaa5575fdbd73cf4db90fcc025b7abf875c5e5b4e335c1 monero-mac-x64-v0.18.4.2.tar.bz2
|
||||
14dd5aa11308f106183dd7834aa200e74ce6f3497103973696b556e893a4fef2 monero-win-x64-v0.18.4.2.zip
|
||||
934d9dbeb06ff5610d2c96ebe34fa480e74f78eaeb3fa3e47d89b7961c9bc5e0 monero-win-x86-v0.18.4.2.zip
|
||||
e9ec2062b3547db58f00102e6905621116ab7f56a331e0bc9b9e892607b87d24 monero-source-v0.18.4.2.tar.bz2
|
||||
#
|
||||
## GUI
|
||||
9d6e87add7e3ac006ee34c13c4f629252595395f54421db768f72dc233e94ea8 monero-gui-install-win-x64-v0.18.4.2.exe
|
||||
e4fcdea3f0ff27c3616a8a75545f42a4e4866ea374fa2eeaa9c87027573358ea monero-gui-linux-x64-v0.18.4.2.tar.bz2
|
||||
3dfee5c5d8e000c72eb3755bf0eb03ca7c5928b69c3a241e147ad22d144e00a7 monero-gui-mac-armv8-v0.18.4.2.dmg
|
||||
16abadcbd608d4f7ba20d17a297f2aa2c9066d33f6f22bf3fcdca679ab603990 monero-gui-mac-x64-v0.18.4.2.dmg
|
||||
4daff8850280173d46464ba9a9de7f712228ad1ef76a1c4954531e4fd2b86d86 monero-gui-win-x64-v0.18.4.2.zip
|
||||
691085e61ece6c56738431f3cfd395536ca0675214e5991e0dbfab85025e82d7 monero-gui-source-v0.18.4.2.tar.bz2
|
||||
#
|
||||
#
|
||||
# ~binaryFate
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmitx+kACgkQ8K9NRioL
|
||||
35J6cQ/7ByvGstg/a5lIYbB+Lz5bNiPozCILD9/offvC7GgOvna9rkHuofuLS+pX
|
||||
qhYEMrjFjmp03XMY+i68M83qkBEZ+yU5iNDbwRuHUNMMWaaGlhnhm3nyUVtDpjjr
|
||||
4xwVsee+dzi0JZhVQG7HJFURiP2Ub5Ua6bSaATDoT/aUYdhmrOnQiH2+VxogiCv3
|
||||
JStDqXq6LpFjzw7UkAfxxu1PW+AQFNBzi3L0qWfzb5WWL7xuK63wXGmEkYBlvult
|
||||
qt3LUhDUzMrfZ5GiiOYDEw44Y2atD4ibOYtBnllCX9CKNb0o2KKU6Qkj+CYqqtnE
|
||||
uGNOt1oT09VPOtE7OUkBLVkALjef7ZXRibE7tN4wSnsrG39DP795/52L6CGJbl4n
|
||||
UDnHzLCUbuvhnoAu5U+rUP5nUEDYS9ANNyj610ogNCo7YjfzLH641WSQ/UnuXKkA
|
||||
RmK8xIiKoOnUeOanX99zqeXqV7gQdQMlfwLUr3pQzCI2YjdvxdRoedSEi5nX5KvO
|
||||
Snf3BcCYMBemGYqVMdo95tc0Gmsw12/O8WwrBbTea+PeAXJuLaBxrLNn+RNZLfF/
|
||||
UJYq2VcEwxG6vXb3cJ5lDKmRDDRI8Fxu6Amdab+6ponhM8Zy3eAynVIO952pLA7N
|
||||
dtl72RsimM+sgHXP4ERYL4c6WARSHE5sAiog43dr56l3PPmM8pE=
|
||||
=SoHG
|
||||
-----END PGP SIGNATURE-----
|
||||
50
orchestration/dev/networks/monero/hashes-v0.18.4.3.txt
Normal file
50
orchestration/dev/networks/monero/hashes-v0.18.4.3.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
# This GPG-signed message exists to confirm the SHA256 sums of Monero binaries.
|
||||
#
|
||||
# Please verify the signature against the key for binaryFate in the
|
||||
# source code repository (/utils/gpg_keys).
|
||||
#
|
||||
#
|
||||
## CLI
|
||||
4e1481835824b9233f204553d4a19645274824f3f6185d8a4b50198470752f54 monero-android-armv7-v0.18.4.3.tar.bz2
|
||||
1aebd24aaaec3d1e87a64163f2e30ab2cd45f3902a7a859413f6870944775c21 monero-android-armv8-v0.18.4.3.tar.bz2
|
||||
ff7b9c5cf2cb3d602c3dff1902ac0bc3394768cefc260b6003a9ad4bcfb7c6a4 monero-freebsd-x64-v0.18.4.3.tar.bz2
|
||||
3ac83049bc565fb5238501f0fa629cdd473bbe94d5fb815088af8e6ff1d761cd monero-linux-armv7-v0.18.4.3.tar.bz2
|
||||
b1cc5f135de3ba8512d56deb4b536b38c41addde922b2a53bf443aeaf2a5a800 monero-linux-armv8-v0.18.4.3.tar.bz2
|
||||
95baaa6e8957b92caeaed7fb19b5c2659373df8dd5f4de2601ed3dae7b17ce2f monero-linux-riscv64-v0.18.4.3.tar.bz2
|
||||
3a7b36ae4da831a4e9913e0a891728f4c43cd320f9b136cdb6686b1d0a33fafa monero-linux-x64-v0.18.4.3.tar.bz2
|
||||
e0b51ca71934c33cb83cfa8535ffffebf431a2fc9efe3acf2baad96fb6ce21ec monero-linux-x86-v0.18.4.3.tar.bz2
|
||||
bab9a6d3c2ca519386cff5ff0b5601642a495ed1a209736acaf354468cba1145 monero-mac-armv8-v0.18.4.3.tar.bz2
|
||||
a8d8273b14f31569f5b7aa3063fbd322e3caec3d63f9f51e287dfc539c7f7d61 monero-mac-x64-v0.18.4.3.tar.bz2
|
||||
bd9f615657c35d2d7dd9a5168ad54f1547dbf9a335dee7f12fab115f6f394e36 monero-win-x64-v0.18.4.3.zip
|
||||
e642ed7bbfa34c30b185387fa553aa9c3ea608db1f3fc0e9332afa9b522c9c1a monero-win-x86-v0.18.4.3.zip
|
||||
6ba5e082c8fa25216aba7aea8198f3e23d4b138df15c512457081e1eb3d03ff6 monero-source-v0.18.4.3.tar.bz2
|
||||
#
|
||||
## GUI
|
||||
7b9255c696a462a00a810d9c8f94e60400a9e7d6438e8d6a8b693e9c13dca9ab monero-gui-install-win-x64-v0.18.4.3.exe
|
||||
0bd84de0a7c18b2a3ea8e8eff2194ae000cf1060045badfd4ab48674bc1b9325 monero-gui-linux-x64-v0.18.4.3.tar.bz2
|
||||
68ea30db32efb4a0671ec723297b6629d932fa188edf76edb38a37adaa3528e6 monero-gui-mac-armv8-v0.18.4.3.dmg
|
||||
27243b01f030fdae68c59cae1daf21f530bbadeaf10579d2908db9a834191cee monero-gui-mac-x64-v0.18.4.3.dmg
|
||||
dc9531cb4319b37b2c2dea4126e44a0fe6e7b6f34d278ccf5dd9ba693e3031e0 monero-gui-win-x64-v0.18.4.3.zip
|
||||
0d44687644db9b1824f324416e98f4a46b3bb0a5ed09af54b2835b6facaa0cdd monero-gui-source-v0.18.4.3.tar.bz2
|
||||
#
|
||||
#
|
||||
# ~binaryFate
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCAAdFiEEgaxZH+nEtlxYBq/D8K9NRioL35IFAmjntxwACgkQ8K9NRioL
|
||||
35J57g//dUOY1KAoLNaV7XLJyGbNk1lT6c2+A8h1wkK6iNQhXsmnc6rcigsHXrG0
|
||||
LQyVUuZJ6ELhNb6BnH5V0zbcB72t8XjkSEqlYhStUfMnaUvj1VdXtL/OnSs3fEvt
|
||||
Zwz6QBTxIKDDYEYyXrvCK96cYaYlIOgK3IVn/zoHdrHRUqTXqRJkFoTHum5l783y
|
||||
vr9BwMFFWYePUrilphjIiLyJDl+eB5al8PaJkqK2whxBUHoA2jF1edJOSq2mZajI
|
||||
+L2fBYClePS8oqwoKGquqCh2RVcmdtXtQTVzRIoNx14qFzP8ymqa+6z1Ygkri7bV
|
||||
qMCJk7KQ8ND7uU9NShpaCIqrZpr5GZ4Al6SRkcpK/7mipQcy2QpKJR3iOpcfiTX1
|
||||
YmYGVmLB3zmHu2kiS0kogZv6Ob7+tVFzOQ8NZX4FVnpB0N0phqMfNFOfHzdQZrsZ
|
||||
qg29HNc9sHlUmsOVmE5w+7Oq+s79yvQB3034XXi/9wQu+f8fKRhqZboe0fe77FLf
|
||||
QXoAYrZZ7LnGz0Z75Q9O4RB7uxM0Ug5imvyEFus4iuBVyBWjgcfyLnbkKJtbXmfn
|
||||
BZBbTProhPJfVa/VffBxW9HZB27W7O14oGWVpUkGWnVMZfVY/78XTUHwxaScQsPO
|
||||
SGawjobQsB3pTMNr/kra1XTjkti70si8Fcs5ueYWGB3yfc6r3hU=
|
||||
=5HRY
|
||||
-----END PGP SIGNATURE-----
|
||||
@@ -1,14 +1,7 @@
|
||||
# rust:1.89.0-slim-bookworm as of August 1st, 2025 (GMT)
|
||||
FROM --platform=linux/amd64 rust@sha256:703cfb0f80db8eb8a3452bf5151162472039c1b37fe4fb2957b495a6f0104ae7 AS deterministic
|
||||
# rust:1.91.1-alpine as of November 11th, 2025 (GMT)
|
||||
FROM --platform=linux/amd64 rust@sha256:700c0959b23445f69c82676b72caa97ca4359decd075dca55b13339df27dc4d3 AS deterministic
|
||||
|
||||
# Move to a Debian package snapshot
|
||||
RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
echo "deb [arch=amd64] http://snapshot.debian.org/archive/debian/20250801T000000Z bookworm main" > /etc/apt/sources.list && \
|
||||
apt update
|
||||
|
||||
# Install dependencies
|
||||
RUN apt update -y && apt upgrade -y && apt install -y clang
|
||||
RUN apk add musl-dev=1.2.5-r10
|
||||
|
||||
# Add the wasm toolchain
|
||||
RUN rustup target add wasm32v1-none
|
||||
@@ -35,6 +28,7 @@ ADD AGPL-3.0 /serai
|
||||
WORKDIR /serai
|
||||
|
||||
# Build the runtime, copying it to the volume if it exists
|
||||
ENV RUSTFLAGS="-Ctarget-feature=-crt-static"
|
||||
CMD cargo build --release -p serai-runtime && \
|
||||
mkdir -p /volume && \
|
||||
cp /serai/target/release/wbuild/serai-runtime/serai_runtime.wasm /volume/serai.wasm
|
||||
|
||||
@@ -19,6 +19,7 @@ pub fn coordinator(
|
||||
let setup = mimalloc(Os::Debian).to_string() +
|
||||
&build_serai_service(
|
||||
"",
|
||||
Os::Debian,
|
||||
network.release(),
|
||||
&format!("{db} {longer_reattempts}"),
|
||||
"serai-coordinator",
|
||||
|
||||
@@ -4,7 +4,13 @@ use crate::{Network, Os, mimalloc, os, build_serai_service, write_dockerfile};
|
||||
|
||||
pub fn ethereum_relayer(orchestration_path: &Path, network: Network) {
|
||||
let setup = mimalloc(Os::Debian).to_string() +
|
||||
&build_serai_service("", network.release(), network.db(), "serai-ethereum-relayer");
|
||||
&build_serai_service(
|
||||
"",
|
||||
Os::Debian,
|
||||
network.release(),
|
||||
network.db(),
|
||||
"serai-ethereum-relayer",
|
||||
);
|
||||
|
||||
let env_vars = [
|
||||
("DB_PATH", "/volume/ethereum-relayer-db".to_string()),
|
||||
|
||||
@@ -143,13 +143,20 @@ WORKDIR /home/{user}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_serai_service(prelude: &str, release: bool, features: &str, package: &str) -> String {
|
||||
fn build_serai_service(
|
||||
prelude: &str,
|
||||
os: Os,
|
||||
release: bool,
|
||||
features: &str,
|
||||
package: &str,
|
||||
) -> String {
|
||||
let profile = if release { "release" } else { "debug" };
|
||||
let profile_flag = if release { "--release" } else { "" };
|
||||
|
||||
format!(
|
||||
r#"
|
||||
FROM rust:1.90-slim-trixie AS builder
|
||||
(match os {
|
||||
Os::Debian => {
|
||||
r#"
|
||||
FROM rust:1.91-slim-trixie AS builder
|
||||
|
||||
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
||||
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
||||
@@ -161,7 +168,25 @@ RUN apt install -y pkg-config libclang-dev clang
|
||||
|
||||
# Dependencies for the Serai node
|
||||
RUN apt install -y make protobuf-compiler
|
||||
"#
|
||||
}
|
||||
Os::Alpine => {
|
||||
r#"
|
||||
FROM rust:1.91-alpine AS builder
|
||||
|
||||
COPY --from=mimalloc-alpine libmimalloc.so /usr/lib
|
||||
ENV LD_PRELOAD=libmimalloc.so
|
||||
|
||||
RUN apk update && apk upgrade
|
||||
|
||||
# Add dev dependencies
|
||||
RUN apk add clang-dev
|
||||
"#
|
||||
}
|
||||
})
|
||||
.to_owned() +
|
||||
&format!(
|
||||
r#"
|
||||
# Add the wasm toolchain
|
||||
RUN rustup target add wasm32v1-none
|
||||
|
||||
@@ -195,7 +220,7 @@ RUN --mount=type=cache,target=/root/.cargo \
|
||||
cargo build {profile_flag} --features "{features}" -p {package} && \
|
||||
mv /serai/target/{profile}/{package} /serai/bin
|
||||
"#
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn write_dockerfile(path: PathBuf, dockerfile: &str) {
|
||||
|
||||
@@ -13,8 +13,8 @@ pub fn message_queue(
|
||||
ethereum_key: <Ristretto as WrappedGroup>::G,
|
||||
monero_key: <Ristretto as WrappedGroup>::G,
|
||||
) {
|
||||
let setup = mimalloc(Os::Debian).to_string() +
|
||||
&build_serai_service("", network.release(), network.db(), "serai-message-queue");
|
||||
let setup = mimalloc(Os::Alpine).to_string() +
|
||||
&build_serai_service("", Os::Alpine, network.release(), network.db(), "serai-message-queue");
|
||||
|
||||
let env_vars = [
|
||||
("COORDINATOR_KEY", hex::encode(coordinator_key.to_bytes())),
|
||||
@@ -41,7 +41,7 @@ CMD {env_vars_str} serai-message-queue
|
||||
"#
|
||||
);
|
||||
|
||||
let run = os(Os::Debian, "", "messagequeue") + &run_message_queue;
|
||||
let run = os(Os::Alpine, "", "messagequeue") + &run_message_queue;
|
||||
let res = setup + &run;
|
||||
|
||||
let mut message_queue_path = orchestration_path.to_path_buf();
|
||||
|
||||
@@ -7,10 +7,10 @@ FROM alpine:latest AS mimalloc-alpine
|
||||
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
|
||||
RUN git clone https://github.com/microsoft/mimalloc && \
|
||||
cd mimalloc && \
|
||||
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
|
||||
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
|
||||
mkdir -p out/secure && \
|
||||
cd out/secure && \
|
||||
cmake -DMI_SECURE=ON ../.. && \
|
||||
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
|
||||
make && \
|
||||
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
||||
"#;
|
||||
@@ -21,10 +21,10 @@ FROM debian:trixie-slim AS mimalloc-debian
|
||||
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
|
||||
RUN git clone https://github.com/microsoft/mimalloc && \
|
||||
cd mimalloc && \
|
||||
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
|
||||
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
|
||||
mkdir -p out/secure && \
|
||||
cd out/secure && \
|
||||
cmake -DMI_SECURE=ON ../.. && \
|
||||
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
|
||||
make && \
|
||||
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
||||
"#;
|
||||
|
||||
@@ -7,7 +7,7 @@ pub fn bitcoin(orchestration_path: &Path, network: Network) {
|
||||
const DOWNLOAD_BITCOIN: &str = r#"
|
||||
FROM alpine:latest AS bitcoin
|
||||
|
||||
ENV BITCOIN_VERSION=29.1
|
||||
ENV BITCOIN_VERSION=30.0
|
||||
|
||||
RUN apk --no-cache add wget git gnupg
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ fn monero_internal(
|
||||
monero_binary: &str,
|
||||
ports: &str,
|
||||
) {
|
||||
const MONERO_VERSION: &str = "0.18.4.2";
|
||||
const MONERO_VERSION: &str = "0.18.4.3";
|
||||
|
||||
let arch = match std::env::consts::ARCH {
|
||||
// We probably would run this without issues yet it's not worth needing to provide support for
|
||||
|
||||
@@ -22,12 +22,13 @@ pub fn processor(
|
||||
if coin == "ethereum" {
|
||||
r#"
|
||||
RUN cargo install svm-rs
|
||||
RUN svm install 0.8.26
|
||||
RUN svm use 0.8.26
|
||||
RUN svm install 0.8.29
|
||||
RUN svm use 0.8.29
|
||||
"#
|
||||
} else {
|
||||
""
|
||||
},
|
||||
Os::Debian,
|
||||
network.release(),
|
||||
&format!("binaries {} {coin}", network.db()),
|
||||
"serai-processor",
|
||||
|
||||
@@ -12,9 +12,10 @@ pub fn serai(
|
||||
serai_key: &Zeroizing<<Ristretto as WrappedGroup>::F>,
|
||||
) {
|
||||
// Always builds in release for performance reasons
|
||||
let setup = mimalloc(Os::Debian).to_string() + &build_serai_service("", true, "", "serai-node");
|
||||
let setup_fast_epoch =
|
||||
mimalloc(Os::Debian).to_string() + &build_serai_service("", true, "fast-epoch", "serai-node");
|
||||
let setup =
|
||||
mimalloc(Os::Debian).to_string() + &build_serai_service("", Os::Debian, true, "", "serai-node");
|
||||
let setup_fast_epoch = mimalloc(Os::Debian).to_string() +
|
||||
&build_serai_service("", Os::Debian, true, "fast-epoch", "serai-node");
|
||||
|
||||
let env_vars = [("KEY", hex::encode(serai_key.to_repr()))];
|
||||
let mut env_vars_str = String::new();
|
||||
|
||||
16
patches/darling/Cargo.toml
Normal file
16
patches/darling/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "darling"
|
||||
version = "0.20.99"
|
||||
description = "Patch to the latest version"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/darling"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
darling = { version = "0.21" }
|
||||
1
patches/darling/src/lib.rs
Normal file
1
patches/darling/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use darling::*;
|
||||
16
patches/ethereum/ark-ff-0.3/Cargo.toml
Normal file
16
patches/ethereum/ark-ff-0.3/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "ark-ff"
|
||||
version = "0.3.99"
|
||||
description = "Patch to an empty crate"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/ark-ff-0.3"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
std = []
|
||||
1
patches/ethereum/ark-ff-0.3/src/lib.rs
Normal file
1
patches/ethereum/ark-ff-0.3/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];
|
||||
16
patches/ethereum/ark-ff-0.4/Cargo.toml
Normal file
16
patches/ethereum/ark-ff-0.4/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "ark-ff"
|
||||
version = "0.4.99"
|
||||
description = "Patch to an empty crate"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/ark-ff-0.4"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
std = []
|
||||
1
patches/ethereum/ark-ff-0.4/src/lib.rs
Normal file
1
patches/ethereum/ark-ff-0.4/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];
|
||||
18
patches/ethereum/c-kzg/Cargo.toml
Normal file
18
patches/ethereum/c-kzg/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "c-kzg"
|
||||
version = "2.99.99"
|
||||
description = "Patch to an empty crate"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/c-kzg"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
std = []
|
||||
serde = []
|
||||
ethereum_kzg_settings = []
|
||||
1
patches/ethereum/c-kzg/src/lib.rs
Normal file
1
patches/ethereum/c-kzg/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];
|
||||
21
patches/ethereum/secp256k1-30/Cargo.toml
Normal file
21
patches/ethereum/secp256k1-30/Cargo.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "secp256k1"
|
||||
version = "0.30.99"
|
||||
description = "Patch to an empty crate"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/secp256k1-30"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
alloc = []
|
||||
std = []
|
||||
rand = []
|
||||
serde = []
|
||||
global-context = []
|
||||
recovery = []
|
||||
1
patches/ethereum/secp256k1-30/src/lib.rs
Normal file
1
patches/ethereum/secp256k1-30/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
const _NEVER_COMPILED: [(); 0 - 1] = [(); 0 - 1];
|
||||
35
patches/librocksdb-sys/Cargo.toml
Normal file
35
patches/librocksdb-sys/Cargo.toml
Normal file
@@ -0,0 +1,35 @@
|
||||
[package]
|
||||
name = "librocksdb-sys"
|
||||
version = "0.17.99"
|
||||
description = "Replacement for `librocksdb-sys` which removes the `jemalloc` feature"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/librocksdb-sys"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
# librocksdb-sys 0.17.3+10.4.2, with the commit provided by crates.io in `cargo_vcs_info.json`
|
||||
librocksdb-sys = { git = "https://github.com/rust-rocksdb/rust-rocksdb", commit = "bb7d2168eab1bc7849f23adbcb825e3aba1bd2f4", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["librocksdb-sys/default"]
|
||||
jemalloc = []
|
||||
static = ["librocksdb-sys/static"]
|
||||
bindgen-runtime = ["librocksdb-sys/bindgen-runtime"]
|
||||
bindgen-static = ["librocksdb-sys/bindgen-static"]
|
||||
mt_static = ["librocksdb-sys/mt_static"]
|
||||
io-uring = ["librocksdb-sys/io-uring"]
|
||||
snappy = ["librocksdb-sys/snappy"]
|
||||
lz4 = ["librocksdb-sys/lz4"]
|
||||
zstd = ["librocksdb-sys/zstd"]
|
||||
zlib = ["librocksdb-sys/zlib"]
|
||||
bzip2 = ["librocksdb-sys/bzip2"]
|
||||
rtti = ["librocksdb-sys/rtti"]
|
||||
lto = ["librocksdb-sys/lto"]
|
||||
1
patches/librocksdb-sys/src/lib.rs
Normal file
1
patches/librocksdb-sys/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use librocksdb_sys::*;
|
||||
30
patches/parity-bip39/Cargo.toml
Normal file
30
patches/parity-bip39/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[package]
|
||||
name = "parity-bip39"
|
||||
version = "2.99.99"
|
||||
description = "Patch back to the upstream library"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/parity-bip39"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
bip39 = { git = "https://github.com/rust-bitcoin/rust-bip39", commit = "f735e2559f30049f6738d1bf68c69a0b7bd7b858", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["bip39/default"]
|
||||
alloc = ["bip39/alloc"]
|
||||
std = ["bip39/std"]
|
||||
|
||||
unicode-normalization = ["bip39/unicode-normalization"]
|
||||
all-languages = ["bip39/all-languages"]
|
||||
|
||||
zeroize = ["bip39/zeroize"]
|
||||
rand_core = ["bip39/rand_core"]
|
||||
rand = ["bip39/rand"]
|
||||
3
patches/parity-bip39/src/lib.rs
Normal file
3
patches/parity-bip39/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
pub use bip39::*;
|
||||
16
patches/thiserror/Cargo.toml
Normal file
16
patches/thiserror/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "thiserror"
|
||||
version = "1.99.99"
|
||||
description = "Patch to the latest version"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/thiserror"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
thiserror = { version = "2", features = ["std"] }
|
||||
1
patches/thiserror/src/lib.rs
Normal file
1
patches/thiserror/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub use thiserror::*;
|
||||
@@ -29,7 +29,7 @@ dkg = { package = "dkg-evrf", path = "../../crypto/dkg/evrf", default-features =
|
||||
frost = { package = "modular-frost", path = "../../crypto/frost", default-features = false }
|
||||
|
||||
secp256k1 = { version = "0.29", default-features = false, features = ["std", "global-context", "rand-std"] }
|
||||
bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["std"] }
|
||||
bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["std", "rpc"] }
|
||||
|
||||
serai-client = { path = "../../substrate/client", default-features = false, features = ["bitcoin"] }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
/*
|
||||
The expected deployment process of Serai's Router is as follows:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: CC0
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
interface IERC20 {
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
@@ -33,9 +33,9 @@ alloy-rpc-types-eth = { version = "1", default-features = false }
|
||||
alloy-transport = { version = "1", default-features = false }
|
||||
alloy-provider = { version = "1", default-features = false }
|
||||
|
||||
revm = { version = "29", default-features = false, features = ["std"] }
|
||||
revm = { version = "33", default-features = false }
|
||||
|
||||
ethereum-schnorr = { package = "ethereum-schnorr-contract", path = "../../../networks/ethereum/schnorr", default-features = false }
|
||||
ethereum-schnorr = { package = "ethereum-schnorr-contract", path = "../../../networks/ethereum/schnorr", default-features = false, features = ["std"] }
|
||||
|
||||
ethereum-primitives = { package = "serai-processor-ethereum-primitives", path = "../primitives", default-features = false }
|
||||
ethereum-deployer = { package = "serai-processor-ethereum-deployer", path = "../deployer", default-features = false }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
/// @title Serai Router (without functions overriden by selector collisions)
|
||||
/// @author Luke Parker <lukeparker@serai.exchange>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
import "IERC20.sol";
|
||||
|
||||
@@ -223,7 +223,7 @@ contract Router is IRouterWithoutCollisions {
|
||||
/*
|
||||
Advance the message past the function selector, enabling decoding the arguments. Ideally, we'd
|
||||
also advance past the signature (to simplify decoding arguments and save some memory). This
|
||||
would transfrom message from:
|
||||
would transform message from:
|
||||
|
||||
message (pointer)
|
||||
v
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
import "Router.sol";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
contract TestERC20 {
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.26;
|
||||
pragma solidity ^0.8.29;
|
||||
|
||||
import "Router.sol";
|
||||
|
||||
|
||||
@@ -31,7 +31,15 @@ struct RawParams {
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub(crate) struct Participations {
|
||||
#[borsh(
|
||||
serialize_with = "messages::borsh_serialize_participant_map",
|
||||
deserialize_with = "messages::borsh_deserialize_participant_map"
|
||||
)]
|
||||
pub(crate) substrate_participations: HashMap<Participant, Vec<u8>>,
|
||||
#[borsh(
|
||||
serialize_with = "messages::borsh_serialize_participant_map",
|
||||
deserialize_with = "messages::borsh_deserialize_participant_map"
|
||||
)]
|
||||
pub(crate) network_participations: HashMap<Participant, Vec<u8>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ 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"] }
|
||||
|
||||
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std", "borsh"] }
|
||||
dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"] }
|
||||
|
||||
serai-primitives = { path = "../../substrate/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../../substrate/in-instructions/primitives", default-features = false, features = ["std", "borsh"] }
|
||||
|
||||
@@ -21,6 +21,44 @@ pub struct SubstrateContext {
|
||||
pub network_latest_finalized_block: BlockHash,
|
||||
}
|
||||
|
||||
pub fn borsh_serialize_participant<W: borsh::io::Write>(
|
||||
value: &Participant,
|
||||
writer: &mut W,
|
||||
) -> borsh::io::Result<()> {
|
||||
u16::from(*value).serialize(writer)
|
||||
}
|
||||
pub fn borsh_deserialize_participant<R: borsh::io::Read>(
|
||||
reader: &mut R,
|
||||
) -> borsh::io::Result<Participant> {
|
||||
u16::deserialize_reader(reader).and_then(|p| {
|
||||
Participant::new(p)
|
||||
.ok_or_else(|| borsh::io::Error::other("invalid `Participant` despite valid `u16`"))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn borsh_serialize_participant_map<W: borsh::io::Write>(
|
||||
value: &HashMap<Participant, Vec<u8>>,
|
||||
writer: &mut W,
|
||||
) -> borsh::io::Result<()> {
|
||||
value
|
||||
.iter()
|
||||
.map(|(key, value)| (u16::from(*key), value))
|
||||
.collect::<HashMap<u16, &Vec<u8>>>()
|
||||
.serialize(writer)
|
||||
}
|
||||
pub fn borsh_deserialize_participant_map<R: borsh::io::Read>(
|
||||
reader: &mut R,
|
||||
) -> borsh::io::Result<HashMap<Participant, Vec<u8>>> {
|
||||
HashMap::<u16, Vec<u8>>::deserialize_reader(reader)?
|
||||
.into_iter()
|
||||
.map(|(key, value)| {
|
||||
Participant::new(key)
|
||||
.ok_or_else(|| borsh::io::Error::other("invalid `Participant` despite valid `u16` in map"))
|
||||
.map(|key| (key, value))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub mod key_gen {
|
||||
use super::*;
|
||||
|
||||
@@ -33,7 +71,15 @@ pub mod key_gen {
|
||||
/// Received participations for the specified key generation protocol.
|
||||
///
|
||||
/// This is sent by the Coordinator's Tributary scanner.
|
||||
Participation { session: Session, participant: Participant, participation: Vec<u8> },
|
||||
Participation {
|
||||
session: Session,
|
||||
#[borsh(
|
||||
serialize_with = "borsh_serialize_participant",
|
||||
deserialize_with = "borsh_deserialize_participant"
|
||||
)]
|
||||
participant: Participant,
|
||||
participation: Vec<u8>,
|
||||
},
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for CoordinatorMessage {
|
||||
@@ -58,11 +104,25 @@ pub mod key_gen {
|
||||
#[derive(Clone, BorshSerialize, BorshDeserialize)]
|
||||
pub enum ProcessorMessage {
|
||||
// Participated in the specified key generation protocol.
|
||||
Participation { session: Session, participation: Vec<u8> },
|
||||
Participation {
|
||||
session: Session,
|
||||
participation: Vec<u8>,
|
||||
},
|
||||
// Resulting keys from the specified key generation protocol.
|
||||
GeneratedKeyPair { session: Session, substrate_key: [u8; 32], network_key: Vec<u8> },
|
||||
GeneratedKeyPair {
|
||||
session: Session,
|
||||
substrate_key: [u8; 32],
|
||||
network_key: Vec<u8>,
|
||||
},
|
||||
// Blame this participant.
|
||||
Blame { session: Session, participant: Participant },
|
||||
Blame {
|
||||
session: Session,
|
||||
#[borsh(
|
||||
serialize_with = "borsh_serialize_participant",
|
||||
deserialize_with = "borsh_deserialize_participant"
|
||||
)]
|
||||
participant: Participant,
|
||||
},
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for ProcessorMessage {
|
||||
@@ -127,11 +187,25 @@ pub mod sign {
|
||||
/// Received preprocesses for the specified signing protocol.
|
||||
///
|
||||
/// This is sent by the Coordinator's Tributary scanner.
|
||||
Preprocesses { id: SignId, preprocesses: HashMap<Participant, Vec<u8>> },
|
||||
Preprocesses {
|
||||
id: SignId,
|
||||
#[borsh(
|
||||
serialize_with = "borsh_serialize_participant_map",
|
||||
deserialize_with = "borsh_deserialize_participant_map"
|
||||
)]
|
||||
preprocesses: HashMap<Participant, Vec<u8>>,
|
||||
},
|
||||
// Received shares for the specified signing protocol.
|
||||
///
|
||||
/// This is sent by the Coordinator's Tributary scanner.
|
||||
Shares { id: SignId, shares: HashMap<Participant, Vec<u8>> },
|
||||
Shares {
|
||||
id: SignId,
|
||||
#[borsh(
|
||||
serialize_with = "borsh_serialize_participant_map",
|
||||
deserialize_with = "borsh_deserialize_participant_map"
|
||||
)]
|
||||
shares: HashMap<Participant, Vec<u8>>,
|
||||
},
|
||||
// Re-attempt a signing protocol.
|
||||
///
|
||||
/// This is sent by the Coordinator's Tributary re-attempt scheduling logic.
|
||||
@@ -152,11 +226,24 @@ pub mod sign {
|
||||
#[derive(Clone, Debug, BorshSerialize, BorshDeserialize)]
|
||||
pub enum ProcessorMessage {
|
||||
// Participant sent an invalid message during the sign protocol.
|
||||
InvalidParticipant { session: Session, participant: Participant },
|
||||
InvalidParticipant {
|
||||
session: Session,
|
||||
#[borsh(
|
||||
serialize_with = "borsh_serialize_participant",
|
||||
deserialize_with = "borsh_deserialize_participant"
|
||||
)]
|
||||
participant: Participant,
|
||||
},
|
||||
// Created preprocesses for the specified signing protocol.
|
||||
Preprocesses { id: SignId, preprocesses: Vec<Vec<u8>> },
|
||||
Preprocesses {
|
||||
id: SignId,
|
||||
preprocesses: Vec<Vec<u8>>,
|
||||
},
|
||||
// Signed shares for the specified signing protocol.
|
||||
Shares { id: SignId, shares: Vec<Vec<u8>> },
|
||||
Shares {
|
||||
id: SignId,
|
||||
shares: Vec<Vec<u8>>,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +388,7 @@ impl CoordinatorMessage {
|
||||
}
|
||||
// Unique since one participation per participant per session
|
||||
key_gen::CoordinatorMessage::Participation { session, participant, .. } => {
|
||||
(1, borsh::to_vec(&(session, participant)).unwrap())
|
||||
(1, borsh::to_vec(&(session, u16::from(*participant))).unwrap())
|
||||
}
|
||||
};
|
||||
|
||||
@@ -372,7 +459,7 @@ impl ProcessorMessage {
|
||||
}
|
||||
// Unique since we only blame a participant once (as this is fatal)
|
||||
key_gen::ProcessorMessage::Blame { session, participant } => {
|
||||
(2, borsh::to_vec(&(session, participant)).unwrap())
|
||||
(2, borsh::to_vec(&(session, u16::from(*participant))).unwrap())
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[toolchain]
|
||||
channel = "1.90"
|
||||
channel = "1.91.1"
|
||||
targets = ["wasm32v1-none"]
|
||||
profile = "minimal"
|
||||
components = ["rust-src", "rustfmt", "clippy"]
|
||||
components = ["rustfmt", "clippy"]
|
||||
|
||||
@@ -36,8 +36,8 @@ rustup target add wasm32v1-none --toolchain nightly
|
||||
|
||||
```
|
||||
cargo install svm-rs
|
||||
svm install 0.8.26
|
||||
svm use 0.8.26
|
||||
svm install 0.8.29
|
||||
svm use 0.8.29
|
||||
```
|
||||
|
||||
### Install foundry (for tests)
|
||||
|
||||
@@ -46,6 +46,8 @@ frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false,
|
||||
|
||||
bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["hazmat"], optional = true }
|
||||
|
||||
ethereum-schnorr-contract = { path = "../../networks/ethereum/schnorr", default-features = false }
|
||||
|
||||
[features]
|
||||
alloc = [
|
||||
"std-shims/alloc",
|
||||
@@ -75,4 +77,6 @@ alloc = [
|
||||
"frost-schnorrkel",
|
||||
|
||||
"bitcoin-serai",
|
||||
|
||||
"ethereum-schnorr-contract/alloc",
|
||||
]
|
||||
|
||||
@@ -16,6 +16,8 @@ pub use embedwards25519;
|
||||
|
||||
pub use schnorr_signatures;
|
||||
|
||||
pub use ethereum_schnorr_contract;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod alloc {
|
||||
pub use multiexp;
|
||||
|
||||
@@ -7,7 +7,7 @@ pub fn reproducibly_builds() {
|
||||
use dockertest::{PullPolicy, Image, TestBodySpecification, DockerTest};
|
||||
|
||||
const RUNS: usize = 3;
|
||||
const TIMEOUT: u16 = 180 * 60; // 3 hours
|
||||
const TIMEOUT: u16 = 3 * 60 * 60; // 3 hours
|
||||
|
||||
serai_docker_tests::build("runtime".to_string());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user