mirror of
https://github.com/serai-dex/serai.git
synced 2025-03-12 09:26:51 +00:00
Merge branch 'develop' into tendermint
This commit is contained in:
commit
cc8284ad40
80 changed files with 2727 additions and 1241 deletions
|
@ -21,7 +21,7 @@ runs:
|
|||
- name: Install solc
|
||||
shell: bash
|
||||
run: |
|
||||
pip3 install solc-select
|
||||
pip3 install solc-select==0.2.1
|
||||
solc-select install 0.8.16
|
||||
solc-select use 0.8.16
|
||||
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
|||
[submodule "coins/monero/c/monero"]
|
||||
path = coins/monero/c/monero
|
||||
url = https://github.com/monero-project/monero
|
|
@ -17,6 +17,7 @@ form of code and documentation.
|
|||
|
||||
- Only use uppercase variable names when relevant to cryptography.
|
||||
|
||||
- Use a two-space ident when possible.
|
||||
- Put a space after comment markers.
|
||||
- Don't use multiple newlines between sections of code.
|
||||
- Have a newline before EOF.
|
||||
|
|
1414
Cargo.lock
generated
1414
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -44,6 +44,3 @@ monero-serai = { opt-level = 3 }
|
|||
|
||||
[profile.release]
|
||||
panic = "unwind"
|
||||
|
||||
[patch.crates-io]
|
||||
zip = { version = "0.6.2", git = "https://github.com/zip-rs/zip", rev = "bb230ef56adc13436d1fcdfaa489249d119c498f" }
|
||||
|
|
|
@ -3,8 +3,14 @@ name = "ethereum-serai"
|
|||
version = "0.1.0"
|
||||
description = "An Ethereum library supporting Schnorr signing and on-chain verification"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/coins/ethereum"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>", "Elizabeth Binks <elizabethjbinks@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
hex-literal = "0.3"
|
||||
|
@ -24,8 +30,8 @@ eyre = "0.6"
|
|||
|
||||
ethers = { version = "0.14", features = ["abigen", "ethers-solc"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["macros"] }
|
||||
|
||||
[build-dependencies]
|
||||
ethers-solc = "0.14"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["macros"] }
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "monero-serai"
|
|||
version = "0.1.1-alpha"
|
||||
description = "A modern Monero transaction library"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/coins/monero"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
|
@ -48,12 +48,14 @@ monero-epee-bin-serde = "1.0"
|
|||
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
|
||||
[features]
|
||||
multisig = ["rand_chacha", "blake2", "transcript", "frost", "dleq"]
|
||||
|
||||
[build-dependencies]
|
||||
dalek-ff-group = { path = "../../crypto/dalek-ff-group", version = "0.1" }
|
||||
monero-generators = { path = "generators", version = "0.1" }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.2", features = ["ed25519", "tests"] }
|
||||
|
||||
[features]
|
||||
multisig = ["rand_chacha", "blake2", "transcript", "frost", "dleq"]
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "monero-generators"
|
|||
version = "0.1.1"
|
||||
description = "Monero's hash_to_point and generators"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/coins/monero/generators"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
@ -23,12 +23,28 @@ pub struct JsonRpcResponse<T> {
|
|||
result: T,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct TransactionResponse {
|
||||
tx_hash: String,
|
||||
block_height: usize,
|
||||
as_hex: String,
|
||||
pruned_as_hex: String,
|
||||
}
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct TransactionsResponse {
|
||||
#[serde(default)]
|
||||
missed_tx: Vec<String>,
|
||||
txs: Vec<TransactionResponse>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Error, Debug)]
|
||||
pub enum RpcError {
|
||||
#[error("internal error ({0})")]
|
||||
InternalError(String),
|
||||
#[error("connection error")]
|
||||
ConnectionError,
|
||||
#[error("invalid node")]
|
||||
InvalidNode,
|
||||
#[error("transactions not found")]
|
||||
TransactionsNotFound(Vec<[u8; 32]>),
|
||||
#[error("invalid point ({0})")]
|
||||
|
@ -40,7 +56,11 @@ pub enum RpcError {
|
|||
}
|
||||
|
||||
fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
|
||||
hex::decode(value).map_err(|_| RpcError::InternalError("Monero returned invalid hex".to_string()))
|
||||
hex::decode(value).map_err(|_| RpcError::InvalidNode)
|
||||
}
|
||||
|
||||
fn hash_hex(hash: &str) -> Result<[u8; 32], RpcError> {
|
||||
rpc_hex(hash)?.try_into().map_err(|_| RpcError::InvalidNode)
|
||||
}
|
||||
|
||||
fn rpc_point(point: &str) -> Result<EdwardsPoint, RpcError> {
|
||||
|
@ -149,19 +169,6 @@ impl Rpc {
|
|||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct TransactionResponse {
|
||||
tx_hash: String,
|
||||
as_hex: String,
|
||||
pruned_as_hex: String,
|
||||
}
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct TransactionsResponse {
|
||||
#[serde(default)]
|
||||
missed_tx: Vec<String>,
|
||||
txs: Vec<TransactionResponse>,
|
||||
}
|
||||
|
||||
let txs: TransactionsResponse = self
|
||||
.rpc_call(
|
||||
"get_transactions",
|
||||
|
@ -173,7 +180,7 @@ impl Rpc {
|
|||
|
||||
if !txs.missed_tx.is_empty() {
|
||||
Err(RpcError::TransactionsNotFound(
|
||||
txs.missed_tx.iter().map(|hash| hex::decode(hash).unwrap().try_into().unwrap()).collect(),
|
||||
txs.missed_tx.iter().map(|hash| hash_hex(hash)).collect::<Result<_, _>>()?,
|
||||
))?;
|
||||
}
|
||||
|
||||
|
@ -181,11 +188,12 @@ impl Rpc {
|
|||
.txs
|
||||
.iter()
|
||||
.map(|res| {
|
||||
let tx = Transaction::deserialize(&mut std::io::Cursor::new(
|
||||
rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex }).unwrap(),
|
||||
))
|
||||
.map_err(|_| {
|
||||
RpcError::InvalidTransaction(hex::decode(&res.tx_hash).unwrap().try_into().unwrap())
|
||||
let tx = Transaction::deserialize(&mut std::io::Cursor::new(rpc_hex(
|
||||
if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex },
|
||||
)?))
|
||||
.map_err(|_| match hash_hex(&res.tx_hash) {
|
||||
Ok(hash) => RpcError::InvalidTransaction(hash),
|
||||
Err(err) => err,
|
||||
})?;
|
||||
|
||||
// https://github.com/monero-project/monero/issues/8311
|
||||
|
@ -205,6 +213,19 @@ impl Rpc {
|
|||
self.get_transactions(&[tx]).await.map(|mut txs| txs.swap_remove(0))
|
||||
}
|
||||
|
||||
pub async fn get_transaction_block_number(&self, tx: &[u8]) -> Result<usize, RpcError> {
|
||||
let txs: TransactionsResponse =
|
||||
self.rpc_call("get_transactions", Some(json!({ "txs_hashes": [hex::encode(tx)] }))).await?;
|
||||
|
||||
if !txs.missed_tx.is_empty() {
|
||||
Err(RpcError::TransactionsNotFound(
|
||||
txs.missed_tx.iter().map(|hash| hash_hex(hash)).collect::<Result<_, _>>()?,
|
||||
))?;
|
||||
}
|
||||
|
||||
Ok(txs.txs[0].block_height)
|
||||
}
|
||||
|
||||
pub async fn get_block(&self, height: usize) -> Result<Block, RpcError> {
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct BlockResponse {
|
||||
|
|
|
@ -3,10 +3,15 @@ name = "serai-extension"
|
|||
version = "0.1.0"
|
||||
description = "An ink! extension for exposing Serai to ink"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/contracts/extension"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||
|
||||
|
|
|
@ -3,10 +3,20 @@ name = "serai-multisig"
|
|||
version = "0.1.0"
|
||||
description = "An ink! tracker for Serai's current multisig"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/contracts/multisig"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[lib]
|
||||
name = "serai_multisig"
|
||||
path = "lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2", default-features = false, features = ["derive"], optional = true }
|
||||
|
@ -22,11 +32,6 @@ serai-extension = { path = "../extension", default-features = false }
|
|||
[dev-dependencies]
|
||||
lazy_static = "1"
|
||||
|
||||
[lib]
|
||||
name = "serai_multisig"
|
||||
path = "lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "dalek-ff-group"
|
|||
version = "0.1.5"
|
||||
description = "ff/group bindings around curve25519-dalek"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/dalek-ff-group"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["curve25519", "ed25519", "ristretto", "dalek", "group"]
|
||||
edition = "2021"
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "dleq"
|
|||
version = "0.1.1"
|
||||
description = "Implementation of single and cross-curve Discrete Log Equality proofs"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/dleq"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "minimal-ed448"
|
|||
version = "0.1.1"
|
||||
description = "Unaudited, inefficient implementation of Ed448 in Rust"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/ed448"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["ed448", "ff", "group"]
|
||||
edition = "2021"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "modular-frost"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
description = "Modular implementation of FROST over ff/group"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/frost"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["frost", "multisig", "threshold"]
|
||||
edition = "2021"
|
||||
|
@ -18,6 +18,7 @@ thiserror = "1"
|
|||
rand_core = "0.6"
|
||||
|
||||
zeroize = { version = "1.5", features = ["zeroize_derive"] }
|
||||
subtle = "2"
|
||||
|
||||
hex = "0.4"
|
||||
|
||||
|
@ -44,6 +45,7 @@ dleq = { path = "../dleq", version = "0.1", features = ["serialize"] }
|
|||
[dev-dependencies]
|
||||
sha2 = "0.10"
|
||||
dalek-ff-group = { path = "../dalek-ff-group", version = "^0.1.2" }
|
||||
serde_json = "1"
|
||||
|
||||
[features]
|
||||
dalek = ["sha2", "dalek-ff-group"]
|
||||
|
@ -55,3 +57,5 @@ p256 = ["kp256", "dep:p256"]
|
|||
secp256k1 = ["kp256", "k256"]
|
||||
|
||||
ed448 = ["sha3", "minimal-ed448"]
|
||||
|
||||
tests = []
|
||||
|
|
|
@ -74,7 +74,7 @@ dalek_curve!(
|
|||
IetfRistrettoHram,
|
||||
RistrettoPoint,
|
||||
b"ristretto",
|
||||
b"FROST-RISTRETTO255-SHA512-v10",
|
||||
b"FROST-RISTRETTO255-SHA512-v11",
|
||||
b"chal",
|
||||
);
|
||||
|
||||
|
@ -85,6 +85,6 @@ dalek_curve!(
|
|||
IetfEd25519Hram,
|
||||
EdwardsPoint,
|
||||
b"edwards25519",
|
||||
b"FROST-ED25519-SHA512-v10",
|
||||
b"FROST-ED25519-SHA512-v11",
|
||||
b"",
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ use minimal_ed448::{scalar::Scalar, point::Point};
|
|||
|
||||
use crate::{curve::Curve, algorithm::Hram};
|
||||
|
||||
const CONTEXT: &[u8] = b"FROST-ED448-SHAKE256-v10";
|
||||
const CONTEXT: &[u8] = b"FROST-ED448-SHAKE256-v11";
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||
pub struct Ed448;
|
||||
|
@ -53,8 +53,8 @@ impl Ietf8032Ed448Hram {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NonIetfEd448Hram;
|
||||
impl Hram<Ed448> for NonIetfEd448Hram {
|
||||
pub struct IetfEd448Hram;
|
||||
impl Hram<Ed448> for IetfEd448Hram {
|
||||
#[allow(non_snake_case)]
|
||||
fn hram(R: &Point, A: &Point, m: &[u8]) -> Scalar {
|
||||
Ietf8032Ed448Hram::hram(&[], R, A, m)
|
||||
|
|
|
@ -92,7 +92,7 @@ macro_rules! kp_curve {
|
|||
}
|
||||
|
||||
#[cfg(feature = "p256")]
|
||||
kp_curve!("p256", p256, P256, IetfP256Hram, b"P-256", b"FROST-P256-SHA256-v10");
|
||||
kp_curve!("p256", p256, P256, IetfP256Hram, b"P-256", b"FROST-P256-SHA256-v11");
|
||||
|
||||
#[cfg(feature = "secp256k1")]
|
||||
kp_curve!(
|
||||
|
@ -101,5 +101,5 @@ kp_curve!(
|
|||
Secp256k1,
|
||||
IetfSecp256k1Hram,
|
||||
b"secp256k1",
|
||||
b"FROST-secp256k1-SHA256-v10"
|
||||
b"FROST-secp256k1-SHA256-v11"
|
||||
);
|
||||
|
|
|
@ -6,8 +6,9 @@ use thiserror::Error;
|
|||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use zeroize::Zeroize;
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use ff::{PrimeField, PrimeFieldBits};
|
||||
use ff::{Field, PrimeField, PrimeFieldBits};
|
||||
use group::{Group, GroupOps, GroupEncoding, prime::PrimeGroup};
|
||||
|
||||
#[cfg(any(test, feature = "dalek"))]
|
||||
|
@ -27,7 +28,7 @@ pub use kp256::{P256, IetfP256Hram};
|
|||
#[cfg(feature = "ed448")]
|
||||
mod ed448;
|
||||
#[cfg(feature = "ed448")]
|
||||
pub use ed448::{Ed448, Ietf8032Ed448Hram, NonIetfEd448Hram};
|
||||
pub use ed448::{Ed448, Ietf8032Ed448Hram, IetfEd448Hram};
|
||||
|
||||
/// Set of errors for curve-related operations, namely encoding and decoding.
|
||||
#[derive(Clone, Error, Debug)]
|
||||
|
@ -49,7 +50,7 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
// This is available via G::Scalar yet `C::G::Scalar` is ambiguous, forcing horrific accesses
|
||||
type F: PrimeField + PrimeFieldBits + Zeroize;
|
||||
/// Group element type.
|
||||
type G: Group<Scalar = Self::F> + GroupOps + PrimeGroup + Zeroize;
|
||||
type G: Group<Scalar = Self::F> + GroupOps + PrimeGroup + Zeroize + ConstantTimeEq;
|
||||
|
||||
/// ID for this curve.
|
||||
const ID: &'static [u8];
|
||||
|
@ -81,6 +82,16 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
Self::hash_to_F(b"rho", binding)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn random_F<R: RngCore + CryptoRng>(rng: &mut R) -> Self::F {
|
||||
let mut res;
|
||||
while {
|
||||
res = Self::F::random(&mut *rng);
|
||||
res.ct_eq(&Self::F::zero()).into()
|
||||
} {}
|
||||
res
|
||||
}
|
||||
|
||||
/// Securely generate a random nonce. H3 from the IETF draft.
|
||||
fn random_nonce<R: RngCore + CryptoRng>(mut secret: Self::F, rng: &mut R) -> Self::F {
|
||||
let mut seed = vec![0; 32];
|
||||
|
@ -89,12 +100,18 @@ pub trait Curve: Clone + Copy + PartialEq + Eq + Debug + Zeroize {
|
|||
let mut repr = secret.to_repr();
|
||||
secret.zeroize();
|
||||
|
||||
seed.extend(repr.as_ref());
|
||||
let mut res;
|
||||
while {
|
||||
seed.extend(repr.as_ref());
|
||||
res = Self::hash_to_F(b"nonce", &seed);
|
||||
res.ct_eq(&Self::F::zero()).into()
|
||||
} {
|
||||
rng.fill_bytes(&mut seed);
|
||||
}
|
||||
|
||||
for i in repr.as_mut() {
|
||||
i.zeroize();
|
||||
}
|
||||
|
||||
let res = Self::hash_to_F(b"nonce", &seed);
|
||||
seed.zeroize();
|
||||
res
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
|
|||
|
||||
for i in 0 .. t {
|
||||
// Step 1: Generate t random values to form a polynomial with
|
||||
coefficients.push(C::F::random(&mut *rng));
|
||||
coefficients.push(C::random_F(&mut *rng));
|
||||
// Step 3: Generate public commitments
|
||||
commitments.push(C::generator() * coefficients[i]);
|
||||
// Serialize them for publication
|
||||
|
@ -56,7 +56,7 @@ fn generate_key_r1<R: RngCore + CryptoRng, C: Curve>(
|
|||
}
|
||||
|
||||
// Step 2: Provide a proof of knowledge
|
||||
let mut r = C::F::random(rng);
|
||||
let mut r = C::random_F(rng);
|
||||
serialized.extend(
|
||||
schnorr::sign::<C>(
|
||||
coefficients[0],
|
||||
|
|
|
@ -42,6 +42,7 @@ pub mod algorithm;
|
|||
pub mod sign;
|
||||
|
||||
/// Tests for application-provided curves and algorithms.
|
||||
#[cfg(any(test, feature = "tests"))]
|
||||
pub mod tests;
|
||||
|
||||
// Validate a map of serialized values to have the expected included participants
|
||||
|
@ -215,6 +216,7 @@ impl<C: Curve> FrostCore<C> {
|
|||
self.params
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "tests"))]
|
||||
pub(crate) fn secret_share(&self) -> C::F {
|
||||
self.secret_share
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::{
|
|||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use transcript::Transcript;
|
||||
|
||||
|
@ -97,8 +98,6 @@ impl<C: Curve> Drop for PreprocessPackage<C> {
|
|||
}
|
||||
impl<C: Curve> ZeroizeOnDrop for PreprocessPackage<C> {}
|
||||
|
||||
// This library unifies the preprocessing step with signing due to security concerns and to provide
|
||||
// a simpler UX
|
||||
fn preprocess<R: RngCore + CryptoRng, C: Curve, A: Algorithm<C>>(
|
||||
rng: &mut R,
|
||||
params: &mut Params<C, A>,
|
||||
|
@ -202,14 +201,20 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
// consistency. While this is suboptimal, it maintains IETF compliance, and Algorithm is
|
||||
// documented accordingly
|
||||
let transcript = |t: &mut A::Transcript, commitments: [C::G; 2]| {
|
||||
if commitments[0].ct_eq(&C::G::identity()).into() ||
|
||||
commitments[1].ct_eq(&C::G::identity()).into()
|
||||
{
|
||||
Err(FrostError::InvalidCommitment(*l))?;
|
||||
}
|
||||
t.append_message(b"commitment_D", commitments[0].to_bytes().as_ref());
|
||||
t.append_message(b"commitment_E", commitments[1].to_bytes().as_ref());
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if *l == params.keys.params().i {
|
||||
for nonce_commitments in &our_preprocess.commitments {
|
||||
for commitments in nonce_commitments {
|
||||
transcript(params.algorithm.transcript(), *commitments);
|
||||
transcript(params.algorithm.transcript(), *commitments).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +232,7 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
commitments.push(Vec::with_capacity(nonce_generators.len()));
|
||||
for _ in 0 .. nonce_generators.len() {
|
||||
commitments[n].push(read_D_E::<_, C>(&mut cursor, *l)?);
|
||||
transcript(params.algorithm.transcript(), commitments[n][commitments[n].len() - 1]);
|
||||
transcript(params.algorithm.transcript(), commitments[n][commitments[n].len() - 1])?;
|
||||
}
|
||||
|
||||
if nonce_generators.len() >= 2 {
|
||||
|
@ -426,6 +431,7 @@ impl<C: Curve, A: Algorithm<C>> AlgorithmMachine<C, A> {
|
|||
Ok(AlgorithmMachine { params: Params::new(algorithm, keys, included)? })
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "tests"))]
|
||||
pub(crate) fn unsafe_override_preprocess(
|
||||
self,
|
||||
preprocess: PreprocessPackage<C>,
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::io::Cursor;
|
|||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use group::{ff::Field, Group};
|
||||
use group::Group;
|
||||
|
||||
use crate::{Curve, FrostCore, tests::core_gen};
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub fn test_multiexp<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
let mut sum = C::G::identity();
|
||||
for _ in 0 .. 10 {
|
||||
for _ in 0 .. 100 {
|
||||
pairs.push((C::F::random(&mut *rng), C::generator() * C::F::random(&mut *rng)));
|
||||
pairs.push((C::random_F(&mut *rng), C::generator() * C::random_F(&mut *rng)));
|
||||
sum += pairs[pairs.len() - 1].1 * pairs[pairs.len() - 1].0;
|
||||
}
|
||||
assert_eq!(multiexp::multiexp(&pairs), sum);
|
||||
|
|
|
@ -10,35 +10,12 @@ use crate::{
|
|||
fn ristretto_vectors() {
|
||||
test_with_vectors::<_, curve::Ristretto, curve::IetfRistrettoHram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"5c3430d391552f6e60ecdc093ff9f6f4488756aa6cebdbad75a768010b8f830e",
|
||||
"b06fc5eac20b4f6e1b271d9df2343d843e1e1fb03c4cbb673f2872d459ce6f01",
|
||||
"f17e505f0e2581c6acfe54d3846a622834b5e7b50cad9a2109a97ba7a80d5c04",
|
||||
],
|
||||
group_secret: "1b25a55e463cfd15cf14a5d3acc3d15053f08da49c8afcf3ab265f2ebc4f970b",
|
||||
group_key: "e2a62f39eede11269e3bd5a7d97554f5ca384f9f6d3dd9c3c0d05083c7254f57",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"de3e8f526dcb51a1b9b48cc284aeca27c385aa3ba1a92a0c8440d51e1a1d2f00",
|
||||
"fa8dca5ec7a05d5a7b782be847ba3dde1509de1dbcf0569fc980cff795db5404",
|
||||
],
|
||||
[
|
||||
"e07061a9ab6735de9a75b0c64f086c5b999894611d0cdc03f85c4e87c8aae602",
|
||||
"38b17578e8e6ad4077071ce6b0bf9cb85ac35fee7868dcb6d9bfa97f0e153e0e",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"a5f046916a6a111672111e47f9825586e1188da8a0f3b7c61f2b6b432c636e07",
|
||||
"4c175c7e43bd197980c2021774036eb288f54179f079fbf21b7d2f9f52846401",
|
||||
],
|
||||
sig: "94b11def3f919503c3544452ad2a59f198f64cc323bd758bb1c65b42032a7473".to_owned() +
|
||||
"f107a30fae272b8ff2d3205e6d86c3386a0ecf21916db3b93ba89ae27ee7d208",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"vectors/frost-ristretto255-sha512.json"
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -47,34 +24,9 @@ fn ristretto_vectors() {
|
|||
fn ed25519_vectors() {
|
||||
test_with_vectors::<_, curve::Ed25519, curve::IetfEd25519Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033f2ec83d93509",
|
||||
"a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07eed76bf409e80d",
|
||||
"d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8bdea643a9a02",
|
||||
],
|
||||
group_secret: "7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a790c6e13a98304",
|
||||
group_key: "15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040d380fb9738673",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"4e64f59e90a3b9cdce346fae68eb0e459532c8ca1ad59a566c3ee2c67bf0100b",
|
||||
"470c660895c6db164ee6564120eec71023fa5297f09c663bb8171646c5632d00",
|
||||
],
|
||||
[
|
||||
"6fc516495dbb364b807cdd0c2e5e3f58aa4914a53fed33cc340033979bb07304",
|
||||
"0837e770a88147d41ff39138ca23b35d6cf303a4f148294755ede4b7e760d701",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"3f2eb12735e5b39da97e884a6caadf6bb83f1efcec709d6f66333d0d67ebe707",
|
||||
"79e572b8632fbb928519dd2eff793de8784a56d582ae48c807d39b0dc5b93509",
|
||||
],
|
||||
sig: "e31e69a4e10d5ca2307c4a0d12cd86e3fceee550e55cb5b3f47c7ad6dbb38884".to_owned() +
|
||||
"cb3f2e837eb15cd858fb6dd68c2a3e3f318a74d16f1fe6376e06d91a2ca51d01",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-ed25519-sha512.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::io::Cursor;
|
|||
use rand_core::OsRng;
|
||||
|
||||
use crate::{
|
||||
curve::{Curve, Ed448, Ietf8032Ed448Hram, NonIetfEd448Hram},
|
||||
curve::{Curve, Ed448, Ietf8032Ed448Hram, IetfEd448Hram},
|
||||
schnorr::{SchnorrSignature, verify},
|
||||
tests::vectors::{Vectors, test_with_vectors},
|
||||
};
|
||||
|
@ -48,88 +48,12 @@ fn ed448_8032_vector() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn ed448_non_ietf() {
|
||||
test_with_vectors::<_, Ed448, NonIetfEd448Hram>(
|
||||
fn ed448_vectors() {
|
||||
test_with_vectors::<_, Ed448, IetfEd448Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
concat!(
|
||||
"4a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df201f5",
|
||||
"25e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd01",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"2503d56c4f516444a45b080182b8a2ebbe4d9b2ab509f25308c88c0e",
|
||||
"a7ccdc44e2ef4fc4f63403a11b116372438a1e287265cadeff1fcb07",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"00db7a8146f995db0a7cf844ed89d8e94c2b5f259378ff66e39d1728",
|
||||
"28b264185ac4decf7219e4aa4478285b9c0eef4fccdf3eea69dd980d",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
group_secret: concat!(
|
||||
"6298e1eef3c379392caaed061ed8a31033c9e9e3420726f23b404158",
|
||||
"a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c",
|
||||
"00"
|
||||
),
|
||||
group_key: concat!(
|
||||
"3832f82fda00ff5365b0376df705675b63d2a93c24c6e81d40801ba2",
|
||||
"65632be10f443f95968fadb70d10786827f30dc001c8d0f9b7c1d1b0",
|
||||
"00"
|
||||
),
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
concat!(
|
||||
"06f2e15b05d29a50f0686a890259f4dcf66147a80809ed9e50926f5f",
|
||||
"173fe23a0627561efa003724dc270effc47a30bc4d80aba30725401d",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"e0482e611c34f191d1c13a09bc8bbf4bda68db4de32aa7908849b02b",
|
||||
"a912cfba46c805e2d8560ab9437e343e1dde6b481a2bae527e111b2c",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
[
|
||||
concat!(
|
||||
"295c56447c070157e6bc3c83ed2afca194569e07d0ad27d28a40dec2",
|
||||
"c4107c07d507db20da1be62ea6976b8e53ab5d26e225c663f2e71511",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"b97303a6c5ab12b6ad310834361033a19d99dfdf93109da721da35c3",
|
||||
"abbc5f29df33b3402692bef9f005bb8ea00af5ba20cc688360fd8831",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
concat!(
|
||||
"5b65641e27007ec71509c6af5cf8527eb01fee5b2b07d8beecf6646e",
|
||||
"b7e7e27d85119b74f895b56ba7561834a1b0c42639b122160a0b6208",
|
||||
"00"
|
||||
),
|
||||
concat!(
|
||||
"821b7ac04d7c01d970b0b3ba4ae8f737a5bac934aed1600b1cad7601",
|
||||
"1c240629bce6a4671a1b6f572cec708ec161a72a5ca04e50eabdfc25",
|
||||
"00"
|
||||
),
|
||||
],
|
||||
sig: concat!(
|
||||
"c7ad7ad9fcfeef9d1492361ba641400bd3a3c8335a83cdffbdd8867d",
|
||||
"2849bb4419dcc3e594baa731081a1a00cd3dea9219a81ecba4646e95",
|
||||
"00",
|
||||
"dd80dede747c7fa086b9796aa7e04ab655dab790d9d838ca08a4db6f",
|
||||
"d30be9a641f83fdc12b124c3d34289c262126c5195517166f4c85e2e",
|
||||
"00"
|
||||
)
|
||||
.to_string(),
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-ed448-shake256.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,35 +13,12 @@ use crate::curve::{P256, IetfP256Hram};
|
|||
fn secp256k1_vectors() {
|
||||
test_with_vectors::<_, Secp256k1, IetfSecp256k1Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"08f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1ea2b01f4254c",
|
||||
"04f0feac2edcedc6ce1253b7fab8c86b856a797f44d83d82a385554e6e401984",
|
||||
"00e95d59dd0d46b0e303e500b62b7ccb0e555d49f5b849f5e748c071da8c0dbc",
|
||||
],
|
||||
group_secret: "0d004150d27c3bf2a42f312683d35fac7394b1e9e318249c1bfe7f0795a83114",
|
||||
group_key: "02f37c34b66ced1fb51c34a90bdae006901f10625cc06c4f64663b0eae87d87b4f",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"36d5c4185c40b02b5e4673e2531a10e6ff9883840a68ec08dbeb896467e21355",
|
||||
"7b3f573ca0a28f9f94522be4748df0ed04de8a83085aff4be7b01aa53fb6ac1b",
|
||||
],
|
||||
[
|
||||
"ba4f8b8e587b2c9fc61a6156885f0bc67654b5e068c9e7749f75c09a98f17c13",
|
||||
"316de06639051ac7869e5ac4458eda1fef90ce93fa3c490556c4192e4fa550d0",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"f9ee00d5ac0c746b751dde99f71d86f8f0300a81bd0336ca6649ef597239e13f",
|
||||
"61048ca334ac6a6cb59d6b3ea2b25b7098e204adc09e2f88b024531b081d1d6f",
|
||||
],
|
||||
sig: "023cf76388f92d403aa937af2e3cb3e7a2350e40400c16a282e330af2c60eeb85a".to_owned() +
|
||||
"5af28d78e0b8ded82abb49d899cfe26ace633248ce58c617569be3e7aa20bd6d",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"vectors/frost-secp256k1-sha256.json"
|
||||
))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -50,34 +27,9 @@ fn secp256k1_vectors() {
|
|||
fn p256_vectors() {
|
||||
test_with_vectors::<_, P256, IetfP256Hram>(
|
||||
&mut OsRng,
|
||||
Vectors {
|
||||
threshold: 2,
|
||||
shares: &[
|
||||
"0c9c1a0fe806c184add50bbdcac913dda73e482daf95dcb9f35dbb0d8a9f7731",
|
||||
"8d8e787bef0ff6c2f494ca45f4dad198c6bee01212d6c84067159c52e1863ad5",
|
||||
"0e80d6e8f6192c003b5488ce1eec8f5429587d48cf001541e713b2d53c09d928",
|
||||
],
|
||||
group_secret: "8ba9bba2e0fd8c4767154d35a0b7562244a4aaf6f36c8fb8735fa48b301bd8de",
|
||||
group_key: "023a309ad94e9fe8a7ba45dfc58f38bf091959d3c99cfbd02b4dc00585ec45ab70",
|
||||
|
||||
msg: "74657374",
|
||||
included: &[1, 3],
|
||||
nonces: &[
|
||||
[
|
||||
"9aa66350b0f72b27ce4668323b4280cd49709177ed8373977c22a75546c9995d",
|
||||
"bd8b05d7fd0ff5a5ed65b1f105478f7718a981741fa8fa9b55ac6d3c8fc59a05",
|
||||
],
|
||||
[
|
||||
"4c1aec8e84c496b80af98415fada2e6a4b1f902d4bc6c9682699b8aeffd97419",
|
||||
"eeaf5ef7af01e55050fb8acafc9c9306ef1cc13214677ba33e7bc51e8677e892",
|
||||
],
|
||||
],
|
||||
sig_shares: &[
|
||||
"ec5b8ab47d55903698492a07bb322ab6e7d3cf32581dcedf43c4fa18b46f3e10",
|
||||
"c97da3580560e88725a8e393d46fee18ecd2e00148e5e303d4a510fae9c11da5",
|
||||
],
|
||||
sig: "036b3eba585ff5d40df29893fb6f60572803aef97800cfaaaa5cf0f0f19d8237f7".to_owned() +
|
||||
"b5d92e0d82b678bcbdf20d9b8fa218d017bfb485f9ec135e24b04050a1cd3664",
|
||||
},
|
||||
Vectors::from(
|
||||
serde_json::from_str::<serde_json::Value>(include_str!("vectors/frost-p256-sha256.json"))
|
||||
.unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(Ed25519, SHA-512)",
|
||||
"group": "ed25519",
|
||||
"hash": "SHA-512"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "7b1c33d3f5291d85de664833beb1ad469f7fb6025a0ec78b3a790c6e13a98304",
|
||||
"group_public_key": "15d21ccd7ee42959562fc8aa63224c8851fb3ec85a3faf66040d380fb9738673",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"178199860edd8c62f5212ee91eff1295d0d670ab4ed4506866bae57e7030b204"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "929dcc590407aae7d388761cddb0c0db6f5627aea8e217f4a033f2ec83d93509"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "a91e66e012e4364ac9aaa405fcafd370402d9859f7b6685c07eed76bf409e80d"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "d3cb090a075eb154e82fdb4b3cb507f110040905468bb9c46da8bdea643a9a02"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "9d06a6381c7a4493929761a73692776772b274236fb5cfcc7d1b48ac3a9c249f",
|
||||
"binding_nonce_randomness": "db184d7bc01a3417fe1f2eb3cf5479bb027145e6369a5f879f32d334ab256b23",
|
||||
"hiding_nonce": "70652da3e8d7533a0e4b9e9104f01b48c396b5b553717784ed8d05c6a36b9609",
|
||||
"binding_nonce": "4f9e1ad260b5c0e4fe0e0719c6324f89fecd053758f77c957f56967e634a710e",
|
||||
"hiding_nonce_commitment": "44105304351ceddc58e15ddea35b2cb48e60ced54ceb22c3b0e5d42d098aa1d8",
|
||||
"binding_nonce_commitment": "b8274b18a12f2cef74ae42f876cec1e31daab5cb162f95a56cd2487409c9d1dd",
|
||||
"binding_factor_input": "c5b95020cba31a9035835f074f718d0c3af02a318d6b4723bbd1c088f4889dd7b9ff8e79f9a67a9d27605144259a7af18b7cca2539ffa5c4f1366a98645da8f4e077d604fff64f20e2377a37e5a10ce152194d62fe856ef4cd935d4f1cb0088c2083a2722ad3f5a84d778e257da0df2a7cadb004b1f5528352af778b94ee1c2a0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "2d5630c36d33258b1208c4205fa759b762d09bfa06b29cf792cf98758c0b3305"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "31ca9b07936d6b342a43d97f23b7bec5a5f5a09575a075393868dd8df5c05a54",
|
||||
"binding_nonce_randomness": "c1db96a85d8b593e14fdb869c0955625478afa6a987ad217e7f2261dcab26819",
|
||||
"hiding_nonce": "233adcb0ec0eddba5f1cc5268f3f4e6fc1dd97fb1e4a1754e6ddc92ed834ca0b",
|
||||
"binding_nonce": "b59fc8a32fe02ec0a44c4671f3d1f82ea3924b7c7c0179398fc9137e82757803",
|
||||
"hiding_nonce_commitment": "d31bd81ce216b1c83912803a574a0285796275cb8b14f6dc92c8b09a6951f0a2",
|
||||
"binding_nonce_commitment": "e1c863cfd08df775b6747ef2456e9bf9a03cc281a479a95261dc39137fcf0967",
|
||||
"binding_factor_input": "c5b95020cba31a9035835f074f718d0c3af02a318d6b4723bbd1c088f4889dd7b9ff8e79f9a67a9d27605144259a7af18b7cca2539ffa5c4f1366a98645da8f4e077d604fff64f20e2377a37e5a10ce152194d62fe856ef4cd935d4f1cb0088c2083a2722ad3f5a84d778e257da0df2a7cadb004b1f5528352af778b94ee1c2a0300000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "1137be5cdf3d18e44367acee8485e9a66c3164077af80619b6291e3943bbef04"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c4b26af1e91fbc8440a0dad253e72620da624553c5b625fd51e6ea179fc09f05"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "9369640967d0cb98f4dedfde58a845e0e18e0a7164396358439060ed282b4e08"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "ae11c539fdc709b78fef5ee1f5a2250297e3e1b62a86a86c26d93c389934ba0e571ccffa50f0871d357fbab1ac8f6c00bcf14fc429f0885595764b05c8ebed0d"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(Ed448, SHAKE256)",
|
||||
"group": "ed448",
|
||||
"hash": "SHAKE256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "6298e1eef3c379392caaed061ed8a31033c9e9e3420726f23b404158a401cd9df24632adfe6b418dc942d8a091817dd8bd70e1c72ba52f3c00",
|
||||
"group_public_key": "3832f82fda00ff5365b0376df705675b63d2a93c24c6e81d40801ba265632be10f443f95968fadb70d10786827f30dc001c8d0f9b7c1d1b000",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"dbd7a514f7a731976620f0436bd135fe8dddc3fadd6e0d13dbd58a1981e587d377d48e0b7ce4e0092967c5e85884d0275a7a740b6abdcd0500"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "4a2b2f5858a932ad3d3b18bd16e76ced3070d72fd79ae4402df201f525e754716a1bc1b87a502297f2a99d89ea054e0018eb55d39562fd0100"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "2503d56c4f516444a45b080182b8a2ebbe4d9b2ab509f25308c88c0ea7ccdc44e2ef4fc4f63403a11b116372438a1e287265cadeff1fcb0700"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "00db7a8146f995db0a7cf844ed89d8e94c2b5f259378ff66e39d172828b264185ac4decf7219e4aa4478285b9c0eef4fccdf3eea69dd980d00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "89bf16040081ff2990336b200613787937ebe1f024b8cdff90eb6f1c741d91c1",
|
||||
"binding_nonce_randomness": "cd646348bb98fd2a4b2f27fb7d6da18201c161847352576b4bf125190e965483",
|
||||
"hiding_nonce": "67a6f023e77361707c6e894c625e809e80f33fdb310810053ae29e28e7011f3193b9020e73c183a98cc3a519160ed759376dd92c9483162200",
|
||||
"binding_nonce": "4812e8d7c8b7a50ced80b507902d074ef8647bc1146979683da8d0fecd93fa3c8230cade2fb4344600aa04bd4b7a21d046c5b63ee865b12a00",
|
||||
"hiding_nonce_commitment": "649c6a53b109897d962d033f23d01fd4e1053dddf3746d2ddce9bd66aea38ccfc3df061df03ca399eb806312ab3037c0c31523142956ada780",
|
||||
"binding_nonce_commitment": "0064cc729a8e2fcf417e43788ecec37b10e9e1dcb3ae90854efbfaad00a0ef3cdd52e18d56f073c8ff0947cb71ff0bb17c3d45d096409ddb00",
|
||||
"binding_factor_input": "106dadce87ca867018702d69a02effd165e1ac1a511c957cff1897ceff2e34ca212fe798d84f0bde6054bf0fa77fd4cd4bc4853d6dc8dbd19d340923f0ebbbb35172df4ab865a45d55af31fa0e6606ea97cf8513022b2b133d0f9f6b8d3be184221fc4592bf12bd7fb4127bb67e51a6dc9e5f1ed5243362fb46a6da552418ca967d43d9bc811a21917a3018de58f11c25f6b9ad8bec3699e06b87dd3ab67a7326c30878c7c55ec1a45802af65da193ce99634158539e38c232a627895c5f14e2e20d487382ccc9c99cd0a0df266a292f283bb9b6854e344ecc32d5e1852fdde5fde77798010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "3412ac894a91a6bc0e3e7c790f3e8ef5d1288e54de780aba384cbb3081b602dd188010e5b0c9ac2b5dca0aae54cfd0f5c391cece8092131d00"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "3718dabb4fd3d7dd9adad4878c6de8b33c8841cfe7cc95a85592952a2c9c554d",
|
||||
"binding_nonce_randomness": "3becbc90798211a0f52543dd1f24869a143fdf743409581af4db30f045773d64",
|
||||
"hiding_nonce": "4f2666770317d14ec9f7fd6690c075c34b4cde7f6d9bceda9e9433ec8c0f2dc983ff1622c3a54916ce7c161381d263fad62539cddab2101600",
|
||||
"binding_nonce": "88f66df8bb66389932721a40de4aa5754f632cac114abc1052688104d19f3b1a010880ebcd0c4c0f8cf567d887e5b0c3c0dc78821166550f00",
|
||||
"hiding_nonce_commitment": "8dcf049167e28d5f53fa7ebbbd136abcaf2be9f2c02448c8979002f92577b22027640def7ddd5b98f9540c2280f36a92d4747bbade0b0c4280",
|
||||
"binding_nonce_commitment": "12e837b89a2c085481fcf0ca640a17a24b6fc96b032d40e4301c78e7232a9f49ffdcad2c21acbc992e79dfc3c6c07cb94e4680b3dcc9935580",
|
||||
"binding_factor_input": "106dadce87ca867018702d69a02effd165e1ac1a511c957cff1897ceff2e34ca212fe798d84f0bde6054bf0fa77fd4cd4bc4853d6dc8dbd19d340923f0ebbbb35172df4ab865a45d55af31fa0e6606ea97cf8513022b2b133d0f9f6b8d3be184221fc4592bf12bd7fb4127bb67e51a6dc9e5f1ed5243362fb46a6da552418ca967d43d9bc811a21917a3018de58f11c25f6b9ad8bec3699e06b87dd3ab67a7326c30878c7c55ec1a45802af65da193ce99634158539e38c232a627895c5f14e2e20d487382ccc9c99cd0a0df266a292f283bb9b6854e344ecc32d5e1852fdde5fde77798030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "6aa48a3635d7b962489283ee1ccda8ea66e5677b1e17f2f475eb565e3ae8ea73360f24c04e3775dadd1f2923adcda3d105536ad28c3c561100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c5057c80d13e565545dac6f3aa333065c809a14a94fea3c8e4e87e386a9cb89602de7355c5d19ebb09d553b100ef1858104fc7c43992d83400"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "2b490ea08411f78c620c668fff8ba70b25b7c89436f20cc45419213de70f93fb6c9094c79293697d72e741b68d2e493446005145d0b7fc3500"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "83ac141d289a5171bc894b058aee2890316280719a870fc5c1608b77403023155d7a9dc15a2b7920bb5826dd540bf76336be99536cebe36280fd093275c38dd4be525767f537fd6a4f5d8a9330811562c84fded5f851ac4b926f6e081d586508397cbc95678e1d628c564f180a0a4ad52a00"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(P-256, SHA-256)",
|
||||
"group": "P-256",
|
||||
"hash": "SHA-256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "8ba9bba2e0fd8c4767154d35a0b7562244a4aaf6f36c8fb8735fa48b301bd8de",
|
||||
"group_public_key": "023a309ad94e9fe8a7ba45dfc58f38bf091959d3c99cfbd02b4dc00585ec45ab70",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"80f25e6c0709353e46bfbe882a11bdbb1f8097e46340eb8673b7e14556e6c3a4"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "0c9c1a0fe806c184add50bbdcac913dda73e482daf95dcb9f35dbb0d8a9f7731"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "8d8e787bef0ff6c2f494ca45f4dad198c6bee01212d6c84067159c52e1863ad5"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "0e80d6e8f6192c003b5488ce1eec8f5429587d48cf001541e713b2d53c09d928"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "f4e8cf80aec3f888d997900ac7e3e349944b5a6b47649fc32186d2f1238103c6",
|
||||
"binding_nonce_randomness": "a7f220770b6f10ff54ec6afa55f99bd08cc92fa1a488c86e9bf493e9cb894cdf",
|
||||
"hiding_nonce": "f871dfcf6bcd199342651adc361b92c941cb6a0d8c8c1a3b91d79e2c1bf3722d",
|
||||
"binding_nonce": "bd3ece3634a1b303dea0586ed67a91fe68510f11ebe66e8868309b1551ef2388",
|
||||
"hiding_nonce_commitment": "03987febbc67a8ed735affdff4d3a5adf22c05c80f97f311ab7437a3027372deb3",
|
||||
"binding_nonce_commitment": "02a1960477d139035b986d6adcb06491378beb92ccd097ad94e76291c52343849d",
|
||||
"binding_factor_input": "350c8b523feea9bb35720e9fbe0405ed48d78caa4fb60869f34367e144c68bb0fc77bf512409ad8b91e2ace4909229891a446c45683f5eb2f843dbec224527dc0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"binding_factor": "cb415dd1d866493ee7d2db7cb33929d7e430e84d80c58070e2bbb1fdbf76a9c8"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "1b6149d252a0a0a6618b8d22a1c49897f9b0d23a48f19598e191e05dc7b7ae33",
|
||||
"binding_nonce_randomness": "e13994bb75aafe337c32afdbfd08ae60dd108fc768845edaa871992044cabf1b",
|
||||
"hiding_nonce": "802e9321f9f63688c6c1a9681a4a4661f71770e0cef92b8a5997155d18fb82ef",
|
||||
"binding_nonce": "8b6b692ae634a24536f45dda95b2398af71cd605fb7a0bbdd9408d211ab99eba",
|
||||
"hiding_nonce_commitment": "0212cac45ebd4100c97506939391f9be4ffc3ca2960e2ef95aeaa38abdede204ca",
|
||||
"binding_nonce_commitment": "03017ce754d310eabda0f5681e61ce3d713cdd337070faa6a68471af49694a4e7e",
|
||||
"binding_factor_input": "350c8b523feea9bb35720e9fbe0405ed48d78caa4fb60869f34367e144c68bb0fc77bf512409ad8b91e2ace4909229891a446c45683f5eb2f843dbec224527dc0000000000000000000000000000000000000000000000000000000000000003",
|
||||
"binding_factor": "dfd82467569334e952edecb10d92adf85b8e299db0b40be3131a12efdfa3e796"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c5acd980310aaf87cb7a9a90428698ef3e6b1e5860f7fb06329bc0efe3f14ca5"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "1e064fbd35467377eb3fe161ff975e9ec3ed8e2e0d4c73f3a6b0a023777e1264"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "029e07d4171dbf9a730ed95e9d95bda06fa4db76c88c519f7f3ca5483019f46cb0e3b3293d665122ffb6ba7bf2421df78e0258ac866e446ef9d94c61135b6f5f09"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(ristretto255, SHA-512)",
|
||||
"group": "ristretto255",
|
||||
"hash": "SHA-512"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "1b25a55e463cfd15cf14a5d3acc3d15053f08da49c8afcf3ab265f2ebc4f970b",
|
||||
"group_public_key": "e2a62f39eede11269e3bd5a7d97554f5ca384f9f6d3dd9c3c0d05083c7254f57",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"410f8b744b19325891d73736923525a4f596c805d060dfb9c98009d34e3fec02"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "5c3430d391552f6e60ecdc093ff9f6f4488756aa6cebdbad75a768010b8f830e"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "b06fc5eac20b4f6e1b271d9df2343d843e1e1fb03c4cbb673f2872d459ce6f01"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "f17e505f0e2581c6acfe54d3846a622834b5e7b50cad9a2109a97ba7a80d5c04"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "81800157bb554f299fe0b6bd658e4c4591d74168b5177bf55e8dceed59dc80c7",
|
||||
"binding_nonce_randomness": "e9b37de02fde28f601f09051ed9a277b02ac81c803a5c72492d58635001fe355",
|
||||
"hiding_nonce": "40f58e8df202b21c94f826e76e4647efdb0ea3ca7ae7e3689bc0cbe2e2f6660c",
|
||||
"binding_nonce": "373dd42b5fe80e88edddf82e03744b6a12d59256f546de612d4bbd91a6b1df06",
|
||||
"hiding_nonce_commitment": "b8c7319a56b296537436e5a6f509a871a3c74eff1534ec1e2f539ccd8b322411",
|
||||
"binding_nonce_commitment": "7af5d4bece8763ce3630370adbd978699402f624fd3a7d2c71ea5839efc3cf54",
|
||||
"binding_factor_input": "9c245d5fc2e451c5c5a617cc6f2a20629fb317d9b1c1915ab4bfa319d4ebf922c54dd1a5b3b754550c72734ac9255db8107a2b01f361754d9f13f428c2f6de9e4f609ae0dbe8bd1f95bee9f9ea219154d567ef174390bac737bb67ee1787c8a34279728d4aa99a6de2d5ce6deb86afe6bc68178f01223bb5eb934c8a23b6354e0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "607df5e2e3a8b5e2704716693e18f548100a32b86a5685d3932a774c3f107e06"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "daeb223c4a913943cff2fb0b0e638dfcc281e1e8936ee6c3fef4d49ad9cbfaa0",
|
||||
"binding_nonce_randomness": "c425768d952ab8f18b9720c54b93e612ba2cca170bb7518cac080896efa7429b",
|
||||
"hiding_nonce": "491477c9dbe8717c77c6c1e2c5f4cec636c7c154313a44c91fea63e309f3e100",
|
||||
"binding_nonce": "3ae1bba7d6f2076f81596912dd916efae5b3c2ef896956321194fdd2e52ebc0f",
|
||||
"hiding_nonce_commitment": "e4466b7670ac4f9d9b7b67655860dd1ab341be18a654bb1966df53c76c85d511",
|
||||
"binding_nonce_commitment": "ce47cd595d25d7effc3c095efa2a687a1728a5ecab402b39e0c0ad9a525ea54f",
|
||||
"binding_factor_input": "9c245d5fc2e451c5c5a617cc6f2a20629fb317d9b1c1915ab4bfa319d4ebf922c54dd1a5b3b754550c72734ac9255db8107a2b01f361754d9f13f428c2f6de9e4f609ae0dbe8bd1f95bee9f9ea219154d567ef174390bac737bb67ee1787c8a34279728d4aa99a6de2d5ce6deb86afe6bc68178f01223bb5eb934c8a23b6354e0300000000000000000000000000000000000000000000000000000000000000",
|
||||
"binding_factor": "2bd27271c28746eb93e2114d6778c12b44c9287d84b85dc780eb08da6f689900"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "c38f438c325ce6bfa4272b37e7707caaeb57fa8c7ddcc05e0725acb8a7d9cd0c"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "4cb9917be3bd53f1d60f1c3d1a3ff563565fa15a391133e7f980e55d3aeb7904"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "204d5d93aa486192ecf2f64ce7dbc1db76948fb1077d1a719ae1ecca6143501e2275dfaafbb62759a59a4fd122b692f941b79be7b6edf34501a69116e2c44701"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"config": {
|
||||
"MAX_PARTICIPANTS": "3",
|
||||
"NUM_PARTICIPANTS": "2",
|
||||
"MIN_PARTICIPANTS": "2",
|
||||
"name": "FROST(secp256k1, SHA-256)",
|
||||
"group": "secp256k1",
|
||||
"hash": "SHA-256"
|
||||
},
|
||||
"inputs": {
|
||||
"group_secret_key": "0d004150d27c3bf2a42f312683d35fac7394b1e9e318249c1bfe7f0795a83114",
|
||||
"group_public_key": "02f37c34b66ced1fb51c34a90bdae006901f10625cc06c4f64663b0eae87d87b4f",
|
||||
"message": "74657374",
|
||||
"share_polynomial_coefficients": [
|
||||
"fbf85eadae3058ea14f19148bb72b45e4399c0b16028acaf0395c9b03c823579"
|
||||
],
|
||||
"participants": {
|
||||
"1": {
|
||||
"participant_share": "08f89ffe80ac94dcb920c26f3f46140bfc7f95b493f8310f5fc1ea2b01f4254c"
|
||||
},
|
||||
"2": {
|
||||
"participant_share": "04f0feac2edcedc6ce1253b7fab8c86b856a797f44d83d82a385554e6e401984"
|
||||
},
|
||||
"3": {
|
||||
"participant_share": "00e95d59dd0d46b0e303e500b62b7ccb0e555d49f5b849f5e748c071da8c0dbc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_one_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"hiding_nonce_randomness": "80cbea5e405d169999d8c4b30b755fedb26ab07ec8198cda4873ed8ce5e16773",
|
||||
"binding_nonce_randomness": "f6d5b38197843046b68903048c1feba433e3500145281fa8bb1e26fdfeef5e7f",
|
||||
"hiding_nonce": "acc83278035223c1ba464e2d11bfacfc872b2b23e1041cf5f6130da21e4d8068",
|
||||
"binding_nonce": "c3ef169995bc3d2c2d48f30b83d0c63751e67ceb057695bcb2a6aa40ed5d926b",
|
||||
"hiding_nonce_commitment": "036673d68a928793c33ae07776908eae8ea15dd947ed81284e939aaba118573a5e",
|
||||
"binding_nonce_commitment": "03d2a96dd4ec1ee29dc22067109d1290dabd8016cb41856ee8ff9281c3fa1baffd",
|
||||
"binding_factor_input": "a645d8249457bbcac34fa7b740f66bcce08fc39506b8bbf1a1c81092f6272eda82ae39234d714f87a7b91dd67d124a06561a36817c1ecaa255c3527d694fc4f10000000000000000000000000000000000000000000000000000000000000001",
|
||||
"binding_factor": "d7bcbd29408dedc9e138262d99b09d8b5705d76eb5de2369d9103e4423f8ac79"
|
||||
},
|
||||
"3": {
|
||||
"hiding_nonce_randomness": "b9794047604beda0c5c0529ac9dfd83c0a80399a7bdf4c3e23cef2faf69cdcc3",
|
||||
"binding_nonce_randomness": "c28ce6252631620b84c2702b34774fab365e286ebc77030a112ebccccbffa78b",
|
||||
"hiding_nonce": "cb3387defef07fc9010c0564ba6495ed41876626ed86b886ca26cbbd3566ffbc",
|
||||
"binding_nonce": "4559459735eb68e8c16319a9fd9a14016053957cb8cea273a24b7c7bc1ee26f6",
|
||||
"hiding_nonce_commitment": "030278e6e6055fb963b40e0c3c37099f803f3f38930fc89092517f8ce1b47e8d6b",
|
||||
"binding_nonce_commitment": "028eb6d238c6c0fc6216906706ad0ff9943c6c1d6079cdf74f674481ebb2485db3",
|
||||
"binding_factor_input": "a645d8249457bbcac34fa7b740f66bcce08fc39506b8bbf1a1c81092f6272eda82ae39234d714f87a7b91dd67d124a06561a36817c1ecaa255c3527d694fc4f10000000000000000000000000000000000000000000000000000000000000003",
|
||||
"binding_factor": "ecc057259f3c8b195308c9b73aaaf840660a37eb264ebce342412c58102ee437"
|
||||
}
|
||||
}
|
||||
},
|
||||
"round_two_outputs": {
|
||||
"participant_list": "1,3",
|
||||
"participants": {
|
||||
"1": {
|
||||
"sig_share": "1750b2a314a81b66fd81366583617aaafcffa68f14495204795aa0434b907aa3"
|
||||
},
|
||||
"3": {
|
||||
"sig_share": "e4dbbbbbcb035eb3512918b0368c4ab2c836a92dccff3251efa7a4aacc7d3790"
|
||||
}
|
||||
}
|
||||
},
|
||||
"final_output": {
|
||||
"sig": "0259696aac722558e8638485d252bb2556f6241a7adfdf284c8c87a3428d46448dfc2c6e5edfab7a1a4eaa4f15b9edc55dc5364fbce1488456690244ee180db233"
|
||||
}
|
||||
}
|
|
@ -12,9 +12,9 @@ use crate::{
|
|||
};
|
||||
|
||||
pub(crate) fn core_sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
let private_key = C::F::random(&mut *rng);
|
||||
let nonce = C::F::random(&mut *rng);
|
||||
let challenge = C::F::random(rng); // Doesn't bother to craft an HRAM
|
||||
let private_key = C::random_F(&mut *rng);
|
||||
let nonce = C::random_F(&mut *rng);
|
||||
let challenge = C::random_F(rng); // Doesn't bother to craft an HRAm
|
||||
assert!(schnorr::verify::<C>(
|
||||
C::generator() * private_key,
|
||||
challenge,
|
||||
|
@ -27,8 +27,8 @@ pub(crate) fn core_sign<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
// random
|
||||
pub(crate) fn core_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
||||
assert!(!schnorr::verify::<C>(
|
||||
C::generator() * C::F::random(&mut *rng),
|
||||
C::F::random(rng),
|
||||
C::generator() * C::random_F(&mut *rng),
|
||||
C::random_F(rng),
|
||||
&SchnorrSignature { R: C::G::identity(), s: C::F::zero() }
|
||||
));
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
let mut challenges = vec![];
|
||||
let mut sigs = vec![];
|
||||
for i in 0 .. 5 {
|
||||
keys.push(C::F::random(&mut *rng));
|
||||
challenges.push(C::F::random(&mut *rng));
|
||||
sigs.push(schnorr::sign::<C>(keys[i], C::F::random(&mut *rng), challenges[i]));
|
||||
keys.push(C::random_F(&mut *rng));
|
||||
challenges.push(C::random_F(&mut *rng));
|
||||
sigs.push(schnorr::sign::<C>(keys[i], C::random_F(&mut *rng), challenges[i]));
|
||||
}
|
||||
|
||||
// Batch verify
|
||||
|
@ -66,7 +66,7 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
// Make sure a completely invalid signature fails when included
|
||||
for i in 0 .. 5 {
|
||||
let mut triplets = triplets.clone();
|
||||
triplets[i].3.s = C::F::random(&mut *rng);
|
||||
triplets[i].3.s = C::random_F(&mut *rng);
|
||||
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
|
||||
assert_eq!(blame, u16::try_from(i + 1).unwrap());
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::{io::Cursor, collections::HashMap};
|
||||
#[cfg(test)]
|
||||
use std::str::FromStr;
|
||||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
|
@ -16,17 +18,61 @@ use crate::{
|
|||
|
||||
pub struct Vectors {
|
||||
pub threshold: u16,
|
||||
pub shares: &'static [&'static str],
|
||||
pub group_secret: &'static str,
|
||||
pub group_key: &'static str,
|
||||
|
||||
pub msg: &'static str,
|
||||
pub included: &'static [u16],
|
||||
pub nonces: &'static [[&'static str; 2]],
|
||||
pub sig_shares: &'static [&'static str],
|
||||
pub group_secret: String,
|
||||
pub group_key: String,
|
||||
pub shares: Vec<String>,
|
||||
|
||||
pub msg: String,
|
||||
pub included: Vec<u16>,
|
||||
pub nonces: Vec<[String; 2]>,
|
||||
|
||||
pub sig_shares: Vec<String>,
|
||||
|
||||
pub sig: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl From<serde_json::Value> for Vectors {
|
||||
fn from(value: serde_json::Value) -> Vectors {
|
||||
let to_str = |value: &serde_json::Value| value.as_str().unwrap().to_string();
|
||||
Vectors {
|
||||
threshold: u16::from_str(value["config"]["NUM_PARTICIPANTS"].as_str().unwrap()).unwrap(),
|
||||
|
||||
group_secret: to_str(&value["inputs"]["group_secret_key"]),
|
||||
group_key: to_str(&value["inputs"]["group_public_key"]),
|
||||
shares: value["inputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|share| to_str(&share["participant_share"]))
|
||||
.collect(),
|
||||
|
||||
msg: to_str(&value["inputs"]["message"]),
|
||||
included: to_str(&value["round_one_outputs"]["participant_list"])
|
||||
.split(",")
|
||||
.map(u16::from_str)
|
||||
.collect::<Result<_, _>>()
|
||||
.unwrap(),
|
||||
nonces: value["round_one_outputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|value| [to_str(&value["hiding_nonce"]), to_str(&value["binding_nonce"])])
|
||||
.collect(),
|
||||
|
||||
sig_shares: value["round_two_outputs"]["participants"]
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|value| to_str(&value["sig_share"]))
|
||||
.collect(),
|
||||
|
||||
sig: to_str(&value["final_output"]["sig"]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load these vectors into FrostKeys using a custom serialization it'll deserialize
|
||||
fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, FrostKeys<C>> {
|
||||
let shares = vectors
|
||||
|
@ -54,7 +100,7 @@ fn vectors_to_multisig_keys<C: Curve>(vectors: &Vectors) -> HashMap<u16, FrostKe
|
|||
assert_eq!(usize::from(these_keys.params().n()), shares.len());
|
||||
assert_eq!(these_keys.params().i(), i);
|
||||
assert_eq!(these_keys.secret_share(), shares[usize::from(i - 1)]);
|
||||
assert_eq!(&hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
||||
assert_eq!(hex::encode(these_keys.group_key().to_bytes().as_ref()), vectors.group_key);
|
||||
keys.insert(i, FrostKeys::new(these_keys));
|
||||
}
|
||||
|
||||
|
@ -67,26 +113,20 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
) {
|
||||
// Do basic tests before trying the vectors
|
||||
test_curve::<_, C>(&mut *rng);
|
||||
test_schnorr::<_, C>(rng);
|
||||
test_schnorr::<_, C>(&mut *rng);
|
||||
test_promotion::<_, C>(rng);
|
||||
|
||||
// Test against the vectors
|
||||
let keys = vectors_to_multisig_keys::<C>(&vectors);
|
||||
let group_key = C::read_G(&mut Cursor::new(hex::decode(vectors.group_key).unwrap())).unwrap();
|
||||
assert_eq!(
|
||||
C::generator() *
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.group_secret).unwrap())).unwrap(),
|
||||
group_key
|
||||
);
|
||||
assert_eq!(
|
||||
recover(&keys),
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.group_secret).unwrap())).unwrap()
|
||||
);
|
||||
let group_key = C::read_G(&mut Cursor::new(hex::decode(&vectors.group_key).unwrap())).unwrap();
|
||||
let secret = C::read_F(&mut Cursor::new(hex::decode(&vectors.group_secret).unwrap())).unwrap();
|
||||
assert_eq!(C::generator() * secret, group_key);
|
||||
assert_eq!(recover(&keys), secret);
|
||||
|
||||
let mut machines = vec![];
|
||||
for i in vectors.included {
|
||||
for i in &vectors.included {
|
||||
machines.push((
|
||||
*i,
|
||||
i,
|
||||
AlgorithmMachine::new(
|
||||
Schnorr::<C, H>::new(),
|
||||
keys[i].clone(),
|
||||
|
@ -102,8 +142,8 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
.drain(..)
|
||||
.map(|(i, machine)| {
|
||||
let nonces = [
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.nonces[c][0]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(vectors.nonces[c][1]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(&vectors.nonces[c][0]).unwrap())).unwrap(),
|
||||
C::read_F(&mut Cursor::new(hex::decode(&vectors.nonces[c][1]).unwrap())).unwrap(),
|
||||
];
|
||||
c += 1;
|
||||
let these_commitments = vec![[C::generator() * nonces[0], C::generator() * nonces[1]]];
|
||||
|
@ -114,7 +154,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
});
|
||||
|
||||
commitments.insert(
|
||||
i,
|
||||
*i,
|
||||
Cursor::new(
|
||||
[
|
||||
these_commitments[0][0].to_bytes().as_ref(),
|
||||
|
@ -134,18 +174,18 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
.drain(..)
|
||||
.map(|(i, machine)| {
|
||||
let (machine, share) =
|
||||
machine.sign(clone_without(&commitments, &i), &hex::decode(vectors.msg).unwrap()).unwrap();
|
||||
machine.sign(clone_without(&commitments, i), &hex::decode(&vectors.msg).unwrap()).unwrap();
|
||||
|
||||
assert_eq!(share, hex::decode(vectors.sig_shares[c]).unwrap());
|
||||
assert_eq!(share, hex::decode(&vectors.sig_shares[c]).unwrap());
|
||||
c += 1;
|
||||
|
||||
shares.insert(i, Cursor::new(share));
|
||||
shares.insert(*i, Cursor::new(share));
|
||||
(i, machine)
|
||||
})
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
for (i, machine) in machines.drain() {
|
||||
let sig = machine.complete(clone_without(&shares, &i)).unwrap();
|
||||
let sig = machine.complete(clone_without(&shares, i)).unwrap();
|
||||
let mut serialized = sig.R.to_bytes().as_ref().to_vec();
|
||||
serialized.extend(sig.s.to_repr().as_ref());
|
||||
assert_eq!(hex::encode(serialized), vectors.sig);
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "multiexp"
|
|||
version = "0.2.1"
|
||||
description = "Multiexponentation algorithms for ff/group"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/multiexp"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["multiexp", "ff", "group"]
|
||||
edition = "2021"
|
||||
|
|
|
@ -3,7 +3,7 @@ name = "flexible-transcript"
|
|||
version = "0.1.3"
|
||||
description = "A simple transcript trait definition, along with viable options"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/transcript"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["transcript"]
|
||||
edition = "2021"
|
||||
|
|
|
@ -13,8 +13,8 @@ bitcoind -regtest -txindex -fallbackfee=0.000001 -rpcuser=$RPC_USER -rpcpassword
|
|||
# give time to bitcoind to start
|
||||
while true
|
||||
do
|
||||
bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 100 $MINER && break
|
||||
sleep 5
|
||||
bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 100 $MINER && break
|
||||
sleep 5
|
||||
done
|
||||
|
||||
bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS createwallet "miner" false false $RPC_PASS false false true &&
|
||||
|
@ -24,6 +24,6 @@ bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS importprivkey $PR
|
|||
# mine a new block every BLOCK_TIME
|
||||
while true
|
||||
do
|
||||
bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 1 $MINER
|
||||
sleep $BLOCK_TIME
|
||||
bitcoin-cli -regtest -rpcuser=$RPC_USER -rpcpassword=$RPC_PASS generatetoaddress 1 $MINER
|
||||
sleep $BLOCK_TIME
|
||||
done
|
||||
|
|
|
@ -2,15 +2,13 @@
|
|||
# Setup Environment
|
||||
RPC_USER="${RPC_USER:=serai}"
|
||||
RPC_PASS="${RPC_PASS:=seraidex}"
|
||||
MINER="${MINER:=xmraddr}"
|
||||
BLOCK_TIME=${BLOCK_TIME:=5}
|
||||
|
||||
|
||||
# Run Monero
|
||||
monerod --regtest --rpc-login ${RPC_USER}:${RPC_PASS} \
|
||||
--rpc-access-control-origins * --rpc-bind-ip=0.0.0.0 --offline \
|
||||
--fixed-difficulty=1 --non-interactive --start-mining ${MINER} \
|
||||
--mining-threads 1 --bg-mining-enable --detach
|
||||
--rpc-access-control-origins * --confirm-external-bind \
|
||||
--rpc-bind-ip=0.0.0.0 --offline --fixed-difficulty=1 \
|
||||
--non-interactive --mining-threads 1 --bg-mining-enable --detach
|
||||
|
||||
# give time to monerod to start
|
||||
while true; do
|
||||
|
|
|
@ -8,7 +8,7 @@ name: serai-dev
|
|||
# coins - node clients for coins only (BTC, ETH, XMR)
|
||||
# cluster-sm - Alice, Bob, Charlie
|
||||
# cluster-coins-sm - cluster-sm with coins
|
||||
# cluter-lg - Alice, Bob, Charlie, Dave, Eve, Ferdie
|
||||
# cluster-lg - Alice, Bob, Charlie, Dave, Eve, Ferdie
|
||||
# cluster-coins-lg - cluster-lg with coins
|
||||
# monero - full node monero only
|
||||
# bitcoin - full node bitcoin only
|
||||
|
@ -42,7 +42,6 @@ services:
|
|||
- "./serai/scripts:/scripts"
|
||||
|
||||
serai-base:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-base
|
||||
profiles:
|
||||
|
@ -52,7 +51,6 @@ services:
|
|||
NAME: base
|
||||
|
||||
serai-alice:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-alice
|
||||
profiles:
|
||||
|
@ -67,7 +65,6 @@ services:
|
|||
VALIDATOR: true
|
||||
|
||||
serai-bob:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-bob
|
||||
profiles:
|
||||
|
@ -81,7 +78,6 @@ services:
|
|||
NAME: Bob
|
||||
|
||||
serai-charlie:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-charlie
|
||||
profiles:
|
||||
|
@ -95,7 +91,6 @@ services:
|
|||
NAME: Charlie
|
||||
|
||||
serai-dave:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-dave
|
||||
profiles:
|
||||
|
@ -107,7 +102,6 @@ services:
|
|||
NAME: Dave
|
||||
|
||||
serai-eve:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-eve
|
||||
profiles:
|
||||
|
@ -119,7 +113,6 @@ services:
|
|||
NAME: Eve
|
||||
|
||||
serai-ferdie:
|
||||
&serai
|
||||
<<: *serai_defaults
|
||||
hostname: serai-ferdie
|
||||
profiles:
|
||||
|
@ -171,6 +164,5 @@ services:
|
|||
context: ./coins/monero/
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "./coins/monero/temp:/temp"
|
||||
- "./coins/monero/scripts:/scripts"
|
||||
entrypoint: /scripts/entry-dev.sh
|
||||
|
|
103
deploy/kubernetes/Makefile
Normal file
103
deploy/kubernetes/Makefile
Normal file
|
@ -0,0 +1,103 @@
|
|||
SHELL := /bin/bash
|
||||
|
||||
check-helm:
|
||||
@helm version || $(MAKE) install-helm
|
||||
|
||||
check-kubectl:
|
||||
@kubectl version || $(MAKE) install-kubectl
|
||||
|
||||
install-helm:
|
||||
@curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
@chmod 700 get_helm.sh
|
||||
@./get_helm.sh
|
||||
@rm get_helm.sh
|
||||
|
||||
install-kubectl:
|
||||
@curl -LO 'https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl'
|
||||
@sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
@rm kubectl
|
||||
|
||||
deploy-base:
|
||||
@docker compose -f ../docker-compose.yml --profile base build --quiet
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-base charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-base,nameOverride=serai-base,\
|
||||
image.envVariables[1].value=base,configMapFile=%
|
||||
|
||||
deploy-bitcoin:
|
||||
@docker compose -f ../docker-compose.yml --profile bitcoin build --quiet
|
||||
@(cat ../coins/bitcoin/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install bitcoin-daemon\
|
||||
charts/bitcoin/ --values charts/bitcoin/values.yaml --set configMapFile=%
|
||||
|
||||
deploy-ethereum:
|
||||
@docker compose -f ../docker-compose.yml --profile ethereum build --quiet
|
||||
@(cat ../coins/ethereum/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install ethereum-daemon\
|
||||
charts/ethereum/ --values charts/ethereum/values.yaml --set configMapFile=%
|
||||
|
||||
deploy-monero:
|
||||
@docker compose -f ../docker-compose.yml --profile monero build --quiet
|
||||
@(cat ../coins/monero/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install monero-daemon\
|
||||
charts/monero/ --values charts/monero/values.yaml --set configMapFile=%
|
||||
|
||||
deploy-cluster-sm:
|
||||
@docker compose -f ../docker-compose.yml --profile cluster-sm build --quiet
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-alice charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-alice,nameOverride=serai-alice,\
|
||||
image.envVariables[1].value=Alice,image.envVariables[2].value="'1'",configMapFile=%
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-charlie charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-charlie,nameOverride=serai-charlie,\
|
||||
image.envVariables[1].value=Charlie,configMapFile=%
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-bob charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-bob,nameOverride=serai-bob,\
|
||||
image.envVariables[1].value=Bob,configMapFile=%
|
||||
|
||||
deploy-cluster-lg: deploy-cluster-sm
|
||||
@docker compose -f ../docker-compose.yml --profile cluster-lg build --quiet
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-dave charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-dave,nameOverride=serai-dave,\
|
||||
image.envVariables[1].value=Dave,configMapFile=%
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-eve charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-eve,nameOverride=serai-eve,\
|
||||
image.envVariables[1].value=Eve,configMapFile=%
|
||||
@(cat ../serai/scripts/entry-dev.sh | base64 -w 0 -) | xargs -I % helm upgrade --install serai-ferdie charts/serai/\
|
||||
--values charts/serai/values.yaml --set image.envVariablesfullnameOverride=serai-ferdie,nameOverride=serai-ferdie,\
|
||||
image.envVariables[1].value=Ferdie,configMapFile=%
|
||||
|
||||
deploy-coins: deploy-bitcoin deploy-ethereum deploy-monero
|
||||
|
||||
deploy-cluster-coins-sm: deploy-cluster-sm deploy-coins
|
||||
|
||||
deploy-cluster-coins-lg: deploy-cluster-lg deploy-coins
|
||||
|
||||
deploy-all: deploy-cluster-coins-lg
|
||||
|
||||
delete-base:
|
||||
@helm delete serai-base
|
||||
|
||||
delete-bitcoin:
|
||||
@helm delete bitcoin-daemon
|
||||
|
||||
delete-ethereum:
|
||||
@helm delete ethereum-daemon
|
||||
|
||||
delete-monero:
|
||||
@helm delete monero-daemon
|
||||
|
||||
delete-cluster-lg: delete-cluster-sm
|
||||
@helm delete serai-dave
|
||||
@helm delete serai-eve
|
||||
@helm delete serai-ferdie
|
||||
|
||||
delete-cluster-sm:
|
||||
@helm delete serai-alice
|
||||
@helm delete serai-charlie
|
||||
@helm delete serai-bob
|
||||
|
||||
delete-coins: delete-bitcoin delete-ethereum delete-monero
|
||||
|
||||
delete-cluster-coins-sm: delete-cluster-sm delete-coins
|
||||
|
||||
delete-cluster-coins-lg: delete-cluster-lg delete-coins
|
||||
|
||||
delete-all: delete-cluster-coins-lg
|
||||
|
||||
check-dependencies: check-helm check-kubectl
|
41
deploy/kubernetes/README.md
Normal file
41
deploy/kubernetes/README.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Kubernetes
|
||||
## Run with Kubernetes
|
||||
Running the Serai infrastructure is easy with Kubernetes.
|
||||
|
||||
We utilize Makefile to easily orchestrate various pieces of the infrastructure on kubernetes.
|
||||
|
||||
**Example to deploy:** `make deploy-<Profile_Name>`
|
||||
```bash
|
||||
make deploy-cluster-sm
|
||||
```
|
||||
**Example to delete:** `make -i delete-<Profile_Name>`
|
||||
```bash
|
||||
make delete-cluster-sm
|
||||
```
|
||||
|
||||
All commands are assumed to be ran from the kubernetes folder, not the serai root folder.
|
||||
|
||||
### Profiles:
|
||||
* deploy-base - single node, named base
|
||||
* deploy-coins - node clients for coins only (BTC, ETH, XMR)
|
||||
* deploy-cluster-sm - Alice (Validator), Bob, Charlie
|
||||
* deploy-cluster-coins-sm - cluster-sm with coins
|
||||
* deploy-cluster-lg - Alice (Validator), Bob, Charlie, Dave, Eve, Ferdie
|
||||
* deploy-cluster-coins-lg - cluster-lg with coins
|
||||
* deploy-monero - full node monero only
|
||||
* deploy-bitcoin - full node bitcoin only
|
||||
* deploy-ethereum - full node ethereum only
|
||||
|
||||
## Requirements for Linux
|
||||
* Local built images of serai and coins, please follow the Instructions [here](../README.md)
|
||||
* Running kubernetes cluster (version >= 1.19)
|
||||
* Curl tool
|
||||
* Make tool
|
||||
* Kubectl, check if not installed
|
||||
```bash
|
||||
make check-kubectl
|
||||
```
|
||||
* Helm, check if not installed
|
||||
```bash
|
||||
make check-helm
|
||||
```
|
5
deploy/kubernetes/charts/bitcoin/Chart.yaml
Normal file
5
deploy/kubernetes/charts/bitcoin/Chart.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v2
|
||||
name: bitcoin
|
||||
description: A Helm chart for bitcoin-daemon
|
||||
type: application
|
||||
version: 0.1.0
|
42
deploy/kubernetes/charts/bitcoin/templates/_helpers.tpl
Normal file
42
deploy/kubernetes/charts/bitcoin/templates/_helpers.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
{{- define "bitcoin.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "bitcoin.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "bitcoin.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "bitcoin.labels" -}}
|
||||
helm.sh/chart: {{ include "bitcoin.chart" . }}
|
||||
{{ include "bitcoin.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "bitcoin.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "bitcoin.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "bitcoin.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "bitcoin.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-configmap
|
||||
data:
|
||||
entry-dev.sh: |
|
||||
{{ .Values.configMapFile | b64dec | indent 4}}
|
88
deploy/kubernetes/charts/bitcoin/templates/deployment.yaml
Normal file
88
deploy/kubernetes/charts/bitcoin/templates/deployment.yaml
Normal file
|
@ -0,0 +1,88 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "bitcoin.fullname" . }}
|
||||
labels:
|
||||
{{- include "bitcoin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "bitcoin.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "bitcoin.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "bitcoin.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if hasKey .Values.image "ports" }}
|
||||
ports:
|
||||
{{- range .Values.image.ports }}
|
||||
- name: {{ .name }}
|
||||
containerPort: {{ .containerPort }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "command" }}
|
||||
command:
|
||||
{{- toYaml .Values.image.command | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "args" }}
|
||||
args:
|
||||
{{- toYaml .Values.image.args | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "envVariables" }}
|
||||
env:
|
||||
{{- toYaml .Values.image.envVariables | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "volumeMounts" }}
|
||||
volumeMounts:
|
||||
{{- range .Values.image.volumeMounts }}
|
||||
- mountPath: {{ .mountPath }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values "volumes" }}
|
||||
volumes:
|
||||
{{- range .Values.volumes }}
|
||||
- configMap:
|
||||
defaultMode: {{ .configMap.defaultMode }}
|
||||
name: {{ $.Release.Name}}-{{ .configMap.name }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
50
deploy/kubernetes/charts/bitcoin/templates/ingress.yaml
Normal file
50
deploy/kubernetes/charts/bitcoin/templates/ingress.yaml
Normal file
|
@ -0,0 +1,50 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "bitcoin.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "bitcoin.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if .pathType }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
24
deploy/kubernetes/charts/bitcoin/templates/service.yaml
Normal file
24
deploy/kubernetes/charts/bitcoin/templates/service.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "bitcoin.fullname" . }}
|
||||
labels:
|
||||
{{- include "bitcoin.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
{{- if hasKey .Values.service "ports" }}
|
||||
{{- range .Values.service.ports }}
|
||||
- port: {{ .port }}
|
||||
name: {{ .name }}
|
||||
targetPort: {{ .targetPort }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "bitcoin.selectorLabels" . | nindent 4 }}
|
74
deploy/kubernetes/charts/bitcoin/values.yaml
Normal file
74
deploy/kubernetes/charts/bitcoin/values.yaml
Normal file
|
@ -0,0 +1,74 @@
|
|||
replicaCount: 1
|
||||
|
||||
net: mainnet
|
||||
|
||||
image:
|
||||
repository: serai-dev-bitcoin
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "latest"
|
||||
ports:
|
||||
- name: p2p
|
||||
containerPort: 18444
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
containerPort: 18443
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: /scripts
|
||||
name: configmap-volume
|
||||
args:
|
||||
- bash
|
||||
- /scripts/entry-dev.sh
|
||||
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: configmap
|
||||
name: configmap-volume
|
||||
|
||||
configMapFile: "entry-dev.sh"
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
serviceAccount:
|
||||
create: false
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
securityContext: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: p2p
|
||||
port: 18444
|
||||
targetPort: p2p
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
port: 18443
|
||||
targetPort: rpc
|
||||
protocol: TCP
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
tls: []
|
||||
|
||||
resources: {}
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
5
deploy/kubernetes/charts/ethereum/Chart.yaml
Normal file
5
deploy/kubernetes/charts/ethereum/Chart.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v2
|
||||
name: ethereum
|
||||
description: A Helm chart for ethereum-daemon
|
||||
type: application
|
||||
version: 0.1.0
|
42
deploy/kubernetes/charts/ethereum/templates/_helpers.tpl
Normal file
42
deploy/kubernetes/charts/ethereum/templates/_helpers.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
{{- define "ethereum.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "ethereum.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "ethereum.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "ethereum.labels" -}}
|
||||
helm.sh/chart: {{ include "ethereum.chart" . }}
|
||||
{{ include "ethereum.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "ethereum.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "ethereum.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "ethereum.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "ethereum.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-configmap
|
||||
data:
|
||||
entry-dev.sh: |
|
||||
{{ .Values.configMapFile | b64dec | indent 4}}
|
89
deploy/kubernetes/charts/ethereum/templates/deployment.yaml
Normal file
89
deploy/kubernetes/charts/ethereum/templates/deployment.yaml
Normal file
|
@ -0,0 +1,89 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "ethereum.fullname" . }}
|
||||
labels:
|
||||
{{- include "ethereum.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "ethereum.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "ethereum.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "ethereum.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if hasKey .Values.image "ports" }}
|
||||
ports:
|
||||
{{- range .Values.image.ports }}
|
||||
- name: {{ .name }}
|
||||
containerPort: {{ .containerPort }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "command" }}
|
||||
command:
|
||||
{{- toYaml .Values.image.command | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "args" }}
|
||||
args:
|
||||
{{- toYaml .Values.image.args | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "envVariables" }}
|
||||
env:
|
||||
{{- toYaml .Values.image.envVariables | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "volumeMounts" }}
|
||||
volumeMounts:
|
||||
{{- range .Values.image.volumeMounts }}
|
||||
- mountPath: {{ .mountPath }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values "volumes" }}
|
||||
volumes:
|
||||
{{- range .Values.volumes }}
|
||||
- configMap:
|
||||
defaultMode: {{ .configMap.defaultMode }}
|
||||
name: {{ $.Release.Name}}-{{ .configMap.name }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
50
deploy/kubernetes/charts/ethereum/templates/ingress.yaml
Normal file
50
deploy/kubernetes/charts/ethereum/templates/ingress.yaml
Normal file
|
@ -0,0 +1,50 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "ethereum.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "ethereum.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if .pathType }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
24
deploy/kubernetes/charts/ethereum/templates/service.yaml
Normal file
24
deploy/kubernetes/charts/ethereum/templates/service.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "ethereum.fullname" . }}
|
||||
labels:
|
||||
{{- include "ethereum.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
{{- if hasKey .Values.service "ports" }}
|
||||
{{- range .Values.service.ports }}
|
||||
- port: {{ .port }}
|
||||
name: {{ .name }}
|
||||
targetPort: {{ .targetPort }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "ethereum.selectorLabels" . | nindent 4 }}
|
60
deploy/kubernetes/charts/ethereum/values.yaml
Normal file
60
deploy/kubernetes/charts/ethereum/values.yaml
Normal file
|
@ -0,0 +1,60 @@
|
|||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: serai-dev-ethereum
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "latest"
|
||||
|
||||
ports:
|
||||
- name: rpc
|
||||
containerPort: 8545
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: /scripts
|
||||
name: configmap-volume
|
||||
args:
|
||||
- bash
|
||||
- /scripts/entry-dev.sh
|
||||
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: configmap
|
||||
name: configmap-volume
|
||||
|
||||
configMapFile: "entry-dev.sh"
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
serviceAccount:
|
||||
create: false
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
securityContext: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8545
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
tls: []
|
||||
|
||||
resources: {}
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
5
deploy/kubernetes/charts/monero/Chart.yaml
Normal file
5
deploy/kubernetes/charts/monero/Chart.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v2
|
||||
name: monero
|
||||
description: A Helm chart for monero-daemon
|
||||
type: application
|
||||
version: 0.1.0
|
42
deploy/kubernetes/charts/monero/templates/_helpers.tpl
Normal file
42
deploy/kubernetes/charts/monero/templates/_helpers.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
{{- define "monero.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "monero.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "monero.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "monero.labels" -}}
|
||||
helm.sh/chart: {{ include "monero.chart" . }}
|
||||
{{ include "monero.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "monero.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "monero.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "monero.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "monero.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
7
deploy/kubernetes/charts/monero/templates/configmap.yaml
Normal file
7
deploy/kubernetes/charts/monero/templates/configmap.yaml
Normal file
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-configmap
|
||||
data:
|
||||
entry-dev.sh: |
|
||||
{{ .Values.configMapFile | b64dec | indent 4}}
|
88
deploy/kubernetes/charts/monero/templates/deployment.yaml
Normal file
88
deploy/kubernetes/charts/monero/templates/deployment.yaml
Normal file
|
@ -0,0 +1,88 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "monero.fullname" . }}
|
||||
labels:
|
||||
{{- include "monero.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "monero.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "monero.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "monero.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if hasKey .Values.image "ports" }}
|
||||
ports:
|
||||
{{- range .Values.image.ports }}
|
||||
- name: {{ .name }}
|
||||
containerPort: {{ .containerPort }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "command" }}
|
||||
command:
|
||||
{{- toYaml .Values.image.command | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "args" }}
|
||||
args:
|
||||
{{- toYaml .Values.image.args | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "envVariables" }}
|
||||
env:
|
||||
{{- toYaml .Values.image.envVariables | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "volumeMounts" }}
|
||||
volumeMounts:
|
||||
{{- range .Values.image.volumeMounts }}
|
||||
- mountPath: {{ .mountPath }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values "volumes" }}
|
||||
volumes:
|
||||
{{- range .Values.volumes }}
|
||||
- configMap:
|
||||
defaultMode: {{ .configMap.defaultMode }}
|
||||
name: {{ $.Release.Name}}-{{ .configMap.name }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
50
deploy/kubernetes/charts/monero/templates/ingress.yaml
Normal file
50
deploy/kubernetes/charts/monero/templates/ingress.yaml
Normal file
|
@ -0,0 +1,50 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "monero.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "monero.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if .pathType }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
24
deploy/kubernetes/charts/monero/templates/service.yaml
Normal file
24
deploy/kubernetes/charts/monero/templates/service.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "monero.fullname" . }}
|
||||
labels:
|
||||
{{- include "monero.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
{{- if hasKey .Values.service "ports" }}
|
||||
{{- range .Values.service.ports }}
|
||||
- port: {{ .port }}
|
||||
name: {{ .name }}
|
||||
targetPort: {{ .targetPort }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "monero.selectorLabels" . | nindent 4 }}
|
72
deploy/kubernetes/charts/monero/values.yaml
Normal file
72
deploy/kubernetes/charts/monero/values.yaml
Normal file
|
@ -0,0 +1,72 @@
|
|||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: serai-dev-monero
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "latest"
|
||||
ports:
|
||||
- name: p2p
|
||||
containerPort: 18080
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
containerPort: 18081
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: /scripts
|
||||
name: configmap-volume
|
||||
args:
|
||||
- bash
|
||||
- /scripts/entry-dev.sh
|
||||
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: configmap
|
||||
name: configmap-volume
|
||||
|
||||
configMapFile: "entry-dev.sh"
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
serviceAccount:
|
||||
create: false
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
securityContext: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: p2p
|
||||
port: 18080
|
||||
targetPort: p2p
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
port: 18081
|
||||
targetPort: rpc
|
||||
protocol: TCP
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
tls: []
|
||||
|
||||
resources: {}
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
5
deploy/kubernetes/charts/serai/Chart.yaml
Normal file
5
deploy/kubernetes/charts/serai/Chart.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v2
|
||||
name: serai
|
||||
description: A Helm chart for serai
|
||||
type: application
|
||||
version: 0.1.0
|
42
deploy/kubernetes/charts/serai/templates/_helpers.tpl
Normal file
42
deploy/kubernetes/charts/serai/templates/_helpers.tpl
Normal file
|
@ -0,0 +1,42 @@
|
|||
{{- define "serai-base.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "serai-base.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 253 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "serai-base.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 253 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "serai-base.labels" -}}
|
||||
helm.sh/chart: {{ include "serai-base.chart" . }}
|
||||
{{ include "serai-base.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "serai-base.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "serai-base.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "serai-base.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "serai-base.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
7
deploy/kubernetes/charts/serai/templates/configmap.yaml
Normal file
7
deploy/kubernetes/charts/serai/templates/configmap.yaml
Normal file
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-configmap
|
||||
data:
|
||||
entry-dev.sh: |
|
||||
{{ .Values.configMapFile | b64dec | indent 4}}
|
88
deploy/kubernetes/charts/serai/templates/deployment.yaml
Normal file
88
deploy/kubernetes/charts/serai/templates/deployment.yaml
Normal file
|
@ -0,0 +1,88 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "serai-base.fullname" . }}
|
||||
labels:
|
||||
{{- include "serai-base.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "serai-base.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "serai-base.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "serai-base.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- if hasKey .Values.image "ports" }}
|
||||
ports:
|
||||
{{- range .Values.image.ports }}
|
||||
- name: {{ .name }}
|
||||
containerPort: {{ .containerPort }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "command" }}
|
||||
command:
|
||||
{{- toYaml .Values.image.command | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "args" }}
|
||||
args:
|
||||
{{- toYaml .Values.image.args | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "envVariables" }}
|
||||
env:
|
||||
{{- toYaml .Values.image.envVariables | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if hasKey .Values.image "volumeMounts" }}
|
||||
volumeMounts:
|
||||
{{- range .Values.image.volumeMounts }}
|
||||
- mountPath: {{ .mountPath }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if hasKey .Values "volumes" }}
|
||||
volumes:
|
||||
{{- range .Values.volumes }}
|
||||
- configMap:
|
||||
defaultMode: {{ .configMap.defaultMode }}
|
||||
name: {{ $.Release.Name}}-{{ .configMap.name }}
|
||||
name: {{ $.Release.Name}}-{{ .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
50
deploy/kubernetes/charts/serai/templates/ingress.yaml
Normal file
50
deploy/kubernetes/charts/serai/templates/ingress.yaml
Normal file
|
@ -0,0 +1,50 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "serai-base.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "serai-base.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if .pathType }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
24
deploy/kubernetes/charts/serai/templates/service.yaml
Normal file
24
deploy/kubernetes/charts/serai/templates/service.yaml
Normal file
|
@ -0,0 +1,24 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "serai-base.fullname" . }}
|
||||
labels:
|
||||
{{- include "serai-base.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
{{- if hasKey .Values.service "ports" }}
|
||||
{{- range .Values.service.ports }}
|
||||
- port: {{ .port }}
|
||||
name: {{ .name }}
|
||||
targetPort: {{ .targetPort }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "serai-base.selectorLabels" . | nindent 4 }}
|
92
deploy/kubernetes/charts/serai/values.yaml
Normal file
92
deploy/kubernetes/charts/serai/values.yaml
Normal file
|
@ -0,0 +1,92 @@
|
|||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: serai
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "dev"
|
||||
ports:
|
||||
- name: p2p
|
||||
containerPort: 30333
|
||||
protocol: TCP
|
||||
- name: prometheus
|
||||
containerPort: 9615
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
containerPort: 9933
|
||||
protocol: TCP
|
||||
- name: ws
|
||||
containerPort: 9944
|
||||
protocol: TCP
|
||||
|
||||
volumeMounts:
|
||||
- mountPath: /scripts
|
||||
name: configmap-volume
|
||||
envVariables:
|
||||
- name: CHAIN
|
||||
value: dev
|
||||
- name: NAME
|
||||
value: base
|
||||
- name: VALIDATOR
|
||||
value:
|
||||
args:
|
||||
- bash
|
||||
- /scripts/entry-dev.sh
|
||||
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: configmap
|
||||
name: configmap-volume
|
||||
|
||||
configMapFile: "entry-dev.sh"
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
serviceAccount:
|
||||
create: false
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
|
||||
securityContext: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: p2p
|
||||
port: 30333
|
||||
targetPort: p2p
|
||||
protocol: TCP
|
||||
- name: prometheus
|
||||
port: 9615
|
||||
targetPort: prometheus
|
||||
protocol: TCP
|
||||
- name: rpc
|
||||
port: 9933
|
||||
targetPort: rpc
|
||||
protocol: TCP
|
||||
- name: ws
|
||||
port: 9944
|
||||
targetPort: ws
|
||||
protocol: TCP
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
tls: []
|
||||
|
||||
resources: {}
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
|
@ -16,7 +16,7 @@ WORKDIR /serai
|
|||
RUN rustup update
|
||||
|
||||
# Install Solc @ 0.8.16
|
||||
RUN pip3 install solc-select
|
||||
RUN pip3 install solc-select==0.2.1
|
||||
RUN solc-select install 0.8.16
|
||||
RUN solc-select use 0.8.16
|
||||
|
||||
|
|
|
@ -3,35 +3,39 @@ name = "serai-processor"
|
|||
version = "0.1.0"
|
||||
description = "Multichain processor premised on canonicity to reach distributed consensus automatically"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/processor"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/processor"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = []
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
rand_core = "0.6"
|
||||
thiserror = "1"
|
||||
|
||||
hex = "0.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
sha3 = "0.10"
|
||||
blake2 = "0.10"
|
||||
|
||||
group = "0.12"
|
||||
k256 = { version = "0.11", features = ["arithmetic", "keccak256", "ecdsa"] }
|
||||
|
||||
curve25519-dalek = { version = "3", features = ["std"] }
|
||||
|
||||
transcript = { package = "flexible-transcript", path = "../crypto/transcript", features = ["recommended"] }
|
||||
dalek-ff-group = { path = "../crypto/dalek-ff-group" }
|
||||
frost = { package = "modular-frost", path = "../crypto/frost", features = ["secp256k1", "ed25519"] }
|
||||
frost = { package = "modular-frost", path = "../crypto/frost", features = ["ed25519"] }
|
||||
|
||||
monero-serai = { path = "../coins/monero", features = ["multisig"] }
|
||||
|
||||
[dev-dependencies]
|
||||
group = "0.12"
|
||||
rand_core = "0.6"
|
||||
|
||||
hex = "0.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
futures = "0.3"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
||||
frost = { package = "modular-frost", path = "../crypto/frost", features = ["ed25519", "tests"] }
|
||||
|
|
|
@ -47,19 +47,22 @@ pub trait Coin {
|
|||
// Doesn't have to take self, enables some level of caching which is pleasant
|
||||
fn address(&self, key: <Self::Curve as Curve>::G) -> Self::Address;
|
||||
|
||||
async fn get_height(&self) -> Result<usize, CoinError>;
|
||||
async fn get_block(&self, height: usize) -> Result<Self::Block, CoinError>;
|
||||
async fn get_latest_block_number(&self) -> Result<usize, CoinError>;
|
||||
async fn get_block(&self, number: usize) -> Result<Self::Block, CoinError>;
|
||||
async fn get_outputs(
|
||||
&self,
|
||||
block: &Self::Block,
|
||||
key: <Self::Curve as Curve>::G,
|
||||
) -> Result<Vec<Self::Output>, CoinError>;
|
||||
|
||||
// TODO: Remove
|
||||
async fn is_confirmed(&self, tx: &[u8]) -> Result<bool, CoinError>;
|
||||
|
||||
async fn prepare_send(
|
||||
&self,
|
||||
keys: FrostKeys<Self::Curve>,
|
||||
transcript: RecommendedTranscript,
|
||||
height: usize,
|
||||
block_number: usize,
|
||||
inputs: Vec<Self::Output>,
|
||||
payments: &[(Self::Address, u64)],
|
||||
fee: Self::Fee,
|
||||
|
@ -76,6 +79,9 @@ pub trait Coin {
|
|||
tx: &Self::Transaction,
|
||||
) -> Result<(Vec<u8>, Vec<<Self::Output as Output>::Id>), CoinError>;
|
||||
|
||||
#[cfg(test)]
|
||||
async fn get_fee(&self) -> Self::Fee;
|
||||
|
||||
#[cfg(test)]
|
||||
async fn mine_block(&self);
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ use monero_serai::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
additional_key,
|
||||
coin::{CoinError, Output as OutputTrait, Coin},
|
||||
view_key,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -54,12 +54,13 @@ impl OutputTrait for Output {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SignableTransaction(
|
||||
FrostKeys<Ed25519>,
|
||||
RecommendedTranscript,
|
||||
usize,
|
||||
MSignableTransaction,
|
||||
);
|
||||
pub struct SignableTransaction {
|
||||
keys: FrostKeys<Ed25519>,
|
||||
transcript: RecommendedTranscript,
|
||||
// Monero height, defined as the length of the chain
|
||||
height: usize,
|
||||
actual: MSignableTransaction,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Monero {
|
||||
|
@ -69,7 +70,7 @@ pub struct Monero {
|
|||
|
||||
impl Monero {
|
||||
pub async fn new(url: String) -> Monero {
|
||||
Monero { rpc: Rpc::new(url), view: view_key::<Monero>(0).0 }
|
||||
Monero { rpc: Rpc::new(url), view: additional_key::<Monero>(0).0 }
|
||||
}
|
||||
|
||||
fn scanner(&self, spend: dfg::EdwardsPoint) -> Scanner {
|
||||
|
@ -121,12 +122,13 @@ impl Coin for Monero {
|
|||
self.scanner(key).address()
|
||||
}
|
||||
|
||||
async fn get_height(&self) -> Result<usize, CoinError> {
|
||||
self.rpc.get_height().await.map_err(|_| CoinError::ConnectionError)
|
||||
async fn get_latest_block_number(&self) -> Result<usize, CoinError> {
|
||||
// Monero defines height as chain length, so subtract 1 for block number
|
||||
Ok(self.rpc.get_height().await.map_err(|_| CoinError::ConnectionError)? - 1)
|
||||
}
|
||||
|
||||
async fn get_block(&self, height: usize) -> Result<Self::Block, CoinError> {
|
||||
self.rpc.get_block(height).await.map_err(|_| CoinError::ConnectionError)
|
||||
async fn get_block(&self, number: usize) -> Result<Self::Block, CoinError> {
|
||||
self.rpc.get_block(number).await.map_err(|_| CoinError::ConnectionError)
|
||||
}
|
||||
|
||||
async fn get_outputs(
|
||||
|
@ -147,21 +149,27 @@ impl Coin for Monero {
|
|||
)
|
||||
}
|
||||
|
||||
async fn is_confirmed(&self, tx: &[u8]) -> Result<bool, CoinError> {
|
||||
let tx_block_number =
|
||||
self.rpc.get_transaction_block_number(tx).await.map_err(|_| CoinError::ConnectionError)?;
|
||||
Ok((self.get_latest_block_number().await?.saturating_sub(tx_block_number) + 1) >= 10)
|
||||
}
|
||||
|
||||
async fn prepare_send(
|
||||
&self,
|
||||
keys: FrostKeys<Ed25519>,
|
||||
transcript: RecommendedTranscript,
|
||||
height: usize,
|
||||
block_number: usize,
|
||||
mut inputs: Vec<Output>,
|
||||
payments: &[(Address, u64)],
|
||||
fee: Fee,
|
||||
) -> Result<SignableTransaction, CoinError> {
|
||||
let spend = keys.group_key();
|
||||
Ok(SignableTransaction(
|
||||
Ok(SignableTransaction {
|
||||
keys,
|
||||
transcript,
|
||||
height,
|
||||
MSignableTransaction::new(
|
||||
height: block_number + 1,
|
||||
actual: MSignableTransaction::new(
|
||||
self.rpc.get_protocol().await.unwrap(), // TODO: Make this deterministic
|
||||
inputs.drain(..).map(|input| input.0).collect(),
|
||||
payments.to_vec(),
|
||||
|
@ -170,7 +178,7 @@ impl Coin for Monero {
|
|||
fee,
|
||||
)
|
||||
.map_err(|_| CoinError::ConnectionError)?,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
async fn attempt_send(
|
||||
|
@ -179,13 +187,13 @@ impl Coin for Monero {
|
|||
included: &[u16],
|
||||
) -> Result<Self::TransactionMachine, CoinError> {
|
||||
transaction
|
||||
.3
|
||||
.actual
|
||||
.clone()
|
||||
.multisig(
|
||||
&self.rpc,
|
||||
transaction.0.clone(),
|
||||
transaction.1.clone(),
|
||||
transaction.2,
|
||||
transaction.keys.clone(),
|
||||
transaction.transcript.clone(),
|
||||
transaction.height,
|
||||
included.to_vec(),
|
||||
)
|
||||
.await
|
||||
|
@ -201,6 +209,11 @@ impl Coin for Monero {
|
|||
Ok((tx.hash().to_vec(), tx.prefix.outputs.iter().map(|output| output.key.to_bytes()).collect()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
async fn get_fee(&self) -> Self::Fee {
|
||||
self.rpc.get_fee().await.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
async fn mine_block(&self) {
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
|
@ -225,7 +238,7 @@ impl Coin for Monero {
|
|||
async fn test_send(&self, address: Self::Address) {
|
||||
use rand_core::OsRng;
|
||||
|
||||
let height = self.get_height().await.unwrap();
|
||||
let new_block = self.get_latest_block_number().await.unwrap() + 1;
|
||||
|
||||
self.mine_block().await;
|
||||
for _ in 0 .. 7 {
|
||||
|
@ -233,7 +246,7 @@ impl Coin for Monero {
|
|||
}
|
||||
|
||||
let outputs = Self::empty_scanner()
|
||||
.scan(&self.rpc, &self.rpc.get_block(height).await.unwrap())
|
||||
.scan(&self.rpc, &self.rpc.get_block(new_block).await.unwrap())
|
||||
.await
|
||||
.unwrap()
|
||||
.swap_remove(0)
|
||||
|
|
|
@ -7,6 +7,7 @@ use frost::{curve::Curve, FrostError};
|
|||
|
||||
mod coin;
|
||||
use coin::{CoinError, Coin};
|
||||
|
||||
mod wallet;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -30,9 +31,10 @@ pub enum SignError {
|
|||
NetworkError(NetworkError),
|
||||
}
|
||||
|
||||
// Generate a static view key for a given chain in a globally consistent manner
|
||||
// Generate a static additional key for a given chain in a globally consistent manner
|
||||
// Doesn't consider the current group key to increase the simplicity of verifying Serai's status
|
||||
// Takes an index, k, for more modern privacy protocols which use multiple view keys
|
||||
pub fn view_key<C: Coin>(k: u64) -> <C::Curve as Curve>::F {
|
||||
C::Curve::hash_to_F(b"Serai DEX View Key", &[C::ID, &k.to_le_bytes()].concat())
|
||||
// Takes an index, k, to support protocols which use multiple secondary keys
|
||||
// Presumably a view key
|
||||
pub(crate) fn additional_key<C: Coin>(k: u64) -> <C::Curve as Curve>::F {
|
||||
C::Curve::hash_to_F(b"Serai DEX Additional Key", &[C::ID, &k.to_le_bytes()].concat())
|
||||
}
|
||||
|
|
|
@ -59,9 +59,9 @@ impl Network for LocalNetwork {
|
|||
}
|
||||
|
||||
async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
|
||||
// Mine a block so there's a confirmed height
|
||||
// Mine blocks so there's a confirmed block
|
||||
coin.mine_block().await;
|
||||
let height = coin.get_height().await.unwrap();
|
||||
let latest = coin.get_latest_block_number().await.unwrap();
|
||||
|
||||
let mut keys = frost::tests::key_gen::<_, C::Curve>(&mut OsRng);
|
||||
let threshold = keys[&1].params().t();
|
||||
|
@ -70,13 +70,13 @@ async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
|
|||
let mut wallets = vec![];
|
||||
for i in 1 ..= threshold {
|
||||
let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone());
|
||||
wallet.acknowledge_height(0, height);
|
||||
wallet.acknowledge_block(0, latest);
|
||||
wallet.add_keys(&WalletKeys::new(keys.remove(&i).unwrap(), 0));
|
||||
wallets.push(wallet);
|
||||
}
|
||||
|
||||
// Get the chain to a height where blocks have sufficient confirmations
|
||||
while (height + C::CONFIRMATIONS) > coin.get_height().await.unwrap() {
|
||||
// Get the chain to a length where blocks have sufficient confirmations
|
||||
while (latest + (C::CONFIRMATIONS - 1)) > coin.get_latest_block_number().await.unwrap() {
|
||||
coin.mine_block().await;
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
|
|||
for (network, wallet) in networks.iter_mut().zip(wallets.iter_mut()) {
|
||||
wallet.poll().await.unwrap();
|
||||
|
||||
let height = coin.get_height().await.unwrap();
|
||||
wallet.acknowledge_height(1, height - 10);
|
||||
let latest = coin.get_latest_block_number().await.unwrap();
|
||||
wallet.acknowledge_block(1, latest - (C::CONFIRMATIONS - 1));
|
||||
let signable = wallet
|
||||
.prepare_sends(1, vec![(wallet.address(), 10000000000)], fee)
|
||||
.await
|
||||
|
@ -112,6 +112,6 @@ async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
|
|||
#[tokio::test]
|
||||
async fn monero() {
|
||||
let monero = Monero::new("http://127.0.0.1:18081".to_string()).await;
|
||||
let fee = monero.rpc.get_fee().await.unwrap();
|
||||
let fee = monero.get_fee().await;
|
||||
test_send(monero, fee).await;
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ use crate::{
|
|||
|
||||
pub struct WalletKeys<C: Curve> {
|
||||
keys: FrostKeys<C>,
|
||||
creation_height: usize,
|
||||
creation_block: usize,
|
||||
}
|
||||
|
||||
impl<C: Curve> WalletKeys<C> {
|
||||
pub fn new(keys: FrostKeys<C>, creation_height: usize) -> WalletKeys<C> {
|
||||
WalletKeys { keys, creation_height }
|
||||
pub fn new(keys: FrostKeys<C>, creation_block: usize) -> WalletKeys<C> {
|
||||
WalletKeys { keys, creation_block }
|
||||
}
|
||||
|
||||
// Bind this key to a specific network by applying an additive offset
|
||||
|
@ -45,42 +45,42 @@ impl<C: Curve> WalletKeys<C> {
|
|||
}
|
||||
|
||||
pub trait CoinDb {
|
||||
// Set a height as scanned to
|
||||
fn scanned_to_height(&mut self, height: usize);
|
||||
// Acknowledge a given coin height for a canonical height
|
||||
fn acknowledge_height(&mut self, canonical: usize, height: usize);
|
||||
// Set a block as scanned to
|
||||
fn scanned_to_block(&mut self, block: usize);
|
||||
// Acknowledge a specific block number as part of a canonical block
|
||||
fn acknowledge_block(&mut self, canonical: usize, block: usize);
|
||||
|
||||
// Adds an output to the DB. Returns false if the output was already added
|
||||
fn add_output<O: Output>(&mut self, output: &O) -> bool;
|
||||
|
||||
// Height this coin has been scanned to
|
||||
fn scanned_height(&self) -> usize;
|
||||
// Acknowledged height for a given canonical height
|
||||
fn acknowledged_height(&self, canonical: usize) -> usize;
|
||||
// Block this coin has been scanned to (inclusive)
|
||||
fn scanned_block(&self) -> usize;
|
||||
// Acknowledged block for a given canonical block
|
||||
fn acknowledged_block(&self, canonical: usize) -> usize;
|
||||
}
|
||||
|
||||
pub struct MemCoinDb {
|
||||
// Height this coin has been scanned to
|
||||
scanned_height: usize,
|
||||
// Acknowledged height for a given canonical height
|
||||
acknowledged_heights: HashMap<usize, usize>,
|
||||
scanned_block: usize,
|
||||
// Acknowledged block for a given canonical block
|
||||
acknowledged_blocks: HashMap<usize, usize>,
|
||||
outputs: HashMap<Vec<u8>, Vec<u8>>,
|
||||
}
|
||||
|
||||
impl MemCoinDb {
|
||||
pub fn new() -> MemCoinDb {
|
||||
MemCoinDb { scanned_height: 0, acknowledged_heights: HashMap::new(), outputs: HashMap::new() }
|
||||
MemCoinDb { scanned_block: 0, acknowledged_blocks: HashMap::new(), outputs: HashMap::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl CoinDb for MemCoinDb {
|
||||
fn scanned_to_height(&mut self, height: usize) {
|
||||
self.scanned_height = height;
|
||||
fn scanned_to_block(&mut self, block: usize) {
|
||||
self.scanned_block = block;
|
||||
}
|
||||
|
||||
fn acknowledge_height(&mut self, canonical: usize, height: usize) {
|
||||
debug_assert!(!self.acknowledged_heights.contains_key(&canonical));
|
||||
self.acknowledged_heights.insert(canonical, height);
|
||||
fn acknowledge_block(&mut self, canonical: usize, block: usize) {
|
||||
debug_assert!(!self.acknowledged_blocks.contains_key(&canonical));
|
||||
self.acknowledged_blocks.insert(canonical, block);
|
||||
}
|
||||
|
||||
fn add_output<O: Output>(&mut self, output: &O) -> bool {
|
||||
|
@ -96,12 +96,12 @@ impl CoinDb for MemCoinDb {
|
|||
true
|
||||
}
|
||||
|
||||
fn scanned_height(&self) -> usize {
|
||||
self.scanned_height
|
||||
fn scanned_block(&self) -> usize {
|
||||
self.scanned_block
|
||||
}
|
||||
|
||||
fn acknowledged_height(&self, canonical: usize) -> usize {
|
||||
self.acknowledged_heights[&canonical]
|
||||
fn acknowledged_block(&self, canonical: usize) -> usize {
|
||||
self.acknowledged_blocks[&canonical]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,36 +212,38 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
Wallet { db, coin, keys: vec![], pending: vec![] }
|
||||
}
|
||||
|
||||
pub fn scanned_height(&self) -> usize {
|
||||
self.db.scanned_height()
|
||||
pub fn scanned_block(&self) -> usize {
|
||||
self.db.scanned_block()
|
||||
}
|
||||
pub fn acknowledge_height(&mut self, canonical: usize, height: usize) {
|
||||
self.db.acknowledge_height(canonical, height);
|
||||
if height > self.db.scanned_height() {
|
||||
self.db.scanned_to_height(height);
|
||||
}
|
||||
pub fn acknowledge_block(&mut self, canonical: usize, block: usize) {
|
||||
self.db.acknowledge_block(canonical, block);
|
||||
}
|
||||
pub fn acknowledged_height(&self, canonical: usize) -> usize {
|
||||
self.db.acknowledged_height(canonical)
|
||||
pub fn acknowledged_block(&self, canonical: usize) -> usize {
|
||||
self.db.acknowledged_block(canonical)
|
||||
}
|
||||
|
||||
pub fn add_keys(&mut self, keys: &WalletKeys<C::Curve>) {
|
||||
// Doesn't use +1 as this is height, not block index, and poll moves by block index
|
||||
self.pending.push((self.acknowledged_height(keys.creation_height), keys.bind(C::ID)));
|
||||
self.pending.push((self.acknowledged_block(keys.creation_block), keys.bind(C::ID)));
|
||||
}
|
||||
|
||||
pub fn address(&self) -> C::Address {
|
||||
self.coin.address(self.keys[self.keys.len() - 1].0.group_key())
|
||||
}
|
||||
|
||||
// TODO: Remove
|
||||
pub async fn is_confirmed(&mut self, tx: &[u8]) -> Result<bool, CoinError> {
|
||||
self.coin.is_confirmed(tx).await
|
||||
}
|
||||
|
||||
pub async fn poll(&mut self) -> Result<(), CoinError> {
|
||||
if self.coin.get_height().await? < C::CONFIRMATIONS {
|
||||
if self.coin.get_latest_block_number().await? < (C::CONFIRMATIONS - 1) {
|
||||
return Ok(());
|
||||
}
|
||||
let confirmed_block = self.coin.get_height().await? - C::CONFIRMATIONS;
|
||||
let confirmed_block = self.coin.get_latest_block_number().await? - (C::CONFIRMATIONS - 1);
|
||||
|
||||
for b in self.scanned_height() ..= confirmed_block {
|
||||
// If any keys activated at this height, shift them over
|
||||
// Will never scan the genesis block, which shouldn't be an issue
|
||||
for b in (self.scanned_block() + 1) ..= confirmed_block {
|
||||
// If any keys activated at this block, shift them over
|
||||
{
|
||||
let mut k = 0;
|
||||
while k < self.pending.len() {
|
||||
|
@ -269,8 +271,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
);
|
||||
}
|
||||
|
||||
// Blocks are zero-indexed while heights aren't
|
||||
self.db.scanned_to_height(b + 1);
|
||||
self.db.scanned_to_block(b);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -291,7 +292,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
return Ok((vec![], vec![]));
|
||||
}
|
||||
|
||||
let acknowledged_height = self.acknowledged_height(canonical);
|
||||
let acknowledged_block = self.acknowledged_block(canonical);
|
||||
|
||||
// TODO: Log schedule outputs when MAX_OUTPUTS is lower than payments.len()
|
||||
// Payments is the first set of TXs in the schedule
|
||||
|
@ -313,16 +314,16 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
// Create the transcript for this transaction
|
||||
let mut transcript = RecommendedTranscript::new(b"Serai Processor Wallet Send");
|
||||
transcript
|
||||
.append_message(b"canonical_height", &u64::try_from(canonical).unwrap().to_le_bytes());
|
||||
.append_message(b"canonical_block", &u64::try_from(canonical).unwrap().to_le_bytes());
|
||||
transcript.append_message(
|
||||
b"acknowledged_height",
|
||||
&u64::try_from(acknowledged_height).unwrap().to_le_bytes(),
|
||||
b"acknowledged_block",
|
||||
&u64::try_from(acknowledged_block).unwrap().to_le_bytes(),
|
||||
);
|
||||
transcript.append_message(b"index", &u64::try_from(txs.len()).unwrap().to_le_bytes());
|
||||
|
||||
let tx = self
|
||||
.coin
|
||||
.prepare_send(keys.clone(), transcript, acknowledged_height, inputs, &outputs, fee)
|
||||
.prepare_send(keys.clone(), transcript, acknowledged_block, inputs, &outputs, fee)
|
||||
.await?;
|
||||
// self.db.save_tx(tx) // TODO
|
||||
txs.push(tx);
|
||||
|
|
|
@ -3,10 +3,15 @@ name = "serai-consensus"
|
|||
version = "0.1.0"
|
||||
description = "Serai consensus module"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/consensus"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
sp-core = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-trie = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
|
|
@ -3,6 +3,7 @@ name = "serai-node"
|
|||
version = "0.1.0"
|
||||
description = "Serai network node, built over Substrate"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/node"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
@ -11,7 +12,7 @@ publish = false
|
|||
name = "serai-node"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3.1.18", features = ["derive"] }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
|
||||
sc-cli = { git = "https://github.com/serai-dex/substrate", features = ["wasmtime"] }
|
||||
sp-core = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
@ -31,7 +32,7 @@ frame-system = { git = "https://github.com/serai-dex/substrate" }
|
|||
pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
||||
# These dependencies are used for the node template's RPCs
|
||||
jsonrpsee = { version = "0.15.1", features = ["server"] }
|
||||
jsonrpsee = { version = "0.15", features = ["server"] }
|
||||
sc-rpc = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-api = { git = "https://github.com/serai-dex/substrate" }
|
||||
sc-rpc-api = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
@ -39,7 +40,6 @@ sp-blockchain = { git = "https://github.com/serai-dex/substrate" }
|
|||
sp-block-builder = { git = "https://github.com/serai-dex/substrate" }
|
||||
substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" }
|
||||
pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" }
|
||||
pallet-contracts-rpc = { git = "https://github.com/serai-dex/substrate", package = "pallet-contracts-rpc" }
|
||||
|
||||
# These dependencies are used for runtime benchmarking
|
||||
frame-benchmarking = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
|
|
@ -9,7 +9,7 @@ use sp_api::ProvideRuntimeApi;
|
|||
|
||||
pub use sc_rpc_api::DenyUnsafe;
|
||||
|
||||
use serai_runtime::{BlockNumber, Hash, opaque::Block, AccountId, Balance, Index};
|
||||
use serai_runtime::{opaque::Block, AccountId, Balance, Index};
|
||||
|
||||
pub struct FullDeps<C, P> {
|
||||
pub client: Arc<C>,
|
||||
|
@ -31,19 +31,16 @@ pub fn create_full<
|
|||
where
|
||||
C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>
|
||||
+ pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
|
||||
+ pallet_contracts_rpc::ContractsRuntimeApi<Block, AccountId, Balance, BlockNumber, Hash>
|
||||
+ BlockBuilder<Block>,
|
||||
{
|
||||
use substrate_frame_rpc_system::{System, SystemApiServer};
|
||||
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
|
||||
use pallet_contracts_rpc::{Contracts, ContractsApiServer};
|
||||
|
||||
let mut module = RpcModule::new(());
|
||||
let FullDeps { client, pool, deny_unsafe } = deps;
|
||||
|
||||
module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
|
||||
module.merge(TransactionPayment::new(client.clone()).into_rpc())?;
|
||||
module.merge(Contracts::new(client).into_rpc())?;
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
|
|
|
@ -3,15 +3,19 @@ name = "serai-runtime"
|
|||
version = "0.1.0"
|
||||
description = "Serai network node runtime, built over Substrate"
|
||||
license = "AGPL-3.0-only"
|
||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/runtime"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
hex-literal = { version = "0.3.4", optional = true }
|
||||
|
||||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
|
||||
codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||
scale-info = { version = "2", default-features = false, features = ["derive"] }
|
||||
|
||||
sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
@ -35,7 +39,6 @@ pallet-transaction-payment = { git = "https://github.com/serai-dex/substrate", d
|
|||
|
||||
pallet-contracts-primitives = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
pallet-contracts = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
pallet-contracts-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
||||
# Used for the node template's RPCs
|
||||
frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||
|
@ -77,7 +80,6 @@ std = [
|
|||
|
||||
"pallet-contracts/std",
|
||||
"pallet-contracts-primitives/std",
|
||||
"pallet-contracts-rpc-runtime-api/std",
|
||||
]
|
||||
|
||||
runtime-benchmarks = [
|
||||
|
|
|
@ -19,7 +19,7 @@ use sp_version::RuntimeVersion;
|
|||
use frame_support::{
|
||||
traits::{ConstU8, ConstU32, ConstU64},
|
||||
weights::{
|
||||
constants::{RocksDbWeight, ExtrinsicBaseWeight, BlockExecutionWeight, WEIGHT_PER_SECOND},
|
||||
constants::{RocksDbWeight, WEIGHT_PER_SECOND},
|
||||
IdentityFee, Weight,
|
||||
},
|
||||
dispatch::DispatchClass,
|
||||
|
@ -30,7 +30,6 @@ pub use frame_system::Call as SystemCall;
|
|||
pub use pallet_timestamp::Call as TimestampCall;
|
||||
pub use pallet_balances::Call as BalancesCall;
|
||||
use pallet_transaction_payment::CurrencyAdapter;
|
||||
use pallet_contracts::DefaultContractAccessWeight;
|
||||
|
||||
/// An index to a block.
|
||||
pub type BlockNumber = u32;
|
||||
|
@ -92,17 +91,6 @@ pub fn native_version() -> NativeVersion {
|
|||
|
||||
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
|
||||
|
||||
/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
|
||||
/// This is used to limit the maximal weight of a single extrinsic.
|
||||
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
|
||||
|
||||
/// We allow for 2 seconds of compute with a 6 second average block time.
|
||||
const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_ref_time(2 * WEIGHT_PER_SECOND.ref_time());
|
||||
|
||||
// Prints debug output of the `contracts` pallet to stdout if the node is
|
||||
// started with `-lruntime::contracts=debug`.
|
||||
const CONTRACTS_DEBUG_OUTPUT: bool = true;
|
||||
|
||||
// Unit = the base number of indivisible units for balances
|
||||
const UNIT: Balance = 1_000_000_000_000;
|
||||
const MILLIUNIT: Balance = 1_000_000_000;
|
||||
|
@ -121,24 +109,10 @@ parameter_types! {
|
|||
pub BlockLength: frame_system::limits::BlockLength =
|
||||
frame_system::limits::BlockLength::max_with_normal_ratio(1024 * 1024, NORMAL_DISPATCH_RATIO);
|
||||
pub BlockWeights: frame_system::limits::BlockWeights =
|
||||
frame_system::limits::BlockWeights::builder()
|
||||
.base_block(BlockExecutionWeight::get())
|
||||
.for_class(DispatchClass::all(), |weights| {
|
||||
weights.base_extrinsic = ExtrinsicBaseWeight::get();
|
||||
})
|
||||
.for_class(DispatchClass::Normal, |weights| {
|
||||
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
|
||||
})
|
||||
.for_class(DispatchClass::Operational, |weights| {
|
||||
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
|
||||
// Operational transactions have some extra reserved space, so that they
|
||||
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
|
||||
weights.reserved = Some(
|
||||
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
|
||||
);
|
||||
})
|
||||
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
|
||||
.build_or_panic();
|
||||
frame_system::limits::BlockWeights::with_sensible_defaults(
|
||||
(2u64 * WEIGHT_PER_SECOND).set_proof_size(u64::MAX),
|
||||
NORMAL_DISPATCH_RATIO,
|
||||
);
|
||||
|
||||
pub const DepositPerItem: Balance = deposit(1, 0);
|
||||
pub const DepositPerByte: Balance = deposit(0, 1);
|
||||
|
@ -236,7 +210,6 @@ impl pallet_contracts::Config for Runtime {
|
|||
type DeletionWeightLimit = DeletionWeightLimit;
|
||||
type Schedule = Schedule;
|
||||
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
|
||||
type ContractAccessWeight = DefaultContractAccessWeight<BlockWeights>;
|
||||
|
||||
type MaxCodeLen = ConstU32<{ 128 * 1024 }>;
|
||||
type MaxStorageKeyLen = ConstU32<128>;
|
||||
|
@ -388,63 +361,4 @@ sp_api::impl_runtime_apis! {
|
|||
TransactionPayment::query_fee_details(uxt, len)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash>
|
||||
for Runtime
|
||||
{
|
||||
fn call(
|
||||
origin: AccountId,
|
||||
dest: AccountId,
|
||||
value: Balance,
|
||||
gas_limit: u64,
|
||||
storage_deposit_limit: Option<Balance>,
|
||||
input_data: Vec<u8>,
|
||||
) -> pallet_contracts_primitives::ContractExecResult<Balance> {
|
||||
Contracts::bare_call(
|
||||
origin,
|
||||
dest,
|
||||
value,
|
||||
Weight::from_ref_time(gas_limit),
|
||||
storage_deposit_limit,
|
||||
input_data,
|
||||
CONTRACTS_DEBUG_OUTPUT
|
||||
)
|
||||
}
|
||||
|
||||
fn instantiate(
|
||||
origin: AccountId,
|
||||
value: Balance,
|
||||
gas_limit: u64,
|
||||
storage_deposit_limit: Option<Balance>,
|
||||
code: pallet_contracts_primitives::Code<Hash>,
|
||||
data: Vec<u8>,
|
||||
salt: Vec<u8>,
|
||||
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, Balance> {
|
||||
Contracts::bare_instantiate(
|
||||
origin,
|
||||
value,
|
||||
Weight::from_ref_time(gas_limit),
|
||||
storage_deposit_limit,
|
||||
code,
|
||||
data,
|
||||
salt,
|
||||
CONTRACTS_DEBUG_OUTPUT
|
||||
)
|
||||
}
|
||||
|
||||
fn upload_code(
|
||||
origin: AccountId,
|
||||
code: Vec<u8>,
|
||||
storage_deposit_limit: Option<Balance>,
|
||||
) -> pallet_contracts_primitives::CodeUploadResult<Hash, Balance> {
|
||||
Contracts::bare_upload_code(origin, code, storage_deposit_limit)
|
||||
}
|
||||
|
||||
fn get_storage(
|
||||
address: AccountId,
|
||||
key: Vec<u8>,
|
||||
) -> pallet_contracts_primitives::GetStorageResult {
|
||||
Contracts::get_storage(address, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue