mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 13:39:25 +00:00
Compare commits
35 Commits
ea66cd0d1a
...
next
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca93c82156 | ||
|
|
5b1875dae6 | ||
|
|
bcd68441be | ||
|
|
4ebf9ad9c7 | ||
|
|
807572199c | ||
|
|
3cdc1536c5 | ||
|
|
9e13e5ebff | ||
|
|
9b2c254eee | ||
|
|
0883479068 | ||
|
|
c5480c63be | ||
|
|
4280ee6987 | ||
|
|
91673d7ae3 | ||
|
|
927f07b62b | ||
|
|
7e774d6d2d | ||
|
|
fccd06b376 | ||
|
|
e3edc0a7fc | ||
|
|
9c47ef2658 | ||
|
|
e1b6b638c6 | ||
|
|
c24768f922 | ||
|
|
87ee879dea | ||
|
|
b5603560e8 | ||
|
|
5818f1a41c | ||
|
|
1b781b4b57 | ||
|
|
94faf098b6 | ||
|
|
03e45f73cd | ||
|
|
63f7e220c0 | ||
|
|
7d49366373 | ||
|
|
55ed33d2d1 | ||
|
|
138a0e9b40 | ||
|
|
4fc7263ac3 | ||
|
|
f27fd59fa6 | ||
|
|
437f0e9a93 | ||
|
|
cc5d38f1ce | ||
|
|
0ce025e0c2 | ||
|
|
224cf4ea21 |
2
.github/actions/bitcoin/action.yml
vendored
2
.github/actions/bitcoin/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
|||||||
version:
|
version:
|
||||||
description: "Version to download and run"
|
description: "Version to download and run"
|
||||||
required: false
|
required: false
|
||||||
default: "29.1"
|
default: "30.0"
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
|
|||||||
21
.github/actions/build-dependencies/action.yml
vendored
21
.github/actions/build-dependencies/action.yml
vendored
@@ -7,6 +7,10 @@ runs:
|
|||||||
- name: Remove unused packages
|
- name: Remove unused packages
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
# Ensure the repositories are synced
|
||||||
|
sudo apt update -y
|
||||||
|
|
||||||
|
# Actually perform the removals
|
||||||
sudo apt remove -y "*powershell*" "*nuget*" "*bazel*" "*ansible*" "*terraform*" "*heroku*" "*aws*" azure-cli
|
sudo apt remove -y "*powershell*" "*nuget*" "*bazel*" "*ansible*" "*terraform*" "*heroku*" "*aws*" azure-cli
|
||||||
sudo apt remove -y "*nodejs*" "*npm*" "*yarn*" "*java*" "*kotlin*" "*golang*" "*swift*" "*julia*" "*fortran*" "*android*"
|
sudo apt remove -y "*nodejs*" "*npm*" "*yarn*" "*java*" "*kotlin*" "*golang*" "*swift*" "*julia*" "*fortran*" "*android*"
|
||||||
sudo apt remove -y "*apache2*" "*nginx*" "*firefox*" "*chromium*" "*chrome*" "*edge*"
|
sudo apt remove -y "*apache2*" "*nginx*" "*firefox*" "*chromium*" "*chrome*" "*edge*"
|
||||||
@@ -14,8 +18,9 @@ runs:
|
|||||||
sudo apt remove -y --allow-remove-essential -f shim-signed *python3*
|
sudo apt remove -y --allow-remove-essential -f shim-signed *python3*
|
||||||
# This removal command requires the prior removals due to unmet dependencies otherwise
|
# This removal command requires the prior removals due to unmet dependencies otherwise
|
||||||
sudo apt remove -y "*qemu*" "*sql*" "*texinfo*" "*imagemagick*"
|
sudo apt remove -y "*qemu*" "*sql*" "*texinfo*" "*imagemagick*"
|
||||||
|
|
||||||
# Reinstall python3 as a general dependency of a functional operating system
|
# Reinstall python3 as a general dependency of a functional operating system
|
||||||
sudo apt install python3
|
sudo apt install -y python3 --fix-missing
|
||||||
if: runner.os == 'Linux'
|
if: runner.os == 'Linux'
|
||||||
|
|
||||||
- name: Remove unused packages
|
- name: Remove unused packages
|
||||||
@@ -33,19 +38,23 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||||
sudo apt install -y ca-certificates protobuf-compiler
|
sudo apt install -y ca-certificates protobuf-compiler libclang-dev
|
||||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
choco install protoc
|
choco install protoc
|
||||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
brew install protobuf
|
brew install protobuf llvm
|
||||||
|
HOMEBREW_ROOT_PATH=/opt/homebrew # Apple Silicon
|
||||||
|
if [ $(uname -m) = "x86_64" ]; then HOMEBREW_ROOT_PATH=/usr/local; fi # Intel
|
||||||
|
ls $HOMEBREW_ROOT_PATH/opt/llvm/lib | grep "libclang.dylib" # Make sure this installed `libclang`
|
||||||
|
echo "DYLD_LIBRARY_PATH=$HOMEBREW_ROOT_PATH/opt/llvm/lib:$DYLD_LIBRARY_PATH" >> "$GITHUB_ENV"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Install solc
|
- name: Install solc
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cargo +1.90 install svm-rs --version =0.5.19
|
cargo +1.91 install svm-rs --version =0.5.19
|
||||||
svm install 0.8.26
|
svm install 0.8.29
|
||||||
svm use 0.8.26
|
svm use 0.8.29
|
||||||
|
|
||||||
- name: Remove preinstalled Docker
|
- name: Remove preinstalled Docker
|
||||||
shell: bash
|
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:
|
version:
|
||||||
description: "Version to download and run"
|
description: "Version to download and run"
|
||||||
required: false
|
required: false
|
||||||
default: v0.18.3.4
|
default: v0.18.4.3
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
|
|||||||
2
.github/actions/monero/action.yml
vendored
2
.github/actions/monero/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
|||||||
version:
|
version:
|
||||||
description: "Version to download and run"
|
description: "Version to download and run"
|
||||||
required: false
|
required: false
|
||||||
default: v0.18.3.4
|
default: v0.18.4.3
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
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:
|
monero-version:
|
||||||
description: "Monero version to download and run as a regtest node"
|
description: "Monero version to download and run as a regtest node"
|
||||||
required: false
|
required: false
|
||||||
default: v0.18.3.4
|
default: v0.18.4.3
|
||||||
|
|
||||||
bitcoin-version:
|
bitcoin-version:
|
||||||
description: "Bitcoin version to download and run as a regtest node"
|
description: "Bitcoin version to download and run as a regtest node"
|
||||||
required: false
|
required: false
|
||||||
default: "29.1"
|
default: "30.0"
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
|
|||||||
2
.github/nightly-version
vendored
2
.github/nightly-version
vendored
@@ -1 +1 @@
|
|||||||
nightly-2025-09-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
|
key: rust-advisory-db
|
||||||
|
|
||||||
- name: Install cargo deny
|
- 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
|
- name: Run cargo deny
|
||||||
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
||||||
|
|||||||
22
.github/workflows/lint.yml
vendored
22
.github/workflows/lint.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
clippy:
|
clippy:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-13, macos-14, windows-latest]
|
os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
uses: ./.github/actions/build-dependencies
|
uses: ./.github/actions/build-dependencies
|
||||||
|
|
||||||
- name: Install nightly rust
|
- name: Install nightly rust
|
||||||
run: rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t 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
|
- name: Run Clippy
|
||||||
run: cargo +${{ steps.nightly.outputs.version }} clippy --all-features --all-targets -- -D warnings -A clippy::items_after_test_module
|
run: cargo +${{ steps.nightly.outputs.version }} clippy --all-features --all-targets -- -D warnings -A clippy::items_after_test_module
|
||||||
@@ -52,7 +52,7 @@ jobs:
|
|||||||
key: rust-advisory-db
|
key: rust-advisory-db
|
||||||
|
|
||||||
- name: Install cargo deny
|
- 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
|
- name: Run cargo deny
|
||||||
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
run: cargo deny -L error --all-features check --hide-inclusion-graph
|
||||||
@@ -88,8 +88,8 @@ jobs:
|
|||||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||||
- name: Verify all dependencies are in use
|
- name: Verify all dependencies are in use
|
||||||
run: |
|
run: |
|
||||||
cargo +1.90 install cargo-machete --version =0.9.1
|
cargo +1.91 install cargo-machete --version =0.9.1
|
||||||
cargo +1.90 machete
|
cargo +1.91 machete
|
||||||
|
|
||||||
msrv:
|
msrv:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -98,7 +98,7 @@ jobs:
|
|||||||
- name: Verify claimed `rust-version`
|
- name: Verify claimed `rust-version`
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cargo +1.90 install cargo-msrv --version =0.18.4
|
cargo +1.91 install cargo-msrv --version =0.18.4
|
||||||
|
|
||||||
function check_msrv {
|
function check_msrv {
|
||||||
# We `cd` into the directory passed as the first argument, but will return to the
|
# 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 "],"
|
# Correct the last line, which was malleated to "],"
|
||||||
members=$(echo "$members" | sed "$(echo "$members" | wc -l)s/\]\,/\]/")
|
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
|
# Don't check the following
|
||||||
# Most of these are binaries, with the exception of the Substrate runtime which has a
|
# Most of these are binaries, with the exception of the Substrate runtime which has a
|
||||||
# bespoke build pipeline
|
# bespoke build pipeline
|
||||||
@@ -192,12 +190,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac
|
||||||
|
|
||||||
|
- name: Build Dependencies
|
||||||
|
uses: ./.github/actions/build-dependencies
|
||||||
|
|
||||||
- name: Slither
|
- name: Slither
|
||||||
run: |
|
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
|
python3 -m pip install slither-analyzer
|
||||||
|
|
||||||
slither --include-paths ./networks/ethereum/schnorr/contracts/Schnorr.sol
|
slither --include-paths ./networks/ethereum/schnorr/contracts/Schnorr.sol
|
||||||
|
|||||||
2
.github/workflows/pages.yml
vendored
2
.github/workflows/pages.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
|||||||
- name: Buld Rust docs
|
- name: Buld Rust docs
|
||||||
run: |
|
run: |
|
||||||
rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32v1-none -c rust-docs
|
rustup toolchain install ${{ steps.nightly.outputs.version }} --profile minimal -t wasm32v1-none -c rust-docs
|
||||||
RUSTDOCFLAGS="--cfg docsrs" cargo +${{ steps.nightly.outputs.version }} doc --workspace --all-features
|
RUSTDOCFLAGS="--cfg docsrs" cargo +${{ steps.nightly.outputs.version }} doc --workspace --no-deps --all-features
|
||||||
mv target/doc docs/_site/rust
|
mv target/doc docs/_site/rust
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
|
|||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,7 +1,14 @@
|
|||||||
target
|
target
|
||||||
|
|
||||||
|
# Don't commit any `Cargo.lock` which aren't the workspace's
|
||||||
|
Cargo.lock
|
||||||
|
!./Cargo.lock
|
||||||
|
|
||||||
|
# Don't commit any `Dockerfile`, as they're auto-generated, except the only one which isn't
|
||||||
Dockerfile
|
Dockerfile
|
||||||
Dockerfile.fast-epoch
|
Dockerfile.fast-epoch
|
||||||
!orchestration/runtime/Dockerfile
|
!orchestration/runtime/Dockerfile
|
||||||
|
|
||||||
.test-logs
|
.test-logs
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
6213
Cargo.lock
generated
6213
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
50
Cargo.toml
50
Cargo.toml
@@ -1,19 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
# Version patches
|
|
||||||
"patches/parking_lot",
|
|
||||||
"patches/zstd",
|
|
||||||
"patches/rocksdb",
|
|
||||||
|
|
||||||
# std patches
|
|
||||||
"patches/matches",
|
|
||||||
"patches/is-terminal",
|
|
||||||
|
|
||||||
# Rewrites/redirects
|
|
||||||
"patches/option-ext",
|
|
||||||
"patches/directories-next",
|
|
||||||
|
|
||||||
"common/std-shims",
|
"common/std-shims",
|
||||||
"common/zalloc",
|
"common/zalloc",
|
||||||
"common/patchable-async-sleep",
|
"common/patchable-async-sleep",
|
||||||
@@ -185,6 +172,12 @@ panic = "unwind"
|
|||||||
overflow-checks = true
|
overflow-checks = true
|
||||||
|
|
||||||
[patch.crates-io]
|
[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
|
# Dependencies from monero-oxide which originate from within our own tree
|
||||||
std-shims = { path = "patches/std-shims" }
|
std-shims = { path = "patches/std-shims" }
|
||||||
simple-request = { path = "patches/simple-request" }
|
simple-request = { path = "patches/simple-request" }
|
||||||
@@ -195,20 +188,16 @@ dalek-ff-group = { path = "patches/dalek-ff-group" }
|
|||||||
minimal-ed448 = { path = "crypto/ed448" }
|
minimal-ed448 = { path = "crypto/ed448" }
|
||||||
modular-frost = { path = "crypto/frost" }
|
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
|
# 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" }
|
lazy_static = { git = "https://github.com/rust-lang-nursery/lazy-static.rs", rev = "5735630d46572f1e5377c8f2ba0f79d18f53b10c" }
|
||||||
|
|
||||||
parking_lot = { path = "patches/parking_lot" }
|
|
||||||
# wasmtime pulls in an old version for this
|
|
||||||
zstd = { path = "patches/zstd" }
|
|
||||||
# Needed for WAL compression
|
|
||||||
rocksdb = { path = "patches/rocksdb" }
|
|
||||||
|
|
||||||
# is-terminal now has an std-based solution with an equivalent API
|
|
||||||
is-terminal = { path = "patches/is-terminal" }
|
|
||||||
# So does matches
|
|
||||||
matches = { path = "patches/matches" }
|
|
||||||
|
|
||||||
# directories-next was created because directories was unmaintained
|
# directories-next was created because directories was unmaintained
|
||||||
# directories-next is now unmaintained while directories is maintained
|
# directories-next is now unmaintained while directories is maintained
|
||||||
# The directories author pulls in ridiculously pointless crates and prefers
|
# The directories author pulls in ridiculously pointless crates and prefers
|
||||||
@@ -217,10 +206,16 @@ matches = { path = "patches/matches" }
|
|||||||
option-ext = { path = "patches/option-ext" }
|
option-ext = { path = "patches/option-ext" }
|
||||||
directories-next = { path = "patches/directories-next" }
|
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" }
|
k256 = { git = "https://github.com/kayabaNerve/elliptic-curves", rev = "4994c9ab163781a88cd4a49beae812a89a44e8c3" }
|
||||||
p256 = { 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]
|
[workspace.lints.clippy]
|
||||||
unwrap_or_default = "allow"
|
unwrap_or_default = "allow"
|
||||||
map_unwrap_or = "allow"
|
map_unwrap_or = "allow"
|
||||||
@@ -265,7 +260,7 @@ redundant_closure_for_method_calls = "deny"
|
|||||||
redundant_else = "deny"
|
redundant_else = "deny"
|
||||||
string_add_assign = "deny"
|
string_add_assign = "deny"
|
||||||
string_slice = "deny"
|
string_slice = "deny"
|
||||||
unchecked_duration_subtraction = "deny"
|
unchecked_time_subtraction = "deny"
|
||||||
uninlined_format_args = "deny"
|
uninlined_format_args = "deny"
|
||||||
unnecessary_box_returns = "deny"
|
unnecessary_box_returns = "deny"
|
||||||
unnecessary_join = "deny"
|
unnecessary_join = "deny"
|
||||||
@@ -274,3 +269,6 @@ unnested_or_patterns = "deny"
|
|||||||
unused_async = "deny"
|
unused_async = "deny"
|
||||||
unused_self = "deny"
|
unused_self = "deny"
|
||||||
zero_sized_map_values = "deny"
|
zero_sized_map_values = "deny"
|
||||||
|
|
||||||
|
[workspace.lints.rust]
|
||||||
|
unused = "allow" # TODO: https://github.com/rust-lang/rust/issues/147648
|
||||||
|
|||||||
50
audits/crypto/dkg/evrf/README.md
Normal file
50
audits/crypto/dkg/evrf/README.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# eVRF DKG
|
||||||
|
|
||||||
|
In 2024, the [eVRF paper](https://eprint.iacr.org/2024/397) was published to
|
||||||
|
the IACR preprint server. Within it was a one-round unbiased DKG and a
|
||||||
|
one-round unbiased threshold DKG. Unfortunately, both simply describe
|
||||||
|
communication of the secret shares as 'Alice sends $s_b$ to Bob'. This causes,
|
||||||
|
in practice, the need for an additional round of communication to occur where
|
||||||
|
all participants confirm they received their secret shares.
|
||||||
|
|
||||||
|
Within Serai, it was posited to use the same premises as the DDH eVRF itself to
|
||||||
|
achieve a verifiable encryption scheme. This allows the secret shares to be
|
||||||
|
posted to any 'bulletin board' (such as a blockchain) and for all observers to
|
||||||
|
confirm:
|
||||||
|
|
||||||
|
- A participant participated
|
||||||
|
- The secret shares sent can be received by the intended recipient so long as
|
||||||
|
they can access the bulletin board
|
||||||
|
|
||||||
|
Additionally, Serai desired a robust scheme (albeit with an biased key as the
|
||||||
|
output, which is fine for our purposes). Accordingly, our implementation
|
||||||
|
instantiates the threshold eVRF DKG from the eVRF paper, with our own proposal
|
||||||
|
for verifiable encryption, with the caller allowed to decide the set of
|
||||||
|
participants. They may:
|
||||||
|
|
||||||
|
- Select everyone, collapsing to the non-threshold unbiased DKG from the eVRF
|
||||||
|
paper
|
||||||
|
- Select a pre-determined set, collapsing to the threshold unbaised DKG from
|
||||||
|
the eVRF paper
|
||||||
|
- Select a post-determined set (with any solution for the Common Subset
|
||||||
|
problem), allowing achieving a robust threshold biased DKG
|
||||||
|
|
||||||
|
Note that the eVRF paper proposes using the eVRF to sample coefficients yet
|
||||||
|
this is unnecessary when the resulting key will be biased. Any proof of
|
||||||
|
knowledge for the coefficients, as necessary for their extraction within the
|
||||||
|
security proofs, would be sufficient.
|
||||||
|
|
||||||
|
MAGIC Grants contracted HashCloak to formalize Serai's proposal for a DKG and
|
||||||
|
provide proofs for its security. This resulted in
|
||||||
|
[this paper](<./Security Proofs.pdf>).
|
||||||
|
|
||||||
|
Our implementation itself is then built on top of the audited
|
||||||
|
[`generalized-bulletproofs`](https://github.com/kayabaNerve/monero-oxide/tree/generalized-bulletproofs/audits/crypto/generalized-bulletproofs)
|
||||||
|
and
|
||||||
|
[`generalized-bulletproofs-ec-gadgets`](https://github.com/monero-oxide/monero-oxide/tree/fcmp%2B%2B/audits/fcmps).
|
||||||
|
|
||||||
|
Note we do not use the originally premised DDH eVRF yet the one premised on
|
||||||
|
elliptic curve divisors, the methodology of which is commented on
|
||||||
|
[here](https://github.com/monero-oxide/monero-oxide/tree/fcmp%2B%2B/audits/divisors).
|
||||||
|
|
||||||
|
Our implementation itself is unaudited at this time however.
|
||||||
BIN
audits/crypto/dkg/evrf/Security Proofs.pdf
Normal file
BIN
audits/crypto/dkg/evrf/Security Proofs.pdf
Normal file
Binary file not shown.
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parity-db = { version = "0.4", default-features = false, optional = true }
|
parity-db = { version = "0.5", default-features = false, optional = true }
|
||||||
rocksdb = { version = "0.24", default-features = false, features = ["zstd"], optional = true }
|
rocksdb = { version = "0.24", default-features = false, features = ["zstd"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
2
common/env/src/lib.rs
vendored
2
common/env/src/lib.rs
vendored
@@ -1,5 +1,5 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
|
||||||
// Obtain a variable from the Serai environment/secret store.
|
// Obtain a variable from the Serai environment/secret store.
|
||||||
pub fn var(variable: &str) -> Option<String> {
|
pub fn var(variable: &str) -> Option<String> {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "simple-request"
|
name = "simple-request"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
description = "A simple HTTP(S) request library"
|
description = "A simple HTTP(S) request library"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/common/request"
|
repository = "https://github.com/serai-dex/serai/tree/develop/common/request"
|
||||||
@@ -19,10 +19,10 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
tower-service = { version = "0.3", default-features = false }
|
tower-service = { version = "0.3", default-features = false }
|
||||||
hyper = { version = "1", default-features = false, features = ["http1", "client"] }
|
hyper = { version = "1", default-features = false, features = ["http1", "client"] }
|
||||||
hyper-util = { version = "0.1", default-features = false, features = ["http1", "client-legacy", "tokio"] }
|
hyper-util = { version = "0.1", default-features = false, features = ["http1", "client-legacy"] }
|
||||||
http-body-util = { version = "0.1", default-features = false }
|
http-body-util = { version = "0.1", default-features = false }
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
tokio = { version = "1", default-features = false }
|
tokio = { version = "1", default-features = false, features = ["sync"] }
|
||||||
|
|
||||||
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "ring", "rustls-native-certs", "native-tokio"], optional = true }
|
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "ring", "rustls-native-certs", "native-tokio"], optional = true }
|
||||||
|
|
||||||
@@ -30,7 +30,8 @@ zeroize = { version = "1", optional = true }
|
|||||||
base64ct = { version = "1", features = ["alloc"], optional = true }
|
base64ct = { version = "1", features = ["alloc"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tls = ["hyper-rustls"]
|
tokio = ["hyper-util/tokio"]
|
||||||
|
tls = ["tokio", "hyper-rustls"]
|
||||||
webpki-roots = ["tls", "hyper-rustls/webpki-roots"]
|
webpki-roots = ["tls", "hyper-rustls/webpki-roots"]
|
||||||
basic-auth = ["zeroize", "base64ct"]
|
basic-auth = ["zeroize", "base64ct"]
|
||||||
default = ["tls"]
|
default = ["tls"]
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
|
use core::{pin::Pin, future::Future};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use tokio::sync::Mutex;
|
use futures_util::FutureExt;
|
||||||
|
use ::tokio::sync::Mutex;
|
||||||
|
|
||||||
use tower_service::Service as TowerService;
|
use tower_service::Service as TowerService;
|
||||||
|
use hyper::{Uri, header::HeaderValue, body::Bytes, client::conn::http1::SendRequest, rt::Executor};
|
||||||
|
pub use hyper;
|
||||||
|
|
||||||
|
use hyper_util::client::legacy::{Client as HyperClient, connect::HttpConnector};
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
use hyper_rustls::{HttpsConnectorBuilder, HttpsConnector};
|
use hyper_rustls::{HttpsConnectorBuilder, HttpsConnector};
|
||||||
use hyper::{Uri, header::HeaderValue, body::Bytes, client::conn::http1::SendRequest};
|
|
||||||
use hyper_util::{
|
|
||||||
rt::tokio::TokioExecutor,
|
|
||||||
client::legacy::{Client as HyperClient, connect::HttpConnector},
|
|
||||||
};
|
|
||||||
pub use hyper;
|
|
||||||
|
|
||||||
mod request;
|
mod request;
|
||||||
pub use request::*;
|
pub use request::*;
|
||||||
@@ -37,21 +38,32 @@ type Connector = HttpConnector;
|
|||||||
type Connector = HttpsConnector<HttpConnector>;
|
type Connector = HttpsConnector<HttpConnector>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum Connection {
|
enum Connection<
|
||||||
|
E: 'static + Send + Sync + Clone + Executor<Pin<Box<dyn Send + Future<Output = ()>>>>,
|
||||||
|
> {
|
||||||
ConnectionPool(HyperClient<Connector, Full<Bytes>>),
|
ConnectionPool(HyperClient<Connector, Full<Bytes>>),
|
||||||
Connection {
|
Connection {
|
||||||
|
executor: E,
|
||||||
connector: Connector,
|
connector: Connector,
|
||||||
host: Uri,
|
host: Uri,
|
||||||
connection: Arc<Mutex<Option<SendRequest<Full<Bytes>>>>>,
|
connection: Arc<Mutex<Option<SendRequest<Full<Bytes>>>>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An HTTP client.
|
||||||
|
///
|
||||||
|
/// `tls` is only guaranteed to work when using the `tokio` executor. Instantiating a client when
|
||||||
|
/// the `tls` feature is active without using the `tokio` executor will cause errors.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Client {
|
pub struct Client<
|
||||||
connection: Connection,
|
E: 'static + Send + Sync + Clone + Executor<Pin<Box<dyn Send + Future<Output = ()>>>>,
|
||||||
|
> {
|
||||||
|
connection: Connection<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl<E: 'static + Send + Sync + Clone + Executor<Pin<Box<dyn Send + Future<Output = ()>>>>>
|
||||||
|
Client<E>
|
||||||
|
{
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn connector() -> Result<Connector, Error> {
|
fn connector() -> Result<Connector, Error> {
|
||||||
let mut res = HttpConnector::new();
|
let mut res = HttpConnector::new();
|
||||||
@@ -59,6 +71,15 @@ impl Client {
|
|||||||
res.set_nodelay(true);
|
res.set_nodelay(true);
|
||||||
res.set_reuse_address(true);
|
res.set_reuse_address(true);
|
||||||
|
|
||||||
|
#[cfg(feature = "tls")]
|
||||||
|
if core::any::TypeId::of::<E>() !=
|
||||||
|
core::any::TypeId::of::<hyper_util::rt::tokio::TokioExecutor>()
|
||||||
|
{
|
||||||
|
Err(Error::ConnectionError(
|
||||||
|
"`tls` feature enabled but not using the `tokio` executor".into(),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
res.enforce_http(false);
|
res.enforce_http(false);
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
@@ -79,19 +100,23 @@ impl Client {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_connection_pool() -> Result<Client, Error> {
|
pub fn with_executor_and_connection_pool(executor: E) -> Result<Client<E>, Error> {
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
connection: Connection::ConnectionPool(
|
connection: Connection::ConnectionPool(
|
||||||
HyperClient::builder(TokioExecutor::new())
|
HyperClient::builder(executor)
|
||||||
.pool_idle_timeout(core::time::Duration::from_secs(60))
|
.pool_idle_timeout(core::time::Duration::from_secs(60))
|
||||||
.build(Self::connector()?),
|
.build(Self::connector()?),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn without_connection_pool(host: &str) -> Result<Client, Error> {
|
pub fn with_executor_and_without_connection_pool(
|
||||||
|
executor: E,
|
||||||
|
host: &str,
|
||||||
|
) -> Result<Client<E>, Error> {
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
connection: Connection::Connection {
|
connection: Connection::Connection {
|
||||||
|
executor,
|
||||||
connector: Self::connector()?,
|
connector: Self::connector()?,
|
||||||
host: {
|
host: {
|
||||||
let uri: Uri = host.parse().map_err(|_| Error::InvalidUri)?;
|
let uri: Uri = host.parse().map_err(|_| Error::InvalidUri)?;
|
||||||
@@ -105,7 +130,7 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn request<R: Into<Request>>(&self, request: R) -> Result<Response<'_>, Error> {
|
pub async fn request<R: Into<Request>>(&self, request: R) -> Result<Response<'_, E>, Error> {
|
||||||
let request: Request = request.into();
|
let request: Request = request.into();
|
||||||
let Request { mut request, response_size_limit } = request;
|
let Request { mut request, response_size_limit } = request;
|
||||||
if let Some(header_host) = request.headers().get(hyper::header::HOST) {
|
if let Some(header_host) = request.headers().get(hyper::header::HOST) {
|
||||||
@@ -141,7 +166,7 @@ impl Client {
|
|||||||
Connection::ConnectionPool(client) => {
|
Connection::ConnectionPool(client) => {
|
||||||
client.request(request).await.map_err(Error::HyperUtil)?
|
client.request(request).await.map_err(Error::HyperUtil)?
|
||||||
}
|
}
|
||||||
Connection::Connection { connector, host, connection } => {
|
Connection::Connection { executor, connector, host, connection } => {
|
||||||
let mut connection_lock = connection.lock().await;
|
let mut connection_lock = connection.lock().await;
|
||||||
|
|
||||||
// If there's not a connection...
|
// If there's not a connection...
|
||||||
@@ -153,9 +178,8 @@ impl Client {
|
|||||||
let call_res = call_res.map_err(Error::ConnectionError);
|
let call_res = call_res.map_err(Error::ConnectionError);
|
||||||
let (requester, connection) =
|
let (requester, connection) =
|
||||||
hyper::client::conn::http1::handshake(call_res?).await.map_err(Error::Hyper)?;
|
hyper::client::conn::http1::handshake(call_res?).await.map_err(Error::Hyper)?;
|
||||||
// This will die when we drop the requester, so we don't need to track an AbortHandle
|
// This task will die when we drop the requester
|
||||||
// for it
|
executor.execute(Box::pin(connection.map(|_| ())));
|
||||||
tokio::spawn(connection);
|
|
||||||
*connection_lock = Some(requester);
|
*connection_lock = Some(requester);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,3 +202,22 @@ impl Client {
|
|||||||
Ok(Response { response, size_limit: response_size_limit, client: self })
|
Ok(Response { response, size_limit: response_size_limit, client: self })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
mod tokio {
|
||||||
|
use hyper_util::rt::tokio::TokioExecutor;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub type TokioClient = Client<TokioExecutor>;
|
||||||
|
impl Client<TokioExecutor> {
|
||||||
|
pub fn with_connection_pool() -> Result<Self, Error> {
|
||||||
|
Self::with_executor_and_connection_pool(TokioExecutor::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn without_connection_pool(host: &str) -> Result<Self, Error> {
|
||||||
|
Self::with_executor_and_without_connection_pool(TokioExecutor::new(), host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "tokio")]
|
||||||
|
pub use tokio::TokioClient;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
use core::{pin::Pin, future::Future};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use hyper::{
|
use hyper::{
|
||||||
StatusCode,
|
StatusCode,
|
||||||
header::{HeaderValue, HeaderMap},
|
header::{HeaderValue, HeaderMap},
|
||||||
body::Incoming,
|
body::Incoming,
|
||||||
|
rt::Executor,
|
||||||
};
|
};
|
||||||
use http_body_util::BodyExt;
|
use http_body_util::BodyExt;
|
||||||
|
|
||||||
@@ -14,13 +16,18 @@ use crate::{Client, Error};
|
|||||||
// Borrows the client so its async task lives as long as this response exists.
|
// Borrows the client so its async task lives as long as this response exists.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Response<'a> {
|
pub struct Response<
|
||||||
|
'a,
|
||||||
|
E: 'static + Send + Sync + Clone + Executor<Pin<Box<dyn Send + Future<Output = ()>>>>,
|
||||||
|
> {
|
||||||
pub(crate) response: hyper::Response<Incoming>,
|
pub(crate) response: hyper::Response<Incoming>,
|
||||||
pub(crate) size_limit: Option<usize>,
|
pub(crate) size_limit: Option<usize>,
|
||||||
pub(crate) client: &'a Client,
|
pub(crate) client: &'a Client<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response<'_> {
|
impl<E: 'static + Send + Sync + Clone + Executor<Pin<Box<dyn Send + Future<Output = ()>>>>>
|
||||||
|
Response<'_, E>
|
||||||
|
{
|
||||||
pub fn status(&self) -> StatusCode {
|
pub fn status(&self) -> StatusCode {
|
||||||
self.response.status()
|
self.response.status()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ mod mutex_shim {
|
|||||||
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
|
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
|
||||||
|
|
||||||
#[rustversion::before(1.80)]
|
#[rustversion::before(1.80)]
|
||||||
|
pub use spin::Lazy as LazyLock;
|
||||||
|
|
||||||
|
#[rustversion::since(1.80)]
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
pub use spin::Lazy as LazyLock;
|
pub use spin::Lazy as LazyLock;
|
||||||
#[rustversion::since(1.80)]
|
#[rustversion::since(1.80)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![cfg_attr(all(zalloc_rustc_nightly, feature = "allocator"), feature(allocator_api))]
|
#![cfg_attr(all(zalloc_rustc_nightly, feature = "allocator"), feature(allocator_api))]
|
||||||
|
|
||||||
//! Implementation of a Zeroizing Allocator, enabling zeroizing memory on deallocation.
|
//! Implementation of a Zeroizing Allocator, enabling zeroizing memory on deallocation.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ tributary-sdk = { path = "../../tributary-sdk" }
|
|||||||
|
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
tokio = { version = "1", default-features = false, features = ["sync"] }
|
tokio = { version = "1", default-features = false, features = ["sync"] }
|
||||||
libp2p = { version = "0.54", default-features = false, features = ["tokio", "tcp", "noise", "yamux", "ping", "request-response", "gossipsub", "macros"] }
|
libp2p = { version = "0.56", default-features = false, features = ["tokio", "tcp", "noise", "yamux", "ping", "request-response", "gossipsub", "macros"] }
|
||||||
|
|
||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
serai-task = { path = "../../../common/task", version = "0.1" }
|
serai-task = { path = "../../../common/task", version = "0.1" }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ impl SwarmTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
gossip::Event::Subscribed { .. } | gossip::Event::Unsubscribed { .. } => {}
|
gossip::Event::Subscribed { .. } | gossip::Event::Unsubscribed { .. } => {}
|
||||||
gossip::Event::GossipsubNotSupported { peer_id } => {
|
gossip::Event::GossipsubNotSupported { peer_id } |
|
||||||
|
gossip::Event::SlowPeer { peer_id, .. } => {
|
||||||
let _: Result<_, _> = self.swarm.disconnect_peer_id(peer_id);
|
let _: Result<_, _> = self.swarm.disconnect_peer_id(peer_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ mod _internal_db {
|
|||||||
// Tributary transactions to publish from the DKG confirmation task
|
// Tributary transactions to publish from the DKG confirmation task
|
||||||
TributaryTransactionsFromDkgConfirmation: (set: ExternalValidatorSet) -> Transaction,
|
TributaryTransactionsFromDkgConfirmation: (set: ExternalValidatorSet) -> Transaction,
|
||||||
// Participants to remove
|
// 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) {
|
pub(crate) fn send(txn: &mut impl DbTxn, set: ExternalValidatorSet, participant: Participant) {
|
||||||
// If this set has yet to be retired, send this transaction
|
// 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) {
|
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> {
|
pub(crate) fn try_recv(txn: &mut impl DbTxn, set: ExternalValidatorSet) -> Option<Participant> {
|
||||||
_internal_db::RemoveParticipant::try_recv(txn, set)
|
_internal_db::RemoveParticipant::try_recv(txn, set)
|
||||||
|
.map(|i| Participant::new(i).expect("sent invalid participant index for removal"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ async fn handle_network(
|
|||||||
&mut txn,
|
&mut txn,
|
||||||
ExternalValidatorSet { network, session },
|
ExternalValidatorSet { network, session },
|
||||||
slash_report,
|
slash_report,
|
||||||
Signature(signature),
|
Signature::from(signature),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#![expect(clippy::cast_possible_truncation)]
|
||||||
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#![expect(clippy::cast_possible_truncation)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use scale::Encode;
|
use scale::Encode;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use zeroize::Zeroize;
|
use zeroize::Zeroize;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("lib.md")]
|
#![doc = include_str!("lib.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![no_std] // Prevents writing new code, in what should be a simple wrapper, which requires std
|
#![no_std] // Prevents writing new code, in what should be a simple wrapper, which requires std
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![allow(clippy::redundant_closure_call)]
|
#![allow(clippy::redundant_closure_call)]
|
||||||
|
|||||||
@@ -23,19 +23,12 @@ thiserror = { version = "2", default-features = false }
|
|||||||
|
|
||||||
std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] }
|
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"] }
|
ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = [
|
std = [
|
||||||
"thiserror/std",
|
"thiserror/std",
|
||||||
|
|
||||||
"std-shims/std",
|
"std-shims/std",
|
||||||
|
|
||||||
"borsh?/std",
|
|
||||||
|
|
||||||
"ciphersuite/std",
|
"ciphersuite/std",
|
||||||
]
|
]
|
||||||
borsh = ["dep:borsh"]
|
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -26,21 +26,9 @@ presented in section 4.2 is extended, with the following changes:
|
|||||||
just one round.
|
just one round.
|
||||||
|
|
||||||
For a gist of the verifiable encryption scheme, please see
|
For a gist of the verifiable encryption scheme, please see
|
||||||
https://gist.github.com/kayabaNerve/cfbde74b0660dfdf8dd55326d6ec33d7. Security
|
https://gist.github.com/kayabaNerve/cfbde74b0660dfdf8dd55326d6ec33d7. For
|
||||||
proofs are currently being worked on.
|
security proofs and audit information, please see
|
||||||
|
[here](../../../audits/crypto/dkg/evrf).
|
||||||
---
|
|
||||||
|
|
||||||
This library relies on an implementation of Bulletproofs and various
|
|
||||||
zero-knowledge gadgets. This library uses
|
|
||||||
[`generalized-bulletproofs`](https://docs.rs/generalized-bulletproofs),
|
|
||||||
[`generalized-bulletproofs-circuit-abstraction`](https://docs.rs/generalized-bulletproofs-circuit-abstraction),
|
|
||||||
and
|
|
||||||
[`generalized-bulletproofs-ec-gadgets`](https://docs.rs/generalized-bulletproofs-ec-gadgets)
|
|
||||||
from the Monero project's FCMP++ codebase. These libraries have received the
|
|
||||||
following audits in the past:
|
|
||||||
- https://github.com/kayabaNerve/monero-oxide/tree/fcmp++/audits/generalized-bulletproofs
|
|
||||||
- https://github.com/kayabaNerve/monero-oxide/tree/fcmp++/audits/fcmps
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
@@ -22,7 +22,6 @@ use ciphersuite::{
|
|||||||
|
|
||||||
/// The ID of a participant, defined as a non-zero u16.
|
/// The ID of a participant, defined as a non-zero u16.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Zeroize)]
|
||||||
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
|
|
||||||
pub struct Participant(u16);
|
pub struct Participant(u16);
|
||||||
impl Participant {
|
impl Participant {
|
||||||
/// Create a new Participant identifier from a u16.
|
/// Create a new Participant identifier from a u16.
|
||||||
@@ -129,18 +128,8 @@ pub enum DkgError {
|
|||||||
NotParticipating,
|
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.
|
/// Parameters for a multisig.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||||
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize))]
|
|
||||||
pub struct ThresholdParams {
|
pub struct ThresholdParams {
|
||||||
/// Participants needed to sign on behalf of the group.
|
/// Participants needed to sign on behalf of the group.
|
||||||
t: u16,
|
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.
|
/// A method of interpolation.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
pub enum Interpolation<F: Zeroize + PrimeField> {
|
pub enum Interpolation<F: Zeroize + PrimeField> {
|
||||||
|
|||||||
@@ -33,6 +33,6 @@ rand_core = { version = "0.6", default-features = false, features = ["std"] }
|
|||||||
ff-group-tests = { path = "../ff-group-tests" }
|
ff-group-tests = { path = "../ff-group-tests" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = ["zeroize/alloc", "sha3/alloc", "crypto-bigint/alloc", "prime-field/alloc", "ciphersuite/alloc"]
|
alloc = ["zeroize/alloc", "sha3/alloc", "prime-field/alloc", "ciphersuite/alloc"]
|
||||||
std = ["alloc", "zeroize/std", "prime-field/std", "ciphersuite/std"]
|
std = ["alloc", "zeroize/std", "prime-field/std", "ciphersuite/std"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
/// Tests for the Field trait.
|
/// Tests for the Field trait.
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ impl<A: Send + Sync + Clone + PartialEq + Debug + WriteAddendum> Addendum for A
|
|||||||
|
|
||||||
/// Algorithm trait usable by the FROST signing machine to produce signatures..
|
/// Algorithm trait usable by the FROST signing machine to produce signatures..
|
||||||
pub trait Algorithm<C: Curve>: Send + Sync {
|
pub trait Algorithm<C: Curve>: Send + Sync {
|
||||||
/// The transcript format this algorithm uses. This likely should NOT be the IETF-compatible
|
/// The transcript format this algorithm uses.
|
||||||
/// transcript included in this crate.
|
///
|
||||||
|
/// This MUST NOT be the IETF-compatible transcript included in this crate UNLESS this is an
|
||||||
|
/// IETF-specified ciphersuite.
|
||||||
type Transcript: Sync + Clone + Debug + Transcript;
|
type Transcript: Sync + Clone + Debug + Transcript;
|
||||||
/// Serializable addendum, used in algorithms requiring more data than just the nonces.
|
/// Serializable addendum, used in algorithms requiring more data than just the nonces.
|
||||||
type Addendum: Addendum;
|
type Addendum: Addendum;
|
||||||
@@ -69,8 +71,10 @@ pub trait Algorithm<C: Curve>: Send + Sync {
|
|||||||
) -> Result<(), FrostError>;
|
) -> Result<(), FrostError>;
|
||||||
|
|
||||||
/// Sign a share with the given secret/nonce.
|
/// Sign a share with the given secret/nonce.
|
||||||
|
///
|
||||||
/// The secret will already have been its lagrange coefficient applied so it is the necessary
|
/// The secret will already have been its lagrange coefficient applied so it is the necessary
|
||||||
/// key share.
|
/// key share.
|
||||||
|
///
|
||||||
/// The nonce will already have been processed into the combined form d + (e * p).
|
/// The nonce will already have been processed into the combined form d + (e * p).
|
||||||
fn sign_share(
|
fn sign_share(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -85,6 +89,7 @@ pub trait Algorithm<C: Curve>: Send + Sync {
|
|||||||
fn verify(&self, group_key: C::G, nonces: &[Vec<C::G>], sum: C::F) -> Option<Self::Signature>;
|
fn verify(&self, group_key: C::G, nonces: &[Vec<C::G>], sum: C::F) -> Option<Self::Signature>;
|
||||||
|
|
||||||
/// Verify a specific share given as a response.
|
/// Verify a specific share given as a response.
|
||||||
|
///
|
||||||
/// This function should return a series of pairs whose products should sum to zero for a valid
|
/// This function should return a series of pairs whose products should sum to zero for a valid
|
||||||
/// share. Any error raised is treated as the share being invalid.
|
/// share. Any error raised is treated as the share being invalid.
|
||||||
#[allow(clippy::type_complexity, clippy::result_unit_err)]
|
#[allow(clippy::type_complexity, clippy::result_unit_err)]
|
||||||
@@ -99,8 +104,10 @@ pub trait Algorithm<C: Curve>: Send + Sync {
|
|||||||
mod sealed {
|
mod sealed {
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
|
|
||||||
/// IETF-compliant transcript. This is incredibly naive and should not be used within larger
|
/// IETF-compliant transcript.
|
||||||
/// protocols.
|
///
|
||||||
|
/// This is incredibly naive and MUST NOT be used within larger protocols. No guarantees are made
|
||||||
|
/// about its safety EXCEPT as used with the IETF-specified FROST ciphersuites.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IetfTranscript(pub(crate) Vec<u8>);
|
pub struct IetfTranscript(pub(crate) Vec<u8>);
|
||||||
impl Transcript for IetfTranscript {
|
impl Transcript for IetfTranscript {
|
||||||
@@ -131,6 +138,7 @@ pub(crate) use sealed::IetfTranscript;
|
|||||||
/// HRAm usable by the included Schnorr signature algorithm to generate challenges.
|
/// HRAm usable by the included Schnorr signature algorithm to generate challenges.
|
||||||
pub trait Hram<C: Curve>: Send + Sync + Clone {
|
pub trait Hram<C: Curve>: Send + Sync + Clone {
|
||||||
/// HRAm function to generate a challenge.
|
/// HRAm function to generate a challenge.
|
||||||
|
///
|
||||||
/// H2 from the IETF draft, despite having a different argument set (not being pre-formatted).
|
/// H2 from the IETF draft, despite having a different argument set (not being pre-formatted).
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn hram(R: &C::G, A: &C::G, m: &[u8]) -> C::F;
|
fn hram(R: &C::G, A: &C::G, m: &[u8]) -> C::F;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ pub trait PreprocessMachine: Send {
|
|||||||
type SignMachine: SignMachine<Self::Signature, Preprocess = Self::Preprocess>;
|
type SignMachine: SignMachine<Self::Signature, Preprocess = Self::Preprocess>;
|
||||||
|
|
||||||
/// Perform the preprocessing round required in order to sign.
|
/// Perform the preprocessing round required in order to sign.
|
||||||
|
///
|
||||||
/// Returns a preprocess message to be broadcast to all participants, over an authenticated
|
/// Returns a preprocess message to be broadcast to all participants, over an authenticated
|
||||||
/// channel.
|
/// channel.
|
||||||
fn preprocess<R: RngCore + CryptoRng>(self, rng: &mut R)
|
fn preprocess<R: RngCore + CryptoRng>(self, rng: &mut R)
|
||||||
@@ -235,6 +236,8 @@ pub trait SignMachine<S>: Send + Sync + Sized {
|
|||||||
/// Takes in the participants' preprocess messages. Returns the signature share to be broadcast
|
/// Takes in the participants' preprocess messages. Returns the signature share to be broadcast
|
||||||
/// to all participants, over an authenticated channel. The parties who participate here will
|
/// to all participants, over an authenticated channel. The parties who participate here will
|
||||||
/// become the signing set for this session.
|
/// become the signing set for this session.
|
||||||
|
///
|
||||||
|
/// The caller MUST only use preprocesses obtained via this machine's `read_preprocess` function.
|
||||||
fn sign(
|
fn sign(
|
||||||
self,
|
self,
|
||||||
commitments: HashMap<Participant, Self::Preprocess>,
|
commitments: HashMap<Participant, Self::Preprocess>,
|
||||||
@@ -421,7 +424,10 @@ pub trait SignatureMachine<S>: Send + Sync {
|
|||||||
fn read_share<R: Read>(&self, reader: &mut R) -> io::Result<Self::SignatureShare>;
|
fn read_share<R: Read>(&self, reader: &mut R) -> io::Result<Self::SignatureShare>;
|
||||||
|
|
||||||
/// Complete signing.
|
/// Complete signing.
|
||||||
|
///
|
||||||
/// Takes in everyone elses' shares. Returns the signature.
|
/// Takes in everyone elses' shares. Returns the signature.
|
||||||
|
///
|
||||||
|
/// The caller MUST only use shares obtained via this machine's `read_shares` function.
|
||||||
fn complete(self, shares: HashMap<Participant, Self::SignatureShare>) -> Result<S, FrostError>;
|
fn complete(self, shares: HashMap<Participant, Self::SignatureShare>) -> Result<S, FrostError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,6 @@ ff = { version = "0.13", default-features = false, features = ["bits"] }
|
|||||||
ff-group-tests = { version = "0.13", path = "../ff-group-tests", optional = true }
|
ff-group-tests = { version = "0.13", path = "../ff-group-tests", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = ["zeroize/alloc", "crypto-bigint/alloc", "ff/alloc"]
|
alloc = ["zeroize/alloc", "ff/alloc"]
|
||||||
std = ["alloc", "zeroize/std", "subtle/std", "rand_core/std", "ff/std", "ff-group-tests"]
|
std = ["alloc", "zeroize/std", "subtle/std", "rand_core/std", "ff/std", "ff-group-tests"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
22
deny.toml
22
deny.toml
@@ -7,11 +7,10 @@ db-urls = ["https://github.com/rustsec/advisory-db"]
|
|||||||
yanked = "deny"
|
yanked = "deny"
|
||||||
|
|
||||||
ignore = [
|
ignore = [
|
||||||
"RUSTSEC-2020-0168", # mach is unmaintained
|
|
||||||
"RUSTSEC-2021-0139", # https://github.com/serai-dex/serai/228
|
|
||||||
"RUSTSEC-2022-0061", # https://github.com/serai-dex/serai/227
|
"RUSTSEC-2022-0061", # https://github.com/serai-dex/serai/227
|
||||||
"RUSTSEC-2024-0370", # proc-macro-error is unmaintained
|
"RUSTSEC-2024-0370", # proc-macro-error is unmaintained
|
||||||
"RUSTSEC-2024-0384", # instant is unmaintained
|
"RUSTSEC-2024-0436", # paste is unmaintained
|
||||||
|
"RUSTSEC-2025-0057", # fxhash is unmaintained, fixed with bytecodealliance/wasmtime/pull/11634
|
||||||
]
|
]
|
||||||
|
|
||||||
[licenses]
|
[licenses]
|
||||||
@@ -30,10 +29,11 @@ allow = [
|
|||||||
"ISC",
|
"ISC",
|
||||||
"Zlib",
|
"Zlib",
|
||||||
"Unicode-3.0",
|
"Unicode-3.0",
|
||||||
"OpenSSL",
|
# "OpenSSL", # Commented as it's not currently in-use within the Serai tree
|
||||||
|
"CDLA-Permissive-2.0",
|
||||||
|
|
||||||
# Non-invasive copyleft
|
# Non-invasive copyleft
|
||||||
"MPL-2.0",
|
# "MPL-2.0", # Commented as it's not currently in-use within the Serai tree
|
||||||
"Apache-2.0",
|
"Apache-2.0",
|
||||||
"Apache-2.0 WITH LLVM-exception",
|
"Apache-2.0 WITH LLVM-exception",
|
||||||
"GPL-3.0-or-later WITH Classpath-exception-2.0",
|
"GPL-3.0-or-later WITH Classpath-exception-2.0",
|
||||||
@@ -80,6 +80,8 @@ exceptions = [
|
|||||||
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-libp2p-p2p" },
|
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator-libp2p-p2p" },
|
||||||
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator" },
|
{ allow = ["AGPL-3.0-only"], name = "serai-coordinator" },
|
||||||
|
|
||||||
|
{ allow = ["AGPL-3.0-only"], name = "pallet-session" },
|
||||||
|
|
||||||
{ allow = ["AGPL-3.0-only"], name = "serai-coins-pallet" },
|
{ allow = ["AGPL-3.0-only"], name = "serai-coins-pallet" },
|
||||||
{ allow = ["AGPL-3.0-only"], name = "serai-dex-pallet" },
|
{ allow = ["AGPL-3.0-only"], name = "serai-dex-pallet" },
|
||||||
|
|
||||||
@@ -124,6 +126,10 @@ highlight = "all"
|
|||||||
deny = [
|
deny = [
|
||||||
{ name = "serde_derive", version = ">=1.0.172, <1.0.185" },
|
{ name = "serde_derive", version = ">=1.0.172, <1.0.185" },
|
||||||
{ name = "hashbrown", version = "=0.15.0" },
|
{ name = "hashbrown", version = "=0.15.0" },
|
||||||
|
# Legacy which _no one_ should use anymore
|
||||||
|
{ name = "is-terminal", version = "*" },
|
||||||
|
# Stop introduction into the tree without realizing it
|
||||||
|
{ name = "once_cell_polyfill", version = "*" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[sources]
|
[sources]
|
||||||
@@ -132,10 +138,10 @@ unknown-git = "deny"
|
|||||||
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
|
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
|
||||||
allow-git = [
|
allow-git = [
|
||||||
"https://github.com/rust-lang-nursery/lazy-static.rs",
|
"https://github.com/rust-lang-nursery/lazy-static.rs",
|
||||||
"https://github.com/kayabaNerve/hybrid-array",
|
|
||||||
"https://github.com/kayabaNerve/elliptic-curves",
|
"https://github.com/kayabaNerve/elliptic-curves",
|
||||||
"https://github.com/monero-oxide/monero-oxide",
|
"https://github.com/monero-oxide/monero-oxide",
|
||||||
"https://github.com/serai-dex/substrate-bip39",
|
"https://github.com/kayabaNerve/monero-oxide",
|
||||||
"https://github.com/serai-dex/substrate",
|
"https://github.com/rust-bitcoin/rust-bip39",
|
||||||
|
"https://github.com/rust-rocksdb/rust-rocksdb",
|
||||||
"https://github.com/serai-dex/patch-polkadot-sdk",
|
"https://github.com/serai-dex/patch-polkadot-sdk",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -238,8 +238,7 @@ async fn main() {
|
|||||||
// TODO: Add a magic value with a key at the start of the connection to make this authed
|
// TODO: Add a magic value with a key at the start of the connection to make this authed
|
||||||
let mut db = db.clone();
|
let mut db = db.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
loop {
|
while let Ok(msg_len) = socket.read_u32_le().await {
|
||||||
let Ok(msg_len) = socket.read_u32_le().await else { break };
|
|
||||||
let mut buf = vec![0; usize::try_from(msg_len).unwrap()];
|
let mut buf = vec![0; usize::try_from(msg_len).unwrap()];
|
||||||
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
||||||
let msg = borsh::from_slice(&buf).unwrap();
|
let msg = borsh::from_slice(&buf).unwrap();
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ 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"] }
|
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"] }
|
||||||
|
|
||||||
hex = { version = "0.4", default-features = false, optional = true }
|
hex = { version = "0.4", default-features = false, optional = true }
|
||||||
serde = { version = "1", default-features = false, features = ["derive"], optional = true }
|
core-json-traits = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
|
||||||
serde_json = { version = "1", default-features = false, optional = true }
|
core-json-derive = { version = "0.4", default-features = false, optional = true }
|
||||||
simple-request = { path = "../../common/request", version = "0.2", default-features = false, features = ["tls", "basic-auth"], optional = true }
|
simple-request = { path = "../../common/request", version = "0.3", default-features = false, features = ["tokio", "tls", "basic-auth"], optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
secp256k1 = { version = "0.29", default-features = false, features = ["std"] }
|
secp256k1 = { version = "0.29", default-features = false, features = ["std"] }
|
||||||
@@ -52,15 +52,16 @@ std = [
|
|||||||
"rand_core/std",
|
"rand_core/std",
|
||||||
|
|
||||||
"bitcoin/std",
|
"bitcoin/std",
|
||||||
"bitcoin/serde",
|
|
||||||
|
|
||||||
"k256/std",
|
"k256/std",
|
||||||
"frost/std",
|
"frost/std",
|
||||||
|
]
|
||||||
|
rpc = [
|
||||||
|
"std",
|
||||||
"hex/std",
|
"hex/std",
|
||||||
"serde/std",
|
"core-json-traits",
|
||||||
"serde_json/std",
|
"core-json-derive",
|
||||||
"simple-request",
|
"simple-request",
|
||||||
]
|
]
|
||||||
hazmat = []
|
hazmat = []
|
||||||
default = ["std"]
|
default = ["std", "rpc"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ pub(crate) mod crypto;
|
|||||||
/// Wallet functionality to create transactions.
|
/// Wallet functionality to create transactions.
|
||||||
pub mod wallet;
|
pub mod wallet;
|
||||||
/// A minimal asynchronous Bitcoin RPC client.
|
/// A minimal asynchronous Bitcoin RPC client.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "rpc")]
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
use core::fmt::Debug;
|
use core::{str::FromStr, fmt::Debug};
|
||||||
use std::collections::HashSet;
|
use std::{io::Read, collections::HashSet};
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use serde::{Deserialize, de::DeserializeOwned};
|
use simple_request::{hyper, Request, TokioClient as Client};
|
||||||
use serde_json::json;
|
|
||||||
|
|
||||||
use simple_request::{hyper, Request, Client};
|
|
||||||
|
|
||||||
use bitcoin::{
|
use bitcoin::{
|
||||||
hashes::{Hash, hex::FromHex},
|
hashes::{Hash, hex::FromHex},
|
||||||
@@ -14,19 +11,12 @@ use bitcoin::{
|
|||||||
Txid, Transaction, BlockHash, Block,
|
Txid, Transaction, BlockHash, Block,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Deserialize)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
code: isize,
|
code: isize,
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
enum RpcResponse<T> {
|
|
||||||
Ok { result: T },
|
|
||||||
Err { error: Error },
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A minimal asynchronous Bitcoin RPC client.
|
/// A minimal asynchronous Bitcoin RPC client.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Rpc {
|
pub struct Rpc {
|
||||||
@@ -34,14 +24,14 @@ pub struct Rpc {
|
|||||||
url: String,
|
url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Error)]
|
#[derive(Clone, Debug, Error)]
|
||||||
pub enum RpcError {
|
pub enum RpcError {
|
||||||
#[error("couldn't connect to node")]
|
#[error("couldn't connect to node")]
|
||||||
ConnectionError,
|
ConnectionError,
|
||||||
#[error("request had an error: {0:?}")]
|
#[error("request had an error: {0:?}")]
|
||||||
RequestError(Error),
|
RequestError(Error),
|
||||||
#[error("node replied with invalid JSON")]
|
#[error("node replied with invalid JSON")]
|
||||||
InvalidJson(serde_json::error::Category),
|
InvalidJson,
|
||||||
#[error("node sent an invalid response ({0})")]
|
#[error("node sent an invalid response ({0})")]
|
||||||
InvalidResponse(&'static str),
|
InvalidResponse(&'static str),
|
||||||
#[error("node was missing expected methods")]
|
#[error("node was missing expected methods")]
|
||||||
@@ -66,7 +56,7 @@ impl Rpc {
|
|||||||
Rpc { client: Client::with_connection_pool().map_err(|_| RpcError::ConnectionError)?, url };
|
Rpc { client: Client::with_connection_pool().map_err(|_| RpcError::ConnectionError)?, url };
|
||||||
|
|
||||||
// Make an RPC request to verify the node is reachable and sane
|
// 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
|
// 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
|
// If we had a more expanded RPC, due to differences in RPC versions, it wouldn't make sense to
|
||||||
@@ -103,22 +93,21 @@ impl Rpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an arbitrary RPC call.
|
/// 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,
|
&self,
|
||||||
method: &str,
|
method: &str,
|
||||||
params: serde_json::Value,
|
params: &str,
|
||||||
) -> Result<Response, RpcError> {
|
) -> Result<Response, RpcError> {
|
||||||
let mut request = Request::from(
|
let mut request = Request::from(
|
||||||
hyper::Request::post(&self.url)
|
hyper::Request::post(&self.url)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.body(
|
.body(
|
||||||
serde_json::to_vec(&json!({ "jsonrpc": "2.0", "method": method, "params": params }))
|
format!(r#"{{ "method": "{method}", "params": {params} }}"#).as_bytes().to_vec().into(),
|
||||||
.unwrap()
|
|
||||||
.into(),
|
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
request.with_basic_auth();
|
request.with_basic_auth();
|
||||||
|
request.set_response_size_limit(Some(100 * 1024 * 1024));
|
||||||
let mut res = self
|
let mut res = self
|
||||||
.client
|
.client
|
||||||
.request(request)
|
.request(request)
|
||||||
@@ -128,11 +117,52 @@ impl Rpc {
|
|||||||
.await
|
.await
|
||||||
.map_err(|_| RpcError::ConnectionError)?;
|
.map_err(|_| RpcError::ConnectionError)?;
|
||||||
|
|
||||||
let res: RpcResponse<Response> =
|
#[derive(Default, core_json_derive::JsonDeserialize)]
|
||||||
serde_json::from_reader(&mut res).map_err(|e| RpcError::InvalidJson(e.classify()))?;
|
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 {
|
match res {
|
||||||
RpcResponse::Ok { result } => Ok(result),
|
RpcResponse { result: Some(result), error: None } => Ok(result),
|
||||||
RpcResponse::Err { error } => Err(RpcError::RequestError(error)),
|
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")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,16 +175,17 @@ impl Rpc {
|
|||||||
// tip block of the current chain. The "height" of a block is defined as the amount of blocks
|
// 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
|
// 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.
|
// 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.
|
/// Get the hash of a block by the block's number.
|
||||||
pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> {
|
pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> {
|
||||||
let mut hash = self
|
let mut hash =
|
||||||
.rpc_call::<BlockHash>("getblockhash", json!([number]))
|
BlockHash::from_str(&self.call::<String>("getblockhash", &format!("[{number}]")).await?)
|
||||||
.await?
|
.map_err(|_| RpcError::InvalidResponse("block hash was not valid hex"))?
|
||||||
.as_raw_hash()
|
.as_raw_hash()
|
||||||
.to_byte_array();
|
.to_byte_array();
|
||||||
// bitcoin stores the inner bytes in reverse order.
|
// bitcoin stores the inner bytes in reverse order.
|
||||||
hash.reverse();
|
hash.reverse();
|
||||||
Ok(hash)
|
Ok(hash)
|
||||||
@@ -162,16 +193,25 @@ impl Rpc {
|
|||||||
|
|
||||||
/// Get a block's number by its hash.
|
/// Get a block's number by its hash.
|
||||||
pub async fn get_block_number(&self, hash: &[u8; 32]) -> Result<usize, RpcError> {
|
pub async fn get_block_number(&self, hash: &[u8; 32]) -> Result<usize, RpcError> {
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Default, core_json_derive::JsonDeserialize)]
|
||||||
struct Number {
|
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.
|
/// Get a block by its hash.
|
||||||
pub async fn get_block(&self, hash: &[u8; 32]) -> Result<Block, RpcError> {
|
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)
|
let bytes: Vec<u8> = FromHex::from_hex(&hex)
|
||||||
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the block"))?;
|
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the block"))?;
|
||||||
let block: Block = encode::deserialize(&bytes)
|
let block: Block = encode::deserialize(&bytes)
|
||||||
@@ -188,8 +228,13 @@ impl Rpc {
|
|||||||
|
|
||||||
/// Publish a transaction.
|
/// Publish a transaction.
|
||||||
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<Txid, RpcError> {
|
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 {
|
let txid = match self
|
||||||
Ok(txid) => txid,
|
.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) => {
|
Err(e) => {
|
||||||
// A const from Bitcoin's bitcoin/src/rpc/protocol.h
|
// A const from Bitcoin's bitcoin/src/rpc/protocol.h
|
||||||
const RPC_VERIFY_ALREADY_IN_CHAIN: isize = -27;
|
const RPC_VERIFY_ALREADY_IN_CHAIN: isize = -27;
|
||||||
@@ -210,7 +255,8 @@ impl Rpc {
|
|||||||
|
|
||||||
/// Get a transaction by its hash.
|
/// Get a transaction by its hash.
|
||||||
pub async fn get_transaction(&self, hash: &[u8; 32]) -> Result<Transaction, RpcError> {
|
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)
|
let bytes: Vec<u8> = FromHex::from_hex(&hex)
|
||||||
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the transaction"))?;
|
.map_err(|_| RpcError::InvalidResponse("node didn't use hex to encode the transaction"))?;
|
||||||
let tx: Transaction = encode::deserialize(&bytes)
|
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 this node has already been interacted with, clear its chain
|
||||||
if rpc.get_latest_block_number().await.unwrap() > 0 {
|
if rpc.get_latest_block_number().await.unwrap() > 0 {
|
||||||
rpc
|
rpc
|
||||||
.rpc_call(
|
.call(
|
||||||
"invalidateblock",
|
"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
|
.await
|
||||||
.unwrap()
|
.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;
|
let block_number = rpc.get_latest_block_number().await.unwrap() + 1;
|
||||||
|
|
||||||
rpc
|
rpc
|
||||||
.rpc_call::<Vec<String>>(
|
.call::<Vec<String>>(
|
||||||
"generatetoaddress",
|
"generatetoaddress",
|
||||||
serde_json::json!([
|
&format!(
|
||||||
1,
|
r#"[1, "{}"]"#,
|
||||||
Address::from_script(&p2tr_script_buf(key).unwrap(), Network::Regtest).unwrap()
|
Address::from_script(&p2tr_script_buf(key).unwrap(), Network::Regtest).unwrap()
|
||||||
]),
|
),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Mine until maturity
|
// Mine until maturity
|
||||||
rpc
|
rpc
|
||||||
.rpc_call::<Vec<String>>(
|
.call::<Vec<String>>(
|
||||||
"generatetoaddress",
|
"generatetoaddress",
|
||||||
serde_json::json!([100, Address::p2sh(Script::new(), Network::Regtest).unwrap()]),
|
&format!(r#"[100, "{}"]"#, Address::p2sh(Script::new(), Network::Regtest).unwrap()),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ workspace = true
|
|||||||
tower = "0.5"
|
tower = "0.5"
|
||||||
|
|
||||||
serde_json = { version = "1", default-features = false }
|
serde_json = { version = "1", default-features = false }
|
||||||
simple-request = { path = "../../../common/request", version = "0.2", default-features = false }
|
simple-request = { path = "../../../common/request", version = "0.3", default-features = false, features = ["tokio"] }
|
||||||
|
|
||||||
alloy-json-rpc = { version = "1", default-features = false }
|
alloy-json-rpc = { version = "1", default-features = false }
|
||||||
alloy-transport = { version = "1", default-features = false }
|
alloy-transport = { version = "1", default-features = false }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
use core::task;
|
use core::task;
|
||||||
@@ -7,7 +7,7 @@ use std::io;
|
|||||||
use alloy_json_rpc::{RequestPacket, ResponsePacket};
|
use alloy_json_rpc::{RequestPacket, ResponsePacket};
|
||||||
use alloy_transport::{TransportError, TransportErrorKind, TransportFut};
|
use alloy_transport::{TransportError, TransportErrorKind, TransportFut};
|
||||||
|
|
||||||
use simple_request::{hyper, Error, Request, Client};
|
use simple_request::{hyper, Error, Request, TokioClient as Client};
|
||||||
|
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ use std::{path::PathBuf, fs, process::Command};
|
|||||||
|
|
||||||
/// Build contracts from the specified path, outputting the artifacts to the specified path.
|
/// 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(
|
pub fn build(
|
||||||
include_paths: &[&str],
|
include_paths: &[&str],
|
||||||
contracts_path: &str,
|
contracts_path: &str,
|
||||||
@@ -35,8 +35,8 @@ pub fn build(
|
|||||||
if let Some(version) = line.strip_prefix("Version: ") {
|
if let Some(version) = line.strip_prefix("Version: ") {
|
||||||
let version =
|
let version =
|
||||||
version.split('+').next().ok_or_else(|| "no value present on line".to_string())?;
|
version.split('+').next().ok_or_else(|| "no value present on line".to_string())?;
|
||||||
if version != "0.8.26" {
|
if version != "0.8.29" {
|
||||||
Err(format!("version was {version}, 0.8.26 required"))?
|
Err(format!("version was {version}, 0.8.29 required"))?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ async fn main() {
|
|||||||
let db = db.clone();
|
let db = db.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut db = db.clone();
|
let mut db = db.clone();
|
||||||
loop {
|
while let Ok(msg_len) = socket.read_u32_le().await {
|
||||||
let Ok(msg_len) = socket.read_u32_le().await else { break };
|
|
||||||
let mut buf = vec![0; usize::try_from(msg_len).unwrap()];
|
let mut buf = vec![0; usize::try_from(msg_len).unwrap()];
|
||||||
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
let Ok(_) = socket.read_exact(&mut buf).await else { break };
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
subtle = { version = "2", default-features = false, features = ["std"] }
|
std-shims = { path = "../../../common/std-shims", version = "0.1", default-features = false }
|
||||||
sha3 = { version = "0.10", default-features = false, features = ["std"] }
|
|
||||||
group = { version = "0.13", default-features = false, features = ["alloc"] }
|
subtle = { version = "2", default-features = false }
|
||||||
k256 = { version = "^0.13.1", default-features = false, features = ["std", "arithmetic"] }
|
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-dependencies]
|
||||||
build-solidity-contracts = { path = "../build-contracts", version = "0.1" }
|
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 }
|
alloy-node-bindings = { version = "1", default-features = false }
|
||||||
|
|
||||||
tokio = { version = "1", default-features = false, features = ["macros"] }
|
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
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
pragma solidity ^0.8.26;
|
pragma solidity ^0.8.29;
|
||||||
|
|
||||||
/// @title A library for verifying Schnorr signatures
|
/// @title A library for verifying Schnorr signatures
|
||||||
/// @author Luke Parker <lukeparker@serai.exchange>
|
/// @author Luke Parker <lukeparker@serai.exchange>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
pragma solidity ^0.8.26;
|
pragma solidity ^0.8.29;
|
||||||
|
|
||||||
import "../Schnorr.sol";
|
import "../Schnorr.sol";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
mod public_key;
|
mod public_key;
|
||||||
pub use public_key::PublicKey;
|
pub use public_key::PublicKey;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::io;
|
use std_shims::io;
|
||||||
|
|
||||||
use sha3::{Digest, Keccak256};
|
use sha3::{Digest, Keccak256};
|
||||||
|
|
||||||
@@ -77,6 +77,7 @@ impl Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write the signature.
|
/// Write the signature.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
pub fn write(&self, writer: &mut impl io::Write) -> io::Result<()> {
|
||||||
writer.write_all(&self.to_bytes())
|
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)
|
# rust:1.91.1-alpine as of November 11th, 2025 (GMT)
|
||||||
FROM --platform=linux/amd64 rust@sha256:703cfb0f80db8eb8a3452bf5151162472039c1b37fe4fb2957b495a6f0104ae7 AS deterministic
|
FROM --platform=linux/amd64 rust@sha256:700c0959b23445f69c82676b72caa97ca4359decd075dca55b13339df27dc4d3 AS deterministic
|
||||||
|
|
||||||
# Move to a Debian package snapshot
|
RUN apk add musl-dev=1.2.5-r10
|
||||||
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
|
|
||||||
|
|
||||||
# Add the wasm toolchain
|
# Add the wasm toolchain
|
||||||
RUN rustup target add wasm32v1-none
|
RUN rustup target add wasm32v1-none
|
||||||
@@ -35,6 +28,7 @@ ADD AGPL-3.0 /serai
|
|||||||
WORKDIR /serai
|
WORKDIR /serai
|
||||||
|
|
||||||
# Build the runtime, copying it to the volume if it exists
|
# Build the runtime, copying it to the volume if it exists
|
||||||
|
ENV RUSTFLAGS="-Ctarget-feature=-crt-static"
|
||||||
CMD cargo build --release -p serai-runtime && \
|
CMD cargo build --release -p serai-runtime && \
|
||||||
mkdir -p /volume && \
|
mkdir -p /volume && \
|
||||||
cp /serai/target/release/wbuild/serai-runtime/serai_runtime.wasm /volume/serai.wasm
|
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() +
|
let setup = mimalloc(Os::Debian).to_string() +
|
||||||
&build_serai_service(
|
&build_serai_service(
|
||||||
"",
|
"",
|
||||||
|
Os::Debian,
|
||||||
network.release(),
|
network.release(),
|
||||||
&format!("{db} {longer_reattempts}"),
|
&format!("{db} {longer_reattempts}"),
|
||||||
"serai-coordinator",
|
"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) {
|
pub fn ethereum_relayer(orchestration_path: &Path, network: Network) {
|
||||||
let setup = mimalloc(Os::Debian).to_string() +
|
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 = [
|
let env_vars = [
|
||||||
("DB_PATH", "/volume/ethereum-relayer-db".to_string()),
|
("DB_PATH", "/volume/ethereum-relayer-db".to_string()),
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ WORKDIR /home/{user}
|
|||||||
|
|
||||||
Os::Debian => format!(
|
Os::Debian => format!(
|
||||||
r#"
|
r#"
|
||||||
FROM debian:bookworm-slim AS image
|
FROM debian:trixie-slim AS image
|
||||||
|
|
||||||
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
||||||
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
||||||
@@ -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 = if release { "release" } else { "debug" };
|
||||||
let profile_flag = if release { "--release" } else { "" };
|
let profile_flag = if release { "--release" } else { "" };
|
||||||
|
|
||||||
format!(
|
(match os {
|
||||||
r#"
|
Os::Debian => {
|
||||||
FROM rust:1.90-slim-bookworm AS builder
|
r#"
|
||||||
|
FROM rust:1.91-slim-trixie AS builder
|
||||||
|
|
||||||
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
||||||
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
||||||
@@ -157,11 +164,29 @@ RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
|||||||
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
|
RUN apt update && apt upgrade -y && apt autoremove -y && apt clean
|
||||||
|
|
||||||
# Add dev dependencies
|
# Add dev dependencies
|
||||||
RUN apt install -y pkg-config clang
|
RUN apt install -y pkg-config libclang-dev clang
|
||||||
|
|
||||||
# Dependencies for the Serai node
|
# Dependencies for the Serai node
|
||||||
RUN apt install -y make protobuf-compiler
|
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
|
# Add the wasm toolchain
|
||||||
RUN rustup target add wasm32v1-none
|
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} && \
|
cargo build {profile_flag} --features "{features}" -p {package} && \
|
||||||
mv /serai/target/{profile}/{package} /serai/bin
|
mv /serai/target/{profile}/{package} /serai/bin
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_dockerfile(path: PathBuf, dockerfile: &str) {
|
pub fn write_dockerfile(path: PathBuf, dockerfile: &str) {
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ pub fn message_queue(
|
|||||||
ethereum_key: <Ristretto as WrappedGroup>::G,
|
ethereum_key: <Ristretto as WrappedGroup>::G,
|
||||||
monero_key: <Ristretto as WrappedGroup>::G,
|
monero_key: <Ristretto as WrappedGroup>::G,
|
||||||
) {
|
) {
|
||||||
let setup = mimalloc(Os::Debian).to_string() +
|
let setup = mimalloc(Os::Alpine).to_string() +
|
||||||
&build_serai_service("", network.release(), network.db(), "serai-message-queue");
|
&build_serai_service("", Os::Alpine, network.release(), network.db(), "serai-message-queue");
|
||||||
|
|
||||||
let env_vars = [
|
let env_vars = [
|
||||||
("COORDINATOR_KEY", hex::encode(coordinator_key.to_bytes())),
|
("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 res = setup + &run;
|
||||||
|
|
||||||
let mut message_queue_path = orchestration_path.to_path_buf();
|
let mut message_queue_path = orchestration_path.to_path_buf();
|
||||||
|
|||||||
@@ -7,24 +7,24 @@ FROM alpine:latest AS mimalloc-alpine
|
|||||||
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
|
RUN apk update && apk upgrade && apk --no-cache add gcc g++ libc-dev make cmake git
|
||||||
RUN git clone https://github.com/microsoft/mimalloc && \
|
RUN git clone https://github.com/microsoft/mimalloc && \
|
||||||
cd mimalloc && \
|
cd mimalloc && \
|
||||||
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
|
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
|
||||||
mkdir -p out/secure && \
|
mkdir -p out/secure && \
|
||||||
cd out/secure && \
|
cd out/secure && \
|
||||||
cmake -DMI_SECURE=ON ../.. && \
|
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
|
||||||
make && \
|
make && \
|
||||||
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
const DEBIAN_MIMALLOC: &str = r#"
|
const DEBIAN_MIMALLOC: &str = r#"
|
||||||
FROM debian:bookworm-slim AS mimalloc-debian
|
FROM debian:trixie-slim AS mimalloc-debian
|
||||||
|
|
||||||
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
|
RUN apt update && apt upgrade -y && apt install -y gcc g++ make cmake git
|
||||||
RUN git clone https://github.com/microsoft/mimalloc && \
|
RUN git clone https://github.com/microsoft/mimalloc && \
|
||||||
cd mimalloc && \
|
cd mimalloc && \
|
||||||
git checkout 43ce4bd7fd34bcc730c1c7471c99995597415488 && \
|
git checkout fbd8b99c2b828428947d70fdc046bb55609be93e && \
|
||||||
mkdir -p out/secure && \
|
mkdir -p out/secure && \
|
||||||
cd out/secure && \
|
cd out/secure && \
|
||||||
cmake -DMI_SECURE=ON ../.. && \
|
cmake -DMI_SECURE=ON -DMI_GUARDED=on ../.. && \
|
||||||
make && \
|
make && \
|
||||||
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
cp ./libmimalloc-secure.so ../../../libmimalloc.so
|
||||||
"#;
|
"#;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ pub fn bitcoin(orchestration_path: &Path, network: Network) {
|
|||||||
const DOWNLOAD_BITCOIN: &str = r#"
|
const DOWNLOAD_BITCOIN: &str = r#"
|
||||||
FROM alpine:latest AS bitcoin
|
FROM alpine:latest AS bitcoin
|
||||||
|
|
||||||
ENV BITCOIN_VERSION=29.1
|
ENV BITCOIN_VERSION=30.0
|
||||||
|
|
||||||
RUN apk --no-cache add wget git gnupg
|
RUN apk --no-cache add wget git gnupg
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fn monero_internal(
|
|||||||
monero_binary: &str,
|
monero_binary: &str,
|
||||||
ports: &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 {
|
let arch = match std::env::consts::ARCH {
|
||||||
// We probably would run this without issues yet it's not worth needing to provide support for
|
// 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" {
|
if coin == "ethereum" {
|
||||||
r#"
|
r#"
|
||||||
RUN cargo install svm-rs
|
RUN cargo install svm-rs
|
||||||
RUN svm install 0.8.26
|
RUN svm install 0.8.29
|
||||||
RUN svm use 0.8.26
|
RUN svm use 0.8.29
|
||||||
"#
|
"#
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
|
Os::Debian,
|
||||||
network.release(),
|
network.release(),
|
||||||
&format!("binaries {} {coin}", network.db()),
|
&format!("binaries {} {coin}", network.db()),
|
||||||
"serai-processor",
|
"serai-processor",
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ pub fn serai(
|
|||||||
serai_key: &Zeroizing<<Ristretto as WrappedGroup>::F>,
|
serai_key: &Zeroizing<<Ristretto as WrappedGroup>::F>,
|
||||||
) {
|
) {
|
||||||
// Always builds in release for performance reasons
|
// Always builds in release for performance reasons
|
||||||
let setup = mimalloc(Os::Debian).to_string() + &build_serai_service("", true, "", "serai-node");
|
let setup =
|
||||||
let setup_fast_epoch =
|
mimalloc(Os::Debian).to_string() + &build_serai_service("", Os::Debian, true, "", "serai-node");
|
||||||
mimalloc(Os::Debian).to_string() + &build_serai_service("", true, "fast-epoch", "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 env_vars = [("KEY", hex::encode(serai_key.to_repr()))];
|
||||||
let mut env_vars_str = String::new();
|
let mut env_vars_str = String::new();
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ crypto-bigint = { version = "0.6", default-features = false, features = ["zeroiz
|
|||||||
prime-field = { path = "../../crypto/prime-field", default-features = false }
|
prime-field = { path = "../../crypto/prime-field", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = ["dalek-ff-group/alloc", "crypto-bigint-05/alloc", "crypto-bigint/alloc", "prime-field/alloc"]
|
alloc = ["dalek-ff-group/alloc", "prime-field/alloc"]
|
||||||
std = ["alloc", "dalek-ff-group/std", "prime-field/std"]
|
std = ["alloc", "dalek-ff-group/std", "prime-field/std"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![no_std] // Prevents writing new code, in what should be a simple wrapper, which requires std
|
#![no_std] // Prevents writing new code, in what should be a simple wrapper, which requires std
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![allow(clippy::redundant_closure_call)]
|
#![allow(clippy::redundant_closure_call)]
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "zstd"
|
name = "darling"
|
||||||
version = "0.11.2+zstd.1.5.2"
|
version = "0.20.99"
|
||||||
description = "zstd which patches to the latest update"
|
description = "Patch to the latest version"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/zstd"
|
repository = "https://github.com/serai-dex/serai/tree/develop/patches/darling"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
keywords = []
|
keywords = []
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -13,4 +13,4 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
zstd = "0.13"
|
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::*;
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "is-terminal"
|
name = "ark-ff"
|
||||||
version = "0.4.10"
|
version = "0.3.99"
|
||||||
description = "is-terminal written around std::io::IsTerminal"
|
description = "Patch to an empty crate"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/is-terminal"
|
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/ark-ff-0.3"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
keywords = []
|
keywords = []
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.70"
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
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];
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "matches"
|
name = "ark-ff"
|
||||||
version = "0.1.10"
|
version = "0.4.99"
|
||||||
description = "Replacement for the matches polyfill which uses the std impl"
|
description = "Patch to an empty crate"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/patches/matches"
|
repository = "https://github.com/serai-dex/serai/tree/develop/patches/ethereum/ark-ff-0.4"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
keywords = []
|
keywords = []
|
||||||
edition = "2018"
|
edition = "2021"
|
||||||
rust-version = "1.42"
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
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 = []
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user