Remove ethereum-serai/serai-processor-ethereum-contracts

contracts was smashed out of ethereum-serai. Both have now been smashed into
individual crates.

Creates a TODO directory with left-over test code yet to be moved.
This commit is contained in:
Luke Parker 2024-09-18 00:57:10 -04:00
parent 433beac93a
commit bdc3bda04a
26 changed files with 35 additions and 6193 deletions

View file

@ -52,12 +52,10 @@ jobs:
-p serai-processor-signers \ -p serai-processor-signers \
-p serai-processor-bin \ -p serai-processor-bin \
-p serai-bitcoin-processor \ -p serai-bitcoin-processor \
-p serai-processor-ethereum-contracts \
-p serai-processor-ethereum-primitives \ -p serai-processor-ethereum-primitives \
-p serai-processor-ethereum-deployer \ -p serai-processor-ethereum-deployer \
-p serai-processor-ethereum-router \ -p serai-processor-ethereum-router \
-p serai-processor-ethereum-erc20 \ -p serai-processor-ethereum-erc20 \
-p ethereum-serai \
-p serai-ethereum-processor \ -p serai-ethereum-processor \
-p serai-monero-processor \ -p serai-monero-processor \
-p tendermint-machine \ -p tendermint-machine \

93
Cargo.lock generated
View file

@ -184,17 +184,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "alloy-json-abi"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "299d2a937b6c60968df3dad2a988b0f0e03277b344639a4f7a31bd68e6285e59"
dependencies = [
"alloy-primitives",
"alloy-sol-type-parser",
"serde",
]
[[package]] [[package]]
name = "alloy-json-rpc" name = "alloy-json-rpc"
version = "0.3.1" version = "0.3.1"
@ -426,7 +415,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71c4d842beb7a6686d04125603bc57614d5ed78bf95e4753274db3db4ba95214" checksum = "71c4d842beb7a6686d04125603bc57614d5ed78bf95e4753274db3db4ba95214"
dependencies = [ dependencies = [
"alloy-json-abi",
"alloy-sol-macro-input", "alloy-sol-macro-input",
"const-hex", "const-hex",
"heck 0.5.0", "heck 0.5.0",
@ -445,33 +433,21 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1306e8d3c9e6e6ecf7a39ffaf7291e73a5f655a2defd366ee92c2efebcdf7fee" checksum = "1306e8d3c9e6e6ecf7a39ffaf7291e73a5f655a2defd366ee92c2efebcdf7fee"
dependencies = [ dependencies = [
"alloy-json-abi",
"const-hex", "const-hex",
"dunce", "dunce",
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_json",
"syn 2.0.77", "syn 2.0.77",
"syn-solidity", "syn-solidity",
] ]
[[package]]
name = "alloy-sol-type-parser"
version = "0.8.0"
source = "git+https://github.com/alloy-rs/core?rev=446b9d2fbce12b88456152170709a3eaac929af0#446b9d2fbce12b88456152170709a3eaac929af0"
dependencies = [
"serde",
"winnow 0.6.18",
]
[[package]] [[package]]
name = "alloy-sol-types" name = "alloy-sol-types"
version = "0.8.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "577e262966e92112edbd15b1b2c0947cc434d6e8311df96d3329793fe8047da9" checksum = "577e262966e92112edbd15b1b2c0947cc434d6e8311df96d3329793fe8047da9"
dependencies = [ dependencies = [
"alloy-json-abi",
"alloy-primitives", "alloy-primitives",
"alloy-sol-macro", "alloy-sol-macro",
"const-hex", "const-hex",
@ -2503,30 +2479,6 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "ethereum-serai"
version = "0.1.0"
dependencies = [
"alloy-consensus",
"alloy-core",
"alloy-network",
"alloy-node-bindings",
"alloy-provider",
"alloy-rpc-client",
"alloy-rpc-types-eth",
"alloy-simple-request-transport",
"alloy-sol-types",
"ethereum-schnorr-contract",
"flexible-transcript",
"group",
"k256",
"modular-frost",
"rand_core",
"serai-processor-ethereum-contracts",
"thiserror",
"tokio",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.3" version = "2.5.3"
@ -6127,16 +6079,6 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "prettyplease"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
dependencies = [
"proc-macro2",
"syn 2.0.77",
]
[[package]] [[package]]
name = "primeorder" name = "primeorder"
version = "0.13.6" version = "0.13.6"
@ -6302,7 +6244,7 @@ dependencies = [
"log", "log",
"multimap", "multimap",
"petgraph", "petgraph",
"prettyplease 0.1.25", "prettyplease",
"prost", "prost",
"prost-types", "prost-types",
"regex", "regex",
@ -8385,11 +8327,18 @@ version = "0.1.0"
name = "serai-ethereum-processor" name = "serai-ethereum-processor"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"alloy-consensus",
"alloy-core",
"alloy-provider",
"alloy-rlp",
"alloy-rpc-client",
"alloy-rpc-types-eth",
"alloy-simple-request-transport",
"borsh", "borsh",
"ciphersuite", "ciphersuite",
"const-hex", "const-hex",
"dkg", "dkg",
"ethereum-serai", "ethereum-schnorr-contract",
"hex", "hex",
"k256", "k256",
"log", "log",
@ -8400,6 +8349,9 @@ dependencies = [
"serai-db", "serai-db",
"serai-env", "serai-env",
"serai-processor-bin", "serai-processor-bin",
"serai-processor-ethereum-erc20",
"serai-processor-ethereum-primitives",
"serai-processor-ethereum-router",
"serai-processor-key-gen", "serai-processor-key-gen",
"serai-processor-primitives", "serai-processor-primitives",
"serai-processor-scanner", "serai-processor-scanner",
@ -8707,20 +8659,6 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "serai-processor-ethereum-contracts"
version = "0.1.0"
dependencies = [
"alloy-sol-macro-expander",
"alloy-sol-macro-input",
"alloy-sol-types",
"build-solidity-contracts",
"prettyplease 0.2.22",
"serde_json",
"syn 2.0.77",
"syn-solidity",
]
[[package]] [[package]]
name = "serai-processor-ethereum-deployer" name = "serai-processor-ethereum-deployer"
version = "0.1.0" version = "0.1.0"
@ -8770,7 +8708,6 @@ dependencies = [
"alloy-provider", "alloy-provider",
"alloy-rpc-types-eth", "alloy-rpc-types-eth",
"alloy-simple-request-transport", "alloy-simple-request-transport",
"alloy-sol-macro",
"alloy-sol-macro-expander", "alloy-sol-macro-expander",
"alloy-sol-macro-input", "alloy-sol-macro-input",
"alloy-sol-types", "alloy-sol-types",
@ -8924,7 +8861,6 @@ dependencies = [
"curve25519-dalek", "curve25519-dalek",
"dkg", "dkg",
"dockertest", "dockertest",
"ethereum-serai",
"hex", "hex",
"k256", "k256",
"monero-simple-request-rpc", "monero-simple-request-rpc",
@ -11954,3 +11890,8 @@ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",
] ]
[[patch.unused]]
name = "alloy-sol-type-parser"
version = "0.8.0"
source = "git+https://github.com/alloy-rs/core?rev=446b9d2fbce12b88456152170709a3eaac929af0#446b9d2fbce12b88456152170709a3eaac929af0"

View file

@ -87,12 +87,10 @@ members = [
"processor/bin", "processor/bin",
"processor/bitcoin", "processor/bitcoin",
"processor/ethereum/contracts",
"processor/ethereum/primitives", "processor/ethereum/primitives",
"processor/ethereum/deployer", "processor/ethereum/deployer",
"processor/ethereum/router", "processor/ethereum/router",
"processor/ethereum/erc20", "processor/ethereum/erc20",
"processor/ethereum/ethereum-serai",
"processor/ethereum", "processor/ethereum",
"processor/monero", "processor/monero",

View file

@ -59,12 +59,10 @@ exceptions = [
{ allow = ["AGPL-3.0"], name = "serai-processor-signers" }, { allow = ["AGPL-3.0"], name = "serai-processor-signers" },
{ allow = ["AGPL-3.0"], name = "serai-bitcoin-processor" }, { allow = ["AGPL-3.0"], name = "serai-bitcoin-processor" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-contracts" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-primitives" }, { allow = ["AGPL-3.0"], name = "serai-processor-ethereum-primitives" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-deployer" }, { allow = ["AGPL-3.0"], name = "serai-processor-ethereum-deployer" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-router" }, { allow = ["AGPL-3.0"], name = "serai-processor-ethereum-router" },
{ allow = ["AGPL-3.0"], name = "serai-processor-ethereum-erc20" }, { allow = ["AGPL-3.0"], name = "serai-processor-ethereum-erc20" },
{ allow = ["AGPL-3.0"], name = "ethereum-serai" },
{ allow = ["AGPL-3.0"], name = "serai-ethereum-processor" }, { allow = ["AGPL-3.0"], name = "serai-ethereum-processor" },
{ allow = ["AGPL-3.0"], name = "serai-monero-processor" }, { allow = ["AGPL-3.0"], name = "serai-monero-processor" },

View file

@ -1,32 +0,0 @@
[package]
name = "serai-processor-ethereum-contracts"
version = "0.1.0"
description = "Ethereum contracts for the Serai processor"
license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/processor/ethereum/contracts"
authors = ["Luke Parker <lukeparker5132@gmail.com>", "Elizabeth Binks <elizabethjbinks@gmail.com>"]
edition = "2021"
publish = false
rust-version = "1.79"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
alloy-sol-types = { version = "0.8", default-features = false, features = ["json"] }
[build-dependencies]
build-solidity-contracts = { path = "../../../networks/ethereum/build-contracts" }
syn = { version = "2", default-features = false, features = ["proc-macro"] }
serde_json = { version = "1", default-features = false, features = ["std"] }
syn-solidity = { version = "0.8", default-features = false }
alloy-sol-macro-input = { version = "0.8", default-features = false }
alloy-sol-macro-expander = { version = "0.8", default-features = false }
prettyplease = { version = "0.2", default-features = false }

View file

@ -1,15 +0,0 @@
AGPL-3.0-only license
Copyright (c) 2022-2024 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/>.

View file

@ -1,7 +0,0 @@
# Serai Processor Ethereum Contracts
The Ethereum contracts used for (and for testing) the Serai processor. This is
its own crate for organizational and build-time reasons. It is not intended to
be publicly used.
This crate will fail to build if `solc` is not installed and available.

View file

@ -1,69 +0,0 @@
use std::{env, fs};
use alloy_sol_macro_input::{SolInputKind, SolInput};
fn write(sol: syn_solidity::File, file: &str) {
let sol = alloy_sol_macro_expander::expand::expand(sol).unwrap();
fs::write(
file,
// TODO: Replace `prettyplease::unparse` with `to_string`
prettyplease::unparse(&syn::File {
attrs: vec![],
items: vec![syn::parse2(sol).unwrap()],
shebang: None,
})
.as_bytes(),
)
.unwrap();
}
fn sol(sol: &str, file: &str) {
let alloy_sol_macro_input::SolInputKind::Sol(sol) =
syn::parse_str(&std::fs::read_to_string(sol).unwrap()).unwrap()
else {
panic!("parsed .sol file wasn't SolInputKind::Sol");
};
write(sol, file);
}
fn abi(ident: &str, abi: &str, file: &str) {
let SolInputKind::Sol(sol) = (SolInput {
attrs: vec![],
path: None,
kind: SolInputKind::Json(
syn::parse_str(ident).unwrap(),
serde_json::from_str(&fs::read_to_string(abi).unwrap()).unwrap(),
),
})
.normalize_json()
.unwrap()
.kind
else {
panic!("normalized JSON wasn't SolInputKind::Sol");
};
write(sol, file);
}
fn main() {
let artifacts_path =
env::var("OUT_DIR").unwrap().to_string() + "/serai-processor-ethereum-contracts";
build_solidity_contracts::build(
&["../../../networks/ethereum/schnorr/contracts"],
"contracts",
&artifacts_path,
)
.unwrap();
// TODO: Use OUT_DIR for the generated code
if !fs::exists("src/abigen").unwrap() {
fs::create_dir("src/abigen").unwrap();
}
// These can be handled with the sol! macro
sol("contracts/IERC20.sol", "src/abigen/erc20.rs");
sol("contracts/Deployer.sol", "src/abigen/deployer.rs");
// This cannot be handled with the sol! macro. The Solidity requires an import, the ABI is built
// to OUT_DIR and the macro doesn't support non-static paths:
// https://github.com/alloy-rs/core/issues/738
abi("Router", &(artifacts_path.clone() + "/Router.abi"), "src/abigen/router.rs");
}

View file

@ -1,584 +0,0 @@
///Module containing a contract's types and functions.
/**
```solidity
contract Deployer {
event Deployment(bytes32 indexed init_code_hash, address created);
error DeploymentFailed();
function deploy(bytes memory init_code) external { <stmts> }
}
```*/
#[allow(non_camel_case_types, non_snake_case, clippy::style)]
pub mod Deployer {
use super::*;
use ::alloy_sol_types as alloy_sol_types;
/**Event with signature `Deployment(bytes32,address)` and selector `0x60b877a3bae7bf0f0bd5e1c40ebf44ea158201397f6b72d7c05360157b1ec0fc`.
```solidity
event Deployment(bytes32 indexed init_code_hash, address created);
```*/
#[allow(non_camel_case_types, non_snake_case, clippy::style)]
#[derive(Clone)]
pub struct Deployment {
#[allow(missing_docs)]
pub init_code_hash: ::alloy_sol_types::private::FixedBytes<32>,
#[allow(missing_docs)]
pub created: ::alloy_sol_types::private::Address,
}
#[allow(non_camel_case_types, non_snake_case, clippy::style)]
const _: () = {
use ::alloy_sol_types as alloy_sol_types;
#[automatically_derived]
impl alloy_sol_types::SolEvent for Deployment {
type DataTuple<'a> = (::alloy_sol_types::sol_data::Address,);
type DataToken<'a> = <Self::DataTuple<
'a,
> as alloy_sol_types::SolType>::Token<'a>;
type TopicList = (
alloy_sol_types::sol_data::FixedBytes<32>,
::alloy_sol_types::sol_data::FixedBytes<32>,
);
const SIGNATURE: &'static str = "Deployment(bytes32,address)";
const SIGNATURE_HASH: alloy_sol_types::private::B256 = alloy_sol_types::private::B256::new([
96u8,
184u8,
119u8,
163u8,
186u8,
231u8,
191u8,
15u8,
11u8,
213u8,
225u8,
196u8,
14u8,
191u8,
68u8,
234u8,
21u8,
130u8,
1u8,
57u8,
127u8,
107u8,
114u8,
215u8,
192u8,
83u8,
96u8,
21u8,
123u8,
30u8,
192u8,
252u8,
]);
const ANONYMOUS: bool = false;
#[allow(unused_variables)]
#[inline]
fn new(
topics: <Self::TopicList as alloy_sol_types::SolType>::RustType,
data: <Self::DataTuple<'_> as alloy_sol_types::SolType>::RustType,
) -> Self {
Self {
init_code_hash: topics.1,
created: data.0,
}
}
#[inline]
fn tokenize_body(&self) -> Self::DataToken<'_> {
(
<::alloy_sol_types::sol_data::Address as alloy_sol_types::SolType>::tokenize(
&self.created,
),
)
}
#[inline]
fn topics(&self) -> <Self::TopicList as alloy_sol_types::SolType>::RustType {
(Self::SIGNATURE_HASH.into(), self.init_code_hash.clone())
}
#[inline]
fn encode_topics_raw(
&self,
out: &mut [alloy_sol_types::abi::token::WordToken],
) -> alloy_sol_types::Result<()> {
if out.len() < <Self::TopicList as alloy_sol_types::TopicList>::COUNT {
return Err(alloy_sol_types::Error::Overrun);
}
out[0usize] = alloy_sol_types::abi::token::WordToken(
Self::SIGNATURE_HASH,
);
out[1usize] = <::alloy_sol_types::sol_data::FixedBytes<
32,
> as alloy_sol_types::EventTopic>::encode_topic(&self.init_code_hash);
Ok(())
}
}
#[automatically_derived]
impl alloy_sol_types::private::IntoLogData for Deployment {
fn to_log_data(&self) -> alloy_sol_types::private::LogData {
From::from(self)
}
fn into_log_data(self) -> alloy_sol_types::private::LogData {
From::from(&self)
}
}
#[automatically_derived]
impl From<&Deployment> for alloy_sol_types::private::LogData {
#[inline]
fn from(this: &Deployment) -> alloy_sol_types::private::LogData {
alloy_sol_types::SolEvent::encode_log_data(this)
}
}
};
/**Custom error with signature `DeploymentFailed()` and selector `0x30116425`.
```solidity
error DeploymentFailed();
```*/
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone)]
pub struct DeploymentFailed {}
#[allow(non_camel_case_types, non_snake_case, clippy::style)]
const _: () = {
use ::alloy_sol_types as alloy_sol_types;
#[doc(hidden)]
type UnderlyingSolTuple<'a> = ();
#[doc(hidden)]
type UnderlyingRustTuple<'a> = ();
#[cfg(test)]
#[allow(dead_code, unreachable_patterns)]
fn _type_assertion(
_t: alloy_sol_types::private::AssertTypeEq<UnderlyingRustTuple>,
) {
match _t {
alloy_sol_types::private::AssertTypeEq::<
<UnderlyingSolTuple as alloy_sol_types::SolType>::RustType,
>(_) => {}
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<DeploymentFailed> for UnderlyingRustTuple<'_> {
fn from(value: DeploymentFailed) -> Self {
()
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<UnderlyingRustTuple<'_>> for DeploymentFailed {
fn from(tuple: UnderlyingRustTuple<'_>) -> Self {
Self {}
}
}
#[automatically_derived]
impl alloy_sol_types::SolError for DeploymentFailed {
type Parameters<'a> = UnderlyingSolTuple<'a>;
type Token<'a> = <Self::Parameters<
'a,
> as alloy_sol_types::SolType>::Token<'a>;
const SIGNATURE: &'static str = "DeploymentFailed()";
const SELECTOR: [u8; 4] = [48u8, 17u8, 100u8, 37u8];
#[inline]
fn new<'a>(
tuple: <Self::Parameters<'a> as alloy_sol_types::SolType>::RustType,
) -> Self {
tuple.into()
}
#[inline]
fn tokenize(&self) -> Self::Token<'_> {
()
}
}
};
/**Function with signature `deploy(bytes)` and selector `0x00774360`.
```solidity
function deploy(bytes memory init_code) external { <stmts> }
```*/
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone)]
pub struct deployCall {
pub init_code: ::alloy_sol_types::private::Bytes,
}
///Container type for the return parameters of the [`deploy(bytes)`](deployCall) function.
#[allow(non_camel_case_types, non_snake_case)]
#[derive(Clone)]
pub struct deployReturn {}
#[allow(non_camel_case_types, non_snake_case, clippy::style)]
const _: () = {
use ::alloy_sol_types as alloy_sol_types;
{
#[doc(hidden)]
type UnderlyingSolTuple<'a> = (::alloy_sol_types::sol_data::Bytes,);
#[doc(hidden)]
type UnderlyingRustTuple<'a> = (::alloy_sol_types::private::Bytes,);
#[cfg(test)]
#[allow(dead_code, unreachable_patterns)]
fn _type_assertion(
_t: alloy_sol_types::private::AssertTypeEq<UnderlyingRustTuple>,
) {
match _t {
alloy_sol_types::private::AssertTypeEq::<
<UnderlyingSolTuple as alloy_sol_types::SolType>::RustType,
>(_) => {}
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<deployCall> for UnderlyingRustTuple<'_> {
fn from(value: deployCall) -> Self {
(value.init_code,)
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<UnderlyingRustTuple<'_>> for deployCall {
fn from(tuple: UnderlyingRustTuple<'_>) -> Self {
Self { init_code: tuple.0 }
}
}
}
{
#[doc(hidden)]
type UnderlyingSolTuple<'a> = ();
#[doc(hidden)]
type UnderlyingRustTuple<'a> = ();
#[cfg(test)]
#[allow(dead_code, unreachable_patterns)]
fn _type_assertion(
_t: alloy_sol_types::private::AssertTypeEq<UnderlyingRustTuple>,
) {
match _t {
alloy_sol_types::private::AssertTypeEq::<
<UnderlyingSolTuple as alloy_sol_types::SolType>::RustType,
>(_) => {}
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<deployReturn> for UnderlyingRustTuple<'_> {
fn from(value: deployReturn) -> Self {
()
}
}
#[automatically_derived]
#[doc(hidden)]
impl ::core::convert::From<UnderlyingRustTuple<'_>> for deployReturn {
fn from(tuple: UnderlyingRustTuple<'_>) -> Self {
Self {}
}
}
}
#[automatically_derived]
impl alloy_sol_types::SolCall for deployCall {
type Parameters<'a> = (::alloy_sol_types::sol_data::Bytes,);
type Token<'a> = <Self::Parameters<
'a,
> as alloy_sol_types::SolType>::Token<'a>;
type Return = deployReturn;
type ReturnTuple<'a> = ();
type ReturnToken<'a> = <Self::ReturnTuple<
'a,
> as alloy_sol_types::SolType>::Token<'a>;
const SIGNATURE: &'static str = "deploy(bytes)";
const SELECTOR: [u8; 4] = [0u8, 119u8, 67u8, 96u8];
#[inline]
fn new<'a>(
tuple: <Self::Parameters<'a> as alloy_sol_types::SolType>::RustType,
) -> Self {
tuple.into()
}
#[inline]
fn tokenize(&self) -> Self::Token<'_> {
(
<::alloy_sol_types::sol_data::Bytes as alloy_sol_types::SolType>::tokenize(
&self.init_code,
),
)
}
#[inline]
fn abi_decode_returns(
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<Self::Return> {
<Self::ReturnTuple<
'_,
> as alloy_sol_types::SolType>::abi_decode_sequence(data, validate)
.map(Into::into)
}
}
};
///Container for all the [`Deployer`](self) function calls.
pub enum DeployerCalls {
deploy(deployCall),
}
#[automatically_derived]
impl DeployerCalls {
/// All the selectors of this enum.
///
/// Note that the selectors might not be in the same order as the variants.
/// No guarantees are made about the order of the selectors.
///
/// Prefer using `SolInterface` methods instead.
pub const SELECTORS: &'static [[u8; 4usize]] = &[[0u8, 119u8, 67u8, 96u8]];
}
#[automatically_derived]
impl alloy_sol_types::SolInterface for DeployerCalls {
const NAME: &'static str = "DeployerCalls";
const MIN_DATA_LENGTH: usize = 64usize;
const COUNT: usize = 1usize;
#[inline]
fn selector(&self) -> [u8; 4] {
match self {
Self::deploy(_) => <deployCall as alloy_sol_types::SolCall>::SELECTOR,
}
}
#[inline]
fn selector_at(i: usize) -> ::core::option::Option<[u8; 4]> {
Self::SELECTORS.get(i).copied()
}
#[inline]
fn valid_selector(selector: [u8; 4]) -> bool {
Self::SELECTORS.binary_search(&selector).is_ok()
}
#[inline]
#[allow(unsafe_code, non_snake_case)]
fn abi_decode_raw(
selector: [u8; 4],
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<Self> {
static DECODE_SHIMS: &[fn(
&[u8],
bool,
) -> alloy_sol_types::Result<DeployerCalls>] = &[
{
fn deploy(
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<DeployerCalls> {
<deployCall as alloy_sol_types::SolCall>::abi_decode_raw(
data,
validate,
)
.map(DeployerCalls::deploy)
}
deploy
},
];
let Ok(idx) = Self::SELECTORS.binary_search(&selector) else {
return Err(
alloy_sol_types::Error::unknown_selector(
<Self as alloy_sol_types::SolInterface>::NAME,
selector,
),
);
};
(unsafe { DECODE_SHIMS.get_unchecked(idx) })(data, validate)
}
#[inline]
fn abi_encoded_size(&self) -> usize {
match self {
Self::deploy(inner) => {
<deployCall as alloy_sol_types::SolCall>::abi_encoded_size(inner)
}
}
}
#[inline]
fn abi_encode_raw(&self, out: &mut alloy_sol_types::private::Vec<u8>) {
match self {
Self::deploy(inner) => {
<deployCall as alloy_sol_types::SolCall>::abi_encode_raw(inner, out)
}
}
}
}
///Container for all the [`Deployer`](self) custom errors.
pub enum DeployerErrors {
DeploymentFailed(DeploymentFailed),
}
#[automatically_derived]
impl DeployerErrors {
/// All the selectors of this enum.
///
/// Note that the selectors might not be in the same order as the variants.
/// No guarantees are made about the order of the selectors.
///
/// Prefer using `SolInterface` methods instead.
pub const SELECTORS: &'static [[u8; 4usize]] = &[[48u8, 17u8, 100u8, 37u8]];
}
#[automatically_derived]
impl alloy_sol_types::SolInterface for DeployerErrors {
const NAME: &'static str = "DeployerErrors";
const MIN_DATA_LENGTH: usize = 0usize;
const COUNT: usize = 1usize;
#[inline]
fn selector(&self) -> [u8; 4] {
match self {
Self::DeploymentFailed(_) => {
<DeploymentFailed as alloy_sol_types::SolError>::SELECTOR
}
}
}
#[inline]
fn selector_at(i: usize) -> ::core::option::Option<[u8; 4]> {
Self::SELECTORS.get(i).copied()
}
#[inline]
fn valid_selector(selector: [u8; 4]) -> bool {
Self::SELECTORS.binary_search(&selector).is_ok()
}
#[inline]
#[allow(unsafe_code, non_snake_case)]
fn abi_decode_raw(
selector: [u8; 4],
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<Self> {
static DECODE_SHIMS: &[fn(
&[u8],
bool,
) -> alloy_sol_types::Result<DeployerErrors>] = &[
{
fn DeploymentFailed(
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<DeployerErrors> {
<DeploymentFailed as alloy_sol_types::SolError>::abi_decode_raw(
data,
validate,
)
.map(DeployerErrors::DeploymentFailed)
}
DeploymentFailed
},
];
let Ok(idx) = Self::SELECTORS.binary_search(&selector) else {
return Err(
alloy_sol_types::Error::unknown_selector(
<Self as alloy_sol_types::SolInterface>::NAME,
selector,
),
);
};
(unsafe { DECODE_SHIMS.get_unchecked(idx) })(data, validate)
}
#[inline]
fn abi_encoded_size(&self) -> usize {
match self {
Self::DeploymentFailed(inner) => {
<DeploymentFailed as alloy_sol_types::SolError>::abi_encoded_size(
inner,
)
}
}
}
#[inline]
fn abi_encode_raw(&self, out: &mut alloy_sol_types::private::Vec<u8>) {
match self {
Self::DeploymentFailed(inner) => {
<DeploymentFailed as alloy_sol_types::SolError>::abi_encode_raw(
inner,
out,
)
}
}
}
}
///Container for all the [`Deployer`](self) events.
pub enum DeployerEvents {
Deployment(Deployment),
}
#[automatically_derived]
impl DeployerEvents {
/// All the selectors of this enum.
///
/// Note that the selectors might not be in the same order as the variants.
/// No guarantees are made about the order of the selectors.
///
/// Prefer using `SolInterface` methods instead.
pub const SELECTORS: &'static [[u8; 32usize]] = &[
[
96u8,
184u8,
119u8,
163u8,
186u8,
231u8,
191u8,
15u8,
11u8,
213u8,
225u8,
196u8,
14u8,
191u8,
68u8,
234u8,
21u8,
130u8,
1u8,
57u8,
127u8,
107u8,
114u8,
215u8,
192u8,
83u8,
96u8,
21u8,
123u8,
30u8,
192u8,
252u8,
],
];
}
#[automatically_derived]
impl alloy_sol_types::SolEventInterface for DeployerEvents {
const NAME: &'static str = "DeployerEvents";
const COUNT: usize = 1usize;
fn decode_raw_log(
topics: &[alloy_sol_types::Word],
data: &[u8],
validate: bool,
) -> alloy_sol_types::Result<Self> {
match topics.first().copied() {
Some(<Deployment as alloy_sol_types::SolEvent>::SIGNATURE_HASH) => {
<Deployment as alloy_sol_types::SolEvent>::decode_raw_log(
topics,
data,
validate,
)
.map(Self::Deployment)
}
_ => {
alloy_sol_types::private::Err(alloy_sol_types::Error::InvalidLog {
name: <Self as alloy_sol_types::SolEventInterface>::NAME,
log: alloy_sol_types::private::Box::new(
alloy_sol_types::private::LogData::new_unchecked(
topics.to_vec(),
data.to_vec().into(),
),
),
})
}
}
}
}
#[automatically_derived]
impl alloy_sol_types::private::IntoLogData for DeployerEvents {
fn to_log_data(&self) -> alloy_sol_types::private::LogData {
match self {
Self::Deployment(inner) => {
alloy_sol_types::private::IntoLogData::to_log_data(inner)
}
}
}
fn into_log_data(self) -> alloy_sol_types::private::LogData {
match self {
Self::Deployment(inner) => {
alloy_sol_types::private::IntoLogData::into_log_data(inner)
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
pub mod erc20;
pub mod deployer;
pub mod router;

File diff suppressed because it is too large Load diff

View file

@ -1,16 +0,0 @@
#[rustfmt::skip]
#[expect(warnings)]
#[expect(needless_pass_by_value)]
#[expect(clippy::all)]
#[expect(clippy::ignored_unit_patterns)]
#[expect(clippy::redundant_closure_for_method_calls)]
mod abigen;
pub mod erc20 {
pub use super::abigen::erc20::IERC20::*;
}
pub mod router {
pub const BYTECODE: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/serai-processor-ethereum-contracts/Router.bin"));
pub use super::abigen::router::Router::*;
}

View file

@ -1,52 +0,0 @@
[package]
name = "ethereum-serai"
version = "0.1.0"
description = "An Ethereum library supporting Schnorr signing and on-chain verification"
license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/processor/ethereum/ethereum-serai"
authors = ["Luke Parker <lukeparker5132@gmail.com>", "Elizabeth Binks <elizabethjbinks@gmail.com>"]
edition = "2021"
publish = false
rust-version = "1.79"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
thiserror = { version = "1", default-features = false }
rand_core = { version = "0.6", default-features = false, features = ["std"] }
transcript = { package = "flexible-transcript", path = "../../../crypto/transcript", default-features = false, features = ["recommended"] }
group = { version = "0.13", default-features = false }
k256 = { version = "^0.13.1", default-features = false, features = ["std", "ecdsa", "arithmetic"] }
frost = { package = "modular-frost", path = "../../../crypto/frost", default-features = false, features = ["secp256k1"] }
alloy-core = { version = "0.8", default-features = false }
alloy-sol-types = { version = "0.8", default-features = false, features = ["json"] }
alloy-consensus = { version = "0.3", default-features = false, features = ["k256"] }
alloy-network = { version = "0.3", default-features = false }
alloy-rpc-types-eth = { version = "0.3", default-features = false }
alloy-rpc-client = { version = "0.3", default-features = false }
alloy-simple-request-transport = { path = "../../../networks/ethereum/alloy-simple-request-transport", default-features = false }
alloy-provider = { version = "0.3", default-features = false }
alloy-node-bindings = { version = "0.3", default-features = false, optional = true }
ethereum-schnorr-contract = { path = "../../../networks/ethereum/schnorr", default-features = false }
contracts = { package = "serai-processor-ethereum-contracts", path = "../contracts" }
[dev-dependencies]
frost = { package = "modular-frost", path = "../../../crypto/frost", default-features = false, features = ["tests"] }
tokio = { version = "1", features = ["macros"] }
alloy-node-bindings = { version = "0.3", default-features = false }
[features]
tests = ["alloy-node-bindings", "frost/tests"]

View file

@ -1,15 +0,0 @@
AGPL-3.0-only license
Copyright (c) 2022-2023 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/>.

View file

@ -1,15 +0,0 @@
# Ethereum
This package contains Ethereum-related functionality, specifically deploying and
interacting with Serai contracts.
While `monero-serai` and `bitcoin-serai` are general purpose libraries,
`ethereum-serai` is Serai specific. If any of the utilities are generally
desired, please fork and maintain your own copy to ensure the desired
functionality is preserved, or open an issue to request we make this library
general purpose.
### Dependencies
- solc
- [Foundry](https://github.com/foundry-rs/foundry)

View file

@ -1,32 +0,0 @@
use group::ff::PrimeField;
use k256::{
elliptic_curve::{
ops::Reduce,
point::{AffineCoordinates, DecompressPoint},
sec1::ToEncodedPoint,
},
AffinePoint, ProjectivePoint, Scalar, U256 as KU256,
};
use frost::{
algorithm::{Hram, SchnorrSignature},
curve::{Ciphersuite, Secp256k1},
};
pub use ethereum_schnorr_contract::*;
use alloy_core::primitives::{Parity, Signature as AlloySignature, Address};
use alloy_consensus::{SignableTransaction, Signed, TxLegacy};
/// The HRAm to use for the Schnorr Solidity library.
///
/// This will panic if the public key being signed for is not representable within the Schnorr
/// Solidity library.
#[derive(Clone, Default)]
pub struct EthereumHram {}
impl Hram<Secp256k1> for EthereumHram {
#[allow(non_snake_case)]
fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar {
Signature::challenge(*R, &PublicKey::new(*A).unwrap(), m)
}
}

View file

@ -1,41 +0,0 @@
use thiserror::Error;
pub mod alloy {
pub use alloy_core::primitives;
pub use alloy_core as core;
pub use alloy_sol_types as sol_types;
pub use alloy_consensus as consensus;
pub use alloy_network as network;
pub use alloy_rpc_types_eth as rpc_types;
pub use alloy_simple_request_transport as simple_request_transport;
pub use alloy_rpc_client as rpc_client;
pub use alloy_provider as provider;
}
pub mod crypto;
/*
pub(crate) mod abi {
pub use contracts::erc20;
pub use contracts::deployer;
pub use contracts::router;
}
pub mod erc20;
pub mod deployer;
pub mod router;
pub mod machine;
#[cfg(any(test, feature = "tests"))]
pub mod tests;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
pub enum Error {
#[error("failed to verify Schnorr signature")]
InvalidSignature,
#[error("couldn't make call/send TX")]
ConnectionError,
}
*/

View file

@ -1,427 +0,0 @@
use std::{
io::{self, Read},
collections::HashMap,
};
use rand_core::{RngCore, CryptoRng};
use transcript::{Transcript, RecommendedTranscript};
use group::GroupEncoding;
use frost::{
curve::{Ciphersuite, Secp256k1},
Participant, ThresholdKeys, FrostError,
algorithm::Schnorr,
sign::*,
};
use alloy_core::primitives::U256;
use crate::{
crypto::{PublicKey, EthereumHram, Signature},
router::{
abi::{Call as AbiCall, OutInstruction as AbiOutInstruction},
Router,
},
};
/// The HRAm to use for the Schnorr Solidity library.
///
/// This will panic if the public key being signed for is not representable within the Schnorr
/// Solidity library.
#[derive(Clone, Default)]
pub struct EthereumHram {}
impl Hram<Secp256k1> for EthereumHram {
#[allow(non_snake_case)]
fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar {
Signature::challenge(*R, &PublicKey::new(*A).unwrap(), m)
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Call {
pub to: [u8; 20],
pub value: U256,
pub data: Vec<u8>,
}
impl Call {
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let mut to = [0; 20];
reader.read_exact(&mut to)?;
let value = {
let mut value_bytes = [0; 32];
reader.read_exact(&mut value_bytes)?;
U256::from_le_slice(&value_bytes)
};
let mut data_len = {
let mut data_len = [0; 4];
reader.read_exact(&mut data_len)?;
usize::try_from(u32::from_le_bytes(data_len)).expect("u32 couldn't fit within a usize")
};
// A valid DoS would be to claim a 4 GB data is present for only 4 bytes
// We read this in 1 KB chunks to only read data actually present (with a max DoS of 1 KB)
let mut data = vec![];
while data_len > 0 {
let chunk_len = data_len.min(1024);
let mut chunk = vec![0; chunk_len];
reader.read_exact(&mut chunk)?;
data.extend(&chunk);
data_len -= chunk_len;
}
Ok(Call { to, value, data })
}
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
writer.write_all(&self.to)?;
writer.write_all(&self.value.as_le_bytes())?;
let data_len = u32::try_from(self.data.len())
.map_err(|_| io::Error::other("call data length exceeded 2**32"))?;
writer.write_all(&data_len.to_le_bytes())?;
writer.write_all(&self.data)
}
}
impl From<Call> for AbiCall {
fn from(call: Call) -> AbiCall {
AbiCall { to: call.to.into(), value: call.value, data: call.data.into() }
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum OutInstructionTarget {
Direct([u8; 20]),
Calls(Vec<Call>),
}
impl OutInstructionTarget {
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let mut kind = [0xff];
reader.read_exact(&mut kind)?;
match kind[0] {
0 => {
let mut addr = [0; 20];
reader.read_exact(&mut addr)?;
Ok(OutInstructionTarget::Direct(addr))
}
1 => {
let mut calls_len = [0; 4];
reader.read_exact(&mut calls_len)?;
let calls_len = u32::from_le_bytes(calls_len);
let mut calls = vec![];
for _ in 0 .. calls_len {
calls.push(Call::read(reader)?);
}
Ok(OutInstructionTarget::Calls(calls))
}
_ => Err(io::Error::other("unrecognized OutInstructionTarget"))?,
}
}
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
match self {
OutInstructionTarget::Direct(addr) => {
writer.write_all(&[0])?;
writer.write_all(addr)?;
}
OutInstructionTarget::Calls(calls) => {
writer.write_all(&[1])?;
let call_len = u32::try_from(calls.len())
.map_err(|_| io::Error::other("amount of calls exceeded 2**32"))?;
writer.write_all(&call_len.to_le_bytes())?;
for call in calls {
call.write(writer)?;
}
}
}
Ok(())
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct OutInstruction {
pub target: OutInstructionTarget,
pub value: U256,
}
impl OutInstruction {
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let target = OutInstructionTarget::read(reader)?;
let value = {
let mut value_bytes = [0; 32];
reader.read_exact(&mut value_bytes)?;
U256::from_le_slice(&value_bytes)
};
Ok(OutInstruction { target, value })
}
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
self.target.write(writer)?;
writer.write_all(&self.value.as_le_bytes())
}
}
impl From<OutInstruction> for AbiOutInstruction {
fn from(instruction: OutInstruction) -> AbiOutInstruction {
match instruction.target {
OutInstructionTarget::Direct(addr) => {
AbiOutInstruction { to: addr.into(), calls: vec![], value: instruction.value }
}
OutInstructionTarget::Calls(calls) => AbiOutInstruction {
to: [0; 20].into(),
calls: calls.into_iter().map(Into::into).collect(),
value: instruction.value,
},
}
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum RouterCommand {
UpdateSeraiKey { chain_id: U256, nonce: U256, key: PublicKey },
Execute { chain_id: U256, nonce: U256, outs: Vec<OutInstruction> },
}
impl RouterCommand {
pub fn msg(&self) -> Vec<u8> {
match self {
RouterCommand::UpdateSeraiKey { chain_id, nonce, key } => {
Router::update_serai_key_message(*chain_id, *nonce, key)
}
RouterCommand::Execute { chain_id, nonce, outs } => Router::execute_message(
*chain_id,
*nonce,
outs.iter().map(|out| out.clone().into()).collect(),
),
}
}
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let mut kind = [0xff];
reader.read_exact(&mut kind)?;
match kind[0] {
0 => {
let mut chain_id = [0; 32];
reader.read_exact(&mut chain_id)?;
let mut nonce = [0; 32];
reader.read_exact(&mut nonce)?;
let key = PublicKey::new(Secp256k1::read_G(reader)?)
.ok_or(io::Error::other("key for RouterCommand doesn't have an eth representation"))?;
Ok(RouterCommand::UpdateSeraiKey {
chain_id: U256::from_le_slice(&chain_id),
nonce: U256::from_le_slice(&nonce),
key,
})
}
1 => {
let mut chain_id = [0; 32];
reader.read_exact(&mut chain_id)?;
let chain_id = U256::from_le_slice(&chain_id);
let mut nonce = [0; 32];
reader.read_exact(&mut nonce)?;
let nonce = U256::from_le_slice(&nonce);
let mut outs_len = [0; 4];
reader.read_exact(&mut outs_len)?;
let outs_len = u32::from_le_bytes(outs_len);
let mut outs = vec![];
for _ in 0 .. outs_len {
outs.push(OutInstruction::read(reader)?);
}
Ok(RouterCommand::Execute { chain_id, nonce, outs })
}
_ => Err(io::Error::other("reading unknown type of RouterCommand"))?,
}
}
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
match self {
RouterCommand::UpdateSeraiKey { chain_id, nonce, key } => {
writer.write_all(&[0])?;
writer.write_all(&chain_id.as_le_bytes())?;
writer.write_all(&nonce.as_le_bytes())?;
writer.write_all(&key.point().to_bytes())
}
RouterCommand::Execute { chain_id, nonce, outs } => {
writer.write_all(&[1])?;
writer.write_all(&chain_id.as_le_bytes())?;
writer.write_all(&nonce.as_le_bytes())?;
writer.write_all(&u32::try_from(outs.len()).unwrap().to_le_bytes())?;
for out in outs {
out.write(writer)?;
}
Ok(())
}
}
}
pub fn serialize(&self) -> Vec<u8> {
let mut res = vec![];
self.write(&mut res).unwrap();
res
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SignedRouterCommand {
command: RouterCommand,
signature: Signature,
}
impl SignedRouterCommand {
pub fn new(key: &PublicKey, command: RouterCommand, signature: &[u8; 64]) -> Option<Self> {
let c = Secp256k1::read_F(&mut &signature[.. 32]).ok()?;
let s = Secp256k1::read_F(&mut &signature[32 ..]).ok()?;
let signature = Signature { c, s };
if !signature.verify(key, &command.msg()) {
None?
}
Some(SignedRouterCommand { command, signature })
}
pub fn command(&self) -> &RouterCommand {
&self.command
}
pub fn signature(&self) -> &Signature {
&self.signature
}
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
let command = RouterCommand::read(reader)?;
let mut sig = [0; 64];
reader.read_exact(&mut sig)?;
let signature = Signature::from_bytes(sig)?;
Ok(SignedRouterCommand { command, signature })
}
pub fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
self.command.write(writer)?;
writer.write_all(&self.signature.to_bytes())
}
}
pub struct RouterCommandMachine {
key: PublicKey,
command: RouterCommand,
machine: AlgorithmMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, EthereumHram>>,
}
impl RouterCommandMachine {
pub fn new(keys: ThresholdKeys<Secp256k1>, command: RouterCommand) -> Option<Self> {
// The Schnorr algorithm should be fine without this, even when using the IETF variant
// If this is better and more comprehensive, we should do it, even if not necessary
let mut transcript = RecommendedTranscript::new(b"ethereum-serai RouterCommandMachine v0.1");
let key = keys.group_key();
transcript.append_message(b"key", key.to_bytes());
transcript.append_message(b"command", command.serialize());
Some(Self {
key: PublicKey::new(key)?,
command,
machine: AlgorithmMachine::new(Schnorr::new(transcript), keys),
})
}
}
impl PreprocessMachine for RouterCommandMachine {
type Preprocess = Preprocess<Secp256k1, ()>;
type Signature = SignedRouterCommand;
type SignMachine = RouterCommandSignMachine;
fn preprocess<R: RngCore + CryptoRng>(
self,
rng: &mut R,
) -> (Self::SignMachine, Self::Preprocess) {
let (machine, preprocess) = self.machine.preprocess(rng);
(RouterCommandSignMachine { key: self.key, command: self.command, machine }, preprocess)
}
}
pub struct RouterCommandSignMachine {
key: PublicKey,
command: RouterCommand,
machine: AlgorithmSignMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, EthereumHram>>,
}
impl SignMachine<SignedRouterCommand> for RouterCommandSignMachine {
type Params = ();
type Keys = ThresholdKeys<Secp256k1>;
type Preprocess = Preprocess<Secp256k1, ()>;
type SignatureShare = SignatureShare<Secp256k1>;
type SignatureMachine = RouterCommandSignatureMachine;
fn cache(self) -> CachedPreprocess {
unimplemented!(
"RouterCommand machines don't support caching their preprocesses due to {}",
"being already bound to a specific command"
);
}
fn from_cache(
(): (),
_: ThresholdKeys<Secp256k1>,
_: CachedPreprocess,
) -> (Self, Self::Preprocess) {
unimplemented!(
"RouterCommand machines don't support caching their preprocesses due to {}",
"being already bound to a specific command"
);
}
fn read_preprocess<R: Read>(&self, reader: &mut R) -> io::Result<Self::Preprocess> {
self.machine.read_preprocess(reader)
}
fn sign(
self,
commitments: HashMap<Participant, Self::Preprocess>,
msg: &[u8],
) -> Result<(RouterCommandSignatureMachine, Self::SignatureShare), FrostError> {
if !msg.is_empty() {
panic!("message was passed to a RouterCommand machine when it generates its own");
}
let (machine, share) = self.machine.sign(commitments, &self.command.msg())?;
Ok((RouterCommandSignatureMachine { key: self.key, command: self.command, machine }, share))
}
}
pub struct RouterCommandSignatureMachine {
key: PublicKey,
command: RouterCommand,
machine:
AlgorithmSignatureMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, EthereumHram>>,
}
impl SignatureMachine<SignedRouterCommand> for RouterCommandSignatureMachine {
type SignatureShare = SignatureShare<Secp256k1>;
fn read_share<R: Read>(&self, reader: &mut R) -> io::Result<Self::SignatureShare> {
self.machine.read_share(reader)
}
fn complete(
self,
shares: HashMap<Participant, Self::SignatureShare>,
) -> Result<SignedRouterCommand, FrostError> {
let signature = self.machine.complete(shares)?;
let signature = Signature::new(signature).expect("machine produced an invalid signature");
assert!(signature.verify(&self.key, &self.command.msg()));
Ok(SignedRouterCommand { command: self.command, signature })
}
}

View file

@ -40,8 +40,12 @@ impl Action {
fn message(&self) -> Vec<u8> { fn message(&self) -> Vec<u8> {
match self { match self {
Action::SetKey { chain_id, nonce, key } => Router::update_serai_key_message(*chain_id, *nonce, key), Action::SetKey { chain_id, nonce, key } => {
Action::Batch { chain_id, nonce, outs } => Router::execute_message(*chain_id, *nonce, OutInstructions::from(outs.as_ref())), Router::update_serai_key_message(*chain_id, *nonce, key)
}
Action::Batch { chain_id, nonce, outs } => {
Router::execute_message(*chain_id, *nonce, OutInstructions::from(outs.as_ref()))
}
} }
} }
@ -129,9 +133,17 @@ impl PreprocessMachine for ClonableTransctionMachine {
self, self,
rng: &mut R, rng: &mut R,
) -> (Self::SignMachine, Self::Preprocess) { ) -> (Self::SignMachine, Self::Preprocess) {
let (machine, preprocess) = AlgorithmMachine::new(IetfSchnorr::<Secp256k1, EthereumHram>::ietf(), self.0.clone()) let (machine, preprocess) =
AlgorithmMachine::new(IetfSchnorr::<Secp256k1, EthereumHram>::ietf(), self.0.clone())
.preprocess(rng); .preprocess(rng);
(ActionSignMachine(PublicKey::new(self.0.group_key()).expect("signing with non-representable key"), self.1, machine), preprocess) (
ActionSignMachine(
PublicKey::new(self.0.group_key()).expect("signing with non-representable key"),
self.1,
machine,
),
preprocess,
)
} }
} }
@ -157,7 +169,7 @@ impl SignMachine<Transaction> for ActionSignMachine {
params: Self::Params, params: Self::Params,
keys: Self::Keys, keys: Self::Keys,
cache: CachedPreprocess, cache: CachedPreprocess,
) -> (Self, Self::Preprocess) { ) -> (Self, Self::Preprocess) {
unimplemented!() unimplemented!()
} }

View file

@ -29,7 +29,6 @@ dkg = { path = "../../crypto/dkg", default-features = false, features = ["std"]
bitcoin-serai = { path = "../../networks/bitcoin" } bitcoin-serai = { path = "../../networks/bitcoin" }
k256 = "0.13" k256 = "0.13"
ethereum-serai = { path = "../../processor/ethereum/ethereum-serai" }
monero-simple-request-rpc = { path = "../../networks/monero/rpc/simple-request" } monero-simple-request-rpc = { path = "../../networks/monero/rpc/simple-request" }
monero-wallet = { path = "../../networks/monero/wallet" } monero-wallet = { path = "../../networks/monero/wallet" }