mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-03 17:40:34 +00:00
Correct clippy warnings
Currently intended to be done with: cargo clippy --features "recommended merlin batch serialize experimental ed25519 ristretto p256 secp256k1 multisig" -- -A clippy::type_complexity -A dead_code
This commit is contained in:
parent
3556584478
commit
76a7160ea5
36 changed files with 129 additions and 122 deletions
|
@ -34,17 +34,17 @@ pub async fn call_verify(
|
|||
contract: &schnorr_mod::Schnorr<SignerMiddleware<Provider<Http>, LocalWallet>>,
|
||||
params: &ProcessedSignature,
|
||||
) -> Result<()> {
|
||||
let ok = contract
|
||||
if contract
|
||||
.verify(
|
||||
params.parity + 27,
|
||||
params.px.to_bytes().into(),
|
||||
params.message.into(),
|
||||
params.message,
|
||||
params.s.to_bytes().into(),
|
||||
params.e.to_bytes().into(),
|
||||
)
|
||||
.call()
|
||||
.await?;
|
||||
if ok {
|
||||
.await?
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(eyre!(EthereumError::VerificationError))
|
||||
|
|
|
@ -41,7 +41,8 @@ pub fn ecrecover(message: Scalar, v: u8, r: Scalar, s: Scalar) -> Option<[u8; 20
|
|||
return Some(address(&key));
|
||||
}
|
||||
}
|
||||
return None;
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{serialize::*, transaction::Transaction};
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct BlockHeader {
|
||||
pub major_version: u64,
|
||||
pub minor_version: u64,
|
||||
|
@ -37,7 +37,7 @@ impl BlockHeader {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Block {
|
||||
pub header: BlockHeader,
|
||||
pub miner_tx: Transaction,
|
||||
|
|
|
@ -38,7 +38,7 @@ lazy_static! {
|
|||
)
|
||||
.decompress()
|
||||
.unwrap();
|
||||
static ref H_TABLE: EdwardsBasepointTable = EdwardsBasepointTable::create(&*H);
|
||||
static ref H_TABLE: EdwardsBasepointTable = EdwardsBasepointTable::create(&H);
|
||||
}
|
||||
|
||||
// Function from libsodium our subsection of Monero relies on. Implementing it here means we don't
|
||||
|
@ -98,5 +98,5 @@ pub fn hash(data: &[u8]) -> [u8; 32] {
|
|||
}
|
||||
|
||||
pub fn hash_to_scalar(data: &[u8]) -> Scalar {
|
||||
Scalar::from_bytes_mod_order(hash(&data))
|
||||
Scalar::from_bytes_mod_order(hash(data))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{Commitment, wallet::TransactionError, serialize::*};
|
|||
|
||||
pub(crate) const MAX_OUTPUTS: usize = 16;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Bulletproofs {
|
||||
pub A: EdwardsPoint,
|
||||
pub S: EdwardsPoint,
|
||||
|
|
|
@ -41,7 +41,7 @@ pub enum ClsagError {
|
|||
InvalidC1,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct ClsagInput {
|
||||
// The actual commitment for the true spend
|
||||
pub commitment: Commitment,
|
||||
|
@ -69,6 +69,7 @@ impl ClsagInput {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
enum Mode {
|
||||
Sign(usize, EdwardsPoint, EdwardsPoint),
|
||||
#[cfg(feature = "experimental")]
|
||||
|
@ -182,7 +183,7 @@ fn core(
|
|||
((D, c * mu_P, c * mu_C), c1.unwrap_or(c))
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Clsag {
|
||||
pub D: EdwardsPoint,
|
||||
pub s: Vec<Scalar>,
|
||||
|
|
|
@ -65,7 +65,7 @@ impl ClsagDetails {
|
|||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
struct Interim {
|
||||
p: Scalar,
|
||||
c: Scalar,
|
||||
|
@ -147,7 +147,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
|||
l: u16,
|
||||
serialized: &mut Re,
|
||||
) -> Result<(), FrostError> {
|
||||
if self.image.is_identity().into() {
|
||||
if self.image.is_identity() {
|
||||
self.transcript.domain_separate(b"CLSAG");
|
||||
self.input().transcript(&mut self.transcript);
|
||||
self.transcript.append_message(b"mask", &self.mask().to_bytes());
|
||||
|
@ -189,15 +189,13 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
|||
&self.image,
|
||||
&self.input(),
|
||||
self.mask(),
|
||||
&self.msg.as_ref().unwrap(),
|
||||
self.msg.as_ref().unwrap(),
|
||||
nonce_sums[0][0].0,
|
||||
nonce_sums[0][1].0,
|
||||
);
|
||||
self.interim = Some(Interim { p, c, clsag, pseudo_out });
|
||||
|
||||
let share = dfg::Scalar(nonces[0].0 - (p * view.secret_share().0));
|
||||
|
||||
share
|
||||
dfg::Scalar(nonces[0].0 - (p * view.secret_share().0))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -215,13 +213,13 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
|||
&self.input().decoys.ring,
|
||||
&self.image,
|
||||
&interim.pseudo_out,
|
||||
&self.msg.as_ref().unwrap(),
|
||||
self.msg.as_ref().unwrap(),
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
return Some((clsag, interim.pseudo_out));
|
||||
}
|
||||
return None;
|
||||
None
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
@ -232,7 +230,6 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
|||
share: dfg::Scalar,
|
||||
) -> bool {
|
||||
let interim = self.interim.as_ref().unwrap();
|
||||
return (&share.0 * &ED25519_BASEPOINT_TABLE) ==
|
||||
(nonces[0][0].0 - (interim.p * verification_share.0));
|
||||
(&share.0 * &ED25519_BASEPOINT_TABLE) == (nonces[0][0].0 - (interim.p * verification_share.0))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ pub(crate) fn rust_hash_to_point(key: EdwardsPoint) -> EdwardsPoint {
|
|||
#[allow(non_snake_case)]
|
||||
let mut Y = z - w;
|
||||
|
||||
Y = Y * Z.invert().unwrap();
|
||||
Y *= Z.invert().unwrap();
|
||||
let mut bytes = Y.to_repr();
|
||||
bytes[31] |= sign.unwrap_u8() << 7;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn generate_key_image(secret: Scalar) -> EdwardsPoint {
|
|||
secret * hash_to_point(&secret * &ED25519_BASEPOINT_TABLE)
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct RctBase {
|
||||
pub fee: u64,
|
||||
pub ecdh_info: Vec<[u8; 8]>,
|
||||
|
@ -68,7 +68,7 @@ impl RctBase {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum RctPrunable {
|
||||
Null,
|
||||
Clsag { bulletproofs: Vec<Bulletproofs>, clsags: Vec<Clsag>, pseudo_outs: Vec<EdwardsPoint> },
|
||||
|
@ -90,9 +90,9 @@ impl RctPrunable {
|
|||
match self {
|
||||
RctPrunable::Null => Ok(()),
|
||||
RctPrunable::Clsag { bulletproofs, clsags, pseudo_outs } => {
|
||||
write_vec(Bulletproofs::serialize, &bulletproofs, w)?;
|
||||
write_raw_vec(Clsag::serialize, &clsags, w)?;
|
||||
write_raw_vec(write_point, &pseudo_outs, w)
|
||||
write_vec(Bulletproofs::serialize, bulletproofs, w)?;
|
||||
write_raw_vec(Clsag::serialize, clsags, w)?;
|
||||
write_raw_vec(write_point, pseudo_outs, w)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,13 +122,13 @@ impl RctPrunable {
|
|||
match self {
|
||||
RctPrunable::Null => panic!("Serializing RctPrunable::Null for a signature"),
|
||||
RctPrunable::Clsag { bulletproofs, .. } => {
|
||||
bulletproofs.iter().map(|bp| bp.signature_serialize(w)).collect()
|
||||
bulletproofs.iter().try_for_each(|bp| bp.signature_serialize(w))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct RctSignatures {
|
||||
pub base: RctBase,
|
||||
pub prunable: RctPrunable,
|
||||
|
|
|
@ -47,7 +47,7 @@ fn rpc_point(point: &str) -> Result<EdwardsPoint, RpcError> {
|
|||
rpc_hex(point)?.try_into().map_err(|_| RpcError::InvalidPoint(point.to_string()))?,
|
||||
)
|
||||
.decompress()
|
||||
.ok_or(RpcError::InvalidPoint(point.to_string()))
|
||||
.ok_or_else(|| RpcError::InvalidPoint(point.to_string()))
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -110,7 +110,7 @@ impl Rpc {
|
|||
&self,
|
||||
hashes: &[[u8; 32]],
|
||||
) -> Result<(Vec<Result<Transaction, RpcError>>, Vec<[u8; 32]>), RpcError> {
|
||||
if hashes.len() == 0 {
|
||||
if hashes.is_empty() {
|
||||
return Ok((vec![], vec![]));
|
||||
}
|
||||
|
||||
|
@ -142,14 +142,14 @@ impl Rpc {
|
|||
.iter()
|
||||
.map(|res| {
|
||||
let tx = Transaction::deserialize(&mut std::io::Cursor::new(
|
||||
rpc_hex(if res.as_hex.len() != 0 { &res.as_hex } else { &res.pruned_as_hex }).unwrap(),
|
||||
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())
|
||||
})?;
|
||||
|
||||
// https://github.com/monero-project/monero/issues/8311
|
||||
if res.as_hex.len() == 0 {
|
||||
if res.as_hex.is_empty() {
|
||||
match tx.prefix.inputs.get(0) {
|
||||
Some(Input::Gen { .. }) => (),
|
||||
_ => Err(RpcError::PrunedTransaction)?,
|
||||
|
@ -165,7 +165,7 @@ impl Rpc {
|
|||
|
||||
pub async fn get_transactions(&self, hashes: &[[u8; 32]]) -> Result<Vec<Transaction>, RpcError> {
|
||||
let (txs, missed) = self.get_transactions_core(hashes).await?;
|
||||
if missed.len() != 0 {
|
||||
if !missed.is_empty() {
|
||||
Err(RpcError::TransactionsNotFound(missed))?;
|
||||
}
|
||||
// This will clone several KB and is accordingly inefficient
|
||||
|
|
|
@ -50,7 +50,7 @@ pub fn write_vec<T, W: io::Write, F: Fn(&T, &mut W) -> io::Result<()>>(
|
|||
w: &mut W,
|
||||
) -> io::Result<()> {
|
||||
write_varint(&values.len().try_into().unwrap(), w)?;
|
||||
write_raw_vec(f, &values, w)
|
||||
write_raw_vec(f, values, w)
|
||||
}
|
||||
|
||||
pub fn read_byte<R: io::Read>(r: &mut R) -> io::Result<u8> {
|
||||
|
@ -81,14 +81,14 @@ pub fn read_32<R: io::Read>(r: &mut R) -> io::Result<[u8; 32]> {
|
|||
// TODO: https://github.com/serai-dex/serai/issues/25
|
||||
pub fn read_scalar<R: io::Read>(r: &mut R) -> io::Result<Scalar> {
|
||||
Scalar::from_canonical_bytes(read_32(r)?)
|
||||
.ok_or(io::Error::new(io::ErrorKind::Other, "unreduced scalar"))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "unreduced scalar"))
|
||||
}
|
||||
|
||||
pub fn read_point<R: io::Read>(r: &mut R) -> io::Result<EdwardsPoint> {
|
||||
CompressedEdwardsY(read_32(r)?)
|
||||
.decompress()
|
||||
.filter(|point| point.is_torsion_free())
|
||||
.ok_or(io::Error::new(io::ErrorKind::Other, "invalid point"))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point"))
|
||||
}
|
||||
|
||||
pub fn read_raw_vec<R: io::Read, T, F: Fn(&mut R) -> io::Result<T>>(
|
||||
|
@ -96,9 +96,7 @@ pub fn read_raw_vec<R: io::Read, T, F: Fn(&mut R) -> io::Result<T>>(
|
|||
len: usize,
|
||||
r: &mut R,
|
||||
) -> io::Result<Vec<T>> {
|
||||
let mut res = Vec::with_capacity(
|
||||
len.try_into().map_err(|_| io::Error::new(io::ErrorKind::Other, "length exceeds usize"))?,
|
||||
);
|
||||
let mut res = Vec::with_capacity(len);
|
||||
for _ in 0 .. len {
|
||||
res.push(f(r)?);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
|
||||
pub const RING_LEN: usize = 11;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Input {
|
||||
Gen(u64),
|
||||
|
||||
|
@ -60,7 +60,7 @@ impl Input {
|
|||
}
|
||||
|
||||
// Doesn't bother moving to an enum for the unused Script classes
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Output {
|
||||
pub amount: u64,
|
||||
pub key: EdwardsPoint,
|
||||
|
@ -106,7 +106,7 @@ impl Output {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Timelock {
|
||||
None,
|
||||
Block(usize),
|
||||
|
@ -151,7 +151,7 @@ impl PartialOrd for Timelock {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct TransactionPrefix {
|
||||
pub version: u64,
|
||||
pub timelock: Timelock,
|
||||
|
@ -198,7 +198,7 @@ impl TransactionPrefix {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Transaction {
|
||||
pub prefix: TransactionPrefix,
|
||||
pub rct_signatures: RctSignatures,
|
||||
|
|
|
@ -57,6 +57,7 @@ pub enum AddressError {
|
|||
}
|
||||
|
||||
impl AddressMeta {
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn to_byte(&self) -> u8 {
|
||||
let bytes = AddressType::network_bytes(self.network);
|
||||
let byte = match self.kind {
|
||||
|
|
|
@ -94,7 +94,7 @@ fn offset(ring: &[u64]) -> Vec<u64> {
|
|||
res
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Decoys {
|
||||
pub i: u8,
|
||||
pub offsets: Vec<u64>,
|
||||
|
|
|
@ -27,7 +27,7 @@ pub(crate) fn uniqueness(inputs: &[Input]) -> [u8; 32] {
|
|||
// If Gen, this should be the only input, making this loop somewhat pointless
|
||||
// This works and even if there were somehow multiple inputs, it'd be a false negative
|
||||
Input::Gen(height) => {
|
||||
write_varint(&(*height).try_into().unwrap(), &mut u).unwrap();
|
||||
write_varint(height, &mut u).unwrap();
|
||||
}
|
||||
Input::ToKey { key_image, .. } => u.extend(key_image.compress().to_bytes()),
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
wallet::{ViewPair, uniqueness, shared_key, amount_decryption, commitment_mask},
|
||||
};
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SpendableOutput {
|
||||
pub tx: [u8; 32],
|
||||
pub o: u8,
|
||||
|
@ -92,7 +92,7 @@ impl Transaction {
|
|||
m_pubkeys.extend(&keys);
|
||||
}
|
||||
|
||||
pubkeys = m_pubkeys.iter().map(|key| key.point.decompress()).filter_map(|key| key).collect();
|
||||
pubkeys = m_pubkeys.iter().filter_map(|key| key.point.decompress()).collect();
|
||||
} else {
|
||||
return Timelocked(self.prefix.timelock, vec![]);
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ mod multisig;
|
|||
pub use multisig::TransactionMachine;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
struct SendOutput {
|
||||
R: EdwardsPoint,
|
||||
dest: EdwardsPoint,
|
||||
|
@ -61,7 +61,7 @@ impl SendOutput {
|
|||
AddressType::Integrated(_) => {
|
||||
unimplemented!("SendOutput::new doesn't support Integrated addresses")
|
||||
}
|
||||
AddressType::Subaddress => &r * spend,
|
||||
AddressType::Subaddress => r * spend,
|
||||
},
|
||||
dest: ((&shared_key * &ED25519_BASEPOINT_TABLE) + spend),
|
||||
commitment: Commitment::new(commitment_mask(shared_key), output.1),
|
||||
|
@ -113,18 +113,17 @@ async fn prepare_inputs<R: RngCore + CryptoRng>(
|
|||
let decoys = Decoys::select(
|
||||
rng,
|
||||
rpc,
|
||||
rpc.get_height().await.map_err(|e| TransactionError::RpcError(e))? - 10,
|
||||
rpc.get_height().await.map_err(TransactionError::RpcError)? - 10,
|
||||
inputs,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| TransactionError::RpcError(e))?;
|
||||
.map_err(TransactionError::RpcError)?;
|
||||
|
||||
for (i, input) in inputs.iter().enumerate() {
|
||||
signable.push((
|
||||
spend + input.key_offset,
|
||||
generate_key_image(spend + input.key_offset),
|
||||
ClsagInput::new(input.commitment, decoys[i].clone())
|
||||
.map_err(|e| TransactionError::ClsagError(e))?,
|
||||
ClsagInput::new(input.commitment, decoys[i].clone()).map_err(TransactionError::ClsagError)?,
|
||||
));
|
||||
|
||||
tx.prefix.inputs.push(Input::ToKey {
|
||||
|
@ -158,7 +157,7 @@ impl Fee {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct SignableTransaction {
|
||||
inputs: Vec<SpendableOutput>,
|
||||
payments: Vec<(Address, u64)>,
|
||||
|
@ -187,10 +186,10 @@ impl SignableTransaction {
|
|||
test(change)?;
|
||||
}
|
||||
|
||||
if inputs.len() == 0 {
|
||||
if inputs.is_empty() {
|
||||
Err(TransactionError::NoInputs)?;
|
||||
}
|
||||
if payments.len() == 0 {
|
||||
if payments.is_empty() {
|
||||
Err(TransactionError::NoOutputs)?;
|
||||
}
|
||||
|
||||
|
@ -339,8 +338,7 @@ impl SignableTransaction {
|
|||
RctPrunable::Null => panic!("Signing for RctPrunable::Null"),
|
||||
RctPrunable::Clsag { ref mut clsags, ref mut pseudo_outs, .. } => {
|
||||
clsags.append(&mut clsag_pairs.iter().map(|clsag| clsag.0.clone()).collect::<Vec<_>>());
|
||||
pseudo_outs
|
||||
.append(&mut clsag_pairs.iter().map(|clsag| clsag.1.clone()).collect::<Vec<_>>());
|
||||
pseudo_outs.append(&mut clsag_pairs.iter().map(|clsag| clsag.1).collect::<Vec<_>>());
|
||||
}
|
||||
}
|
||||
Ok(tx)
|
||||
|
|
|
@ -108,7 +108,7 @@ impl SignableTransaction {
|
|||
transcript.append_message(b"input_shared_key", &input.key_offset.to_bytes());
|
||||
}
|
||||
for payment in &self.payments {
|
||||
transcript.append_message(b"payment_address", &payment.0.to_string().as_bytes());
|
||||
transcript.append_message(b"payment_address", payment.0.to_string().as_bytes());
|
||||
transcript.append_message(b"payment_amount", &payment.1.to_le_bytes());
|
||||
}
|
||||
|
||||
|
@ -125,11 +125,11 @@ impl SignableTransaction {
|
|||
clsags.push(
|
||||
AlgorithmMachine::new(
|
||||
ClsagMultisig::new(transcript.clone(), input.key, inputs[i].clone())
|
||||
.map_err(|e| TransactionError::MultisigError(e))?,
|
||||
.map_err(TransactionError::MultisigError)?,
|
||||
Arc::new(offset),
|
||||
&included,
|
||||
)
|
||||
.map_err(|e| TransactionError::FrostError(e))?,
|
||||
.map_err(TransactionError::FrostError)?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ impl SignableTransaction {
|
|||
&self.inputs,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| TransactionError::RpcError(e))?;
|
||||
.map_err(TransactionError::RpcError)?;
|
||||
|
||||
Ok(TransactionMachine {
|
||||
signable: self,
|
||||
|
@ -223,7 +223,7 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||
mut commitments: HashMap<u16, Re>,
|
||||
msg: &[u8],
|
||||
) -> Result<(TransactionSignatureMachine, Vec<u8>), FrostError> {
|
||||
if msg.len() != 0 {
|
||||
if !msg.is_empty() {
|
||||
Err(FrostError::InternalError(
|
||||
"message was passed to the TransactionMachine when it generates its own",
|
||||
))?;
|
||||
|
@ -237,7 +237,8 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||
let mut commitments = (0 .. self.clsags.len())
|
||||
.map(|c| {
|
||||
let mut buf = [0; CLSAG_LEN];
|
||||
(&self.included)
|
||||
self
|
||||
.included
|
||||
.iter()
|
||||
.map(|l| {
|
||||
// Add all commitments to the transcript for their entropy
|
||||
|
@ -310,7 +311,7 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||
|
||||
// Sort the inputs, as expected
|
||||
let mut sorted = Vec::with_capacity(self.clsags.len());
|
||||
while self.clsags.len() != 0 {
|
||||
while !self.clsags.is_empty() {
|
||||
sorted.push((
|
||||
images.swap_remove(0),
|
||||
self.signable.inputs.swap_remove(0),
|
||||
|
@ -324,11 +325,11 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||
|
||||
let mut rng = ChaCha12Rng::from_seed(self.transcript.rng_seed(b"pseudo_out_masks"));
|
||||
let mut sum_pseudo_outs = Scalar::zero();
|
||||
while sorted.len() != 0 {
|
||||
while !sorted.is_empty() {
|
||||
let value = sorted.remove(0);
|
||||
|
||||
let mut mask = random_scalar(&mut rng);
|
||||
if sorted.len() == 0 {
|
||||
if sorted.is_empty() {
|
||||
mask = output_masks - sum_pseudo_outs;
|
||||
} else {
|
||||
sum_pseudo_outs += mask;
|
||||
|
|
|
@ -6,6 +6,7 @@ use serai_extension::{Curve, GlobalValidatorSetId, ValidatorSetIndex, Key};
|
|||
|
||||
type KeysHash = [u8; 32];
|
||||
|
||||
#[allow(clippy::all)]
|
||||
#[ink::contract(env = serai_extension::SeraiEnvironment)]
|
||||
mod multisig {
|
||||
use scale::Encode;
|
||||
|
|
|
@ -231,7 +231,7 @@ impl PrimeField for Scalar {
|
|||
fn from_repr(bytes: [u8; 32]) -> CtOption<Self> {
|
||||
let scalar = DScalar::from_canonical_bytes(bytes);
|
||||
// TODO: This unwrap_or isn't constant time, yet do we have an alternative?
|
||||
CtOption::new(Scalar(scalar.unwrap_or(DScalar::zero())), choice(scalar.is_some()))
|
||||
CtOption::new(Scalar(scalar.unwrap_or_else(DScalar::zero)), choice(scalar.is_some()))
|
||||
}
|
||||
fn to_repr(&self) -> [u8; 32] {
|
||||
self.0.to_bytes()
|
||||
|
|
|
@ -163,6 +163,7 @@ where
|
|||
match self.Re_0 {
|
||||
Re::R(R0_0, R1_0) => {
|
||||
let mut e = Self::nonces(transcript.clone(), (R0_0, R1_0));
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0 .. (RING_LEN - 1) {
|
||||
e = Self::R_nonces(transcript.clone(), generators, self.s[i], ring[i], e);
|
||||
}
|
||||
|
@ -178,6 +179,7 @@ where
|
|||
Re::e(e_0) => {
|
||||
let e_0 = (e_0, scalar_convert(e_0).ok_or(DLEqError::InvalidChallenge)?);
|
||||
let mut e = None;
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0 .. RING_LEN {
|
||||
e = Some(Self::R_nonces(
|
||||
transcript.clone(),
|
||||
|
@ -230,8 +232,8 @@ where
|
|||
}
|
||||
|
||||
let mut s = [(G0::Scalar::zero(), G1::Scalar::zero()); RING_LEN];
|
||||
for i in 0 .. RING_LEN {
|
||||
s[i] = (read_scalar(r)?, read_scalar(r)?);
|
||||
for s in s.iter_mut() {
|
||||
*s = (read_scalar(r)?, read_scalar(r)?);
|
||||
}
|
||||
|
||||
Ok(Aos { Re_0, s })
|
||||
|
|
|
@ -15,6 +15,7 @@ use std::io::{Read, Write};
|
|||
#[cfg(feature = "serialize")]
|
||||
use crate::cross_group::read_point;
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
pub(crate) enum BitSignature {
|
||||
ClassicLinear,
|
||||
ConciseLinear,
|
||||
|
|
|
@ -97,6 +97,12 @@ pub struct Schnorr<C: Curve, H: Hram<C>> {
|
|||
_hram: PhantomData<H>,
|
||||
}
|
||||
|
||||
impl<C: Curve, H: Hram<C>> Default for Schnorr<C, H> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Curve, H: Hram<C>> Schnorr<C, H> {
|
||||
pub fn new() -> Schnorr<C, H> {
|
||||
Schnorr { transcript: IetfTranscript(vec![]), c: None, _hram: PhantomData }
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
fn challenge<C: Curve>(context: &str, l: u16, R: &[u8], Am: &[u8]) -> C::F {
|
||||
const DST: &'static [u8] = b"FROST Schnorr Proof of Knowledge";
|
||||
const DST: &[u8] = b"FROST Schnorr Proof of Knowledge";
|
||||
|
||||
// Uses hash_msg to get a fixed size value out of the context string
|
||||
let mut transcript = C::hash_msg(context.as_bytes());
|
||||
|
@ -91,7 +91,7 @@ fn verify_r1<Re: Read, R: RngCore + CryptoRng, C: Curve>(
|
|||
continue;
|
||||
}
|
||||
|
||||
let invalid = FrostError::InvalidCommitment(l.try_into().unwrap());
|
||||
let invalid = FrostError::InvalidCommitment(l);
|
||||
|
||||
// Read the entire list of commitments as the key we're providing a PoK for (A) and the message
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -124,7 +124,7 @@ fn verify_r1<Re: Read, R: RngCore + CryptoRng, C: Curve>(
|
|||
commitments.insert(l, these_commitments);
|
||||
}
|
||||
|
||||
schnorr::batch_verify(rng, &signatures).map_err(|l| FrostError::InvalidProofOfKnowledge(l))?;
|
||||
schnorr::batch_verify(rng, &signatures).map_err(FrostError::InvalidProofOfKnowledge)?;
|
||||
|
||||
Ok(commitments)
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ fn complete_r2<Re: Read, R: RngCore + CryptoRng, C: Curve>(
|
|||
values.push((-*share, C::GENERATOR));
|
||||
batch.queue(rng, *l, values);
|
||||
}
|
||||
batch.verify_with_vartime_blame().map_err(|l| FrostError::InvalidCommitment(l))?;
|
||||
batch.verify_with_vartime_blame().map_err(FrostError::InvalidCommitment)?;
|
||||
|
||||
// Stripe commitments per t and sum them in advance. Calculating verification shares relies on
|
||||
// these sums so preprocessing them is a massive speedup
|
||||
|
|
|
@ -161,7 +161,7 @@ impl<C: Curve> FrostKeys<C> {
|
|||
// Carry any existing offset
|
||||
// Enables schemes like Monero's subaddresses which have a per-subaddress offset and then a
|
||||
// one-time-key offset
|
||||
res.offset = Some(offset + res.offset.unwrap_or(C::F::zero()));
|
||||
res.offset = Some(offset + res.offset.unwrap_or_else(C::F::zero));
|
||||
res.group_key += C::GENERATOR * offset;
|
||||
res
|
||||
}
|
||||
|
@ -187,8 +187,8 @@ impl<C: Curve> FrostKeys<C> {
|
|||
Err(FrostError::InvalidSigningSet("invalid amount of participants included"))?;
|
||||
}
|
||||
|
||||
let secret_share = self.secret_share * lagrange::<C::F>(self.params.i, &included);
|
||||
let offset = self.offset.unwrap_or(C::F::zero());
|
||||
let secret_share = self.secret_share * lagrange::<C::F>(self.params.i, included);
|
||||
let offset = self.offset.unwrap_or_else(C::F::zero);
|
||||
let offset_share = offset * C::F::from(included.len().try_into().unwrap()).invert().unwrap();
|
||||
|
||||
Ok(FrostView {
|
||||
|
@ -198,7 +198,7 @@ impl<C: Curve> FrostKeys<C> {
|
|||
.verification_shares
|
||||
.iter()
|
||||
.map(|(l, share)| {
|
||||
(*l, (*share * lagrange::<C::F>(*l, &included)) + (C::GENERATOR * offset_share))
|
||||
(*l, (*share * lagrange::<C::F>(*l, included)) + (C::GENERATOR * offset_share))
|
||||
})
|
||||
.collect(),
|
||||
included: included.to_vec(),
|
||||
|
@ -218,7 +218,7 @@ impl<C: Curve> FrostKeys<C> {
|
|||
serialized.extend(&self.params.i.to_be_bytes());
|
||||
serialized.extend(self.secret_share.to_repr().as_ref());
|
||||
serialized.extend(self.group_key.to_bytes().as_ref());
|
||||
for l in 1 ..= self.params.n.into() {
|
||||
for l in 1 ..= self.params.n {
|
||||
serialized.extend(self.verification_shares[&l].to_bytes().as_ref());
|
||||
}
|
||||
serialized
|
||||
|
@ -237,7 +237,7 @@ impl<C: Curve> FrostKeys<C> {
|
|||
|
||||
let mut id = vec![0; C::ID.len()];
|
||||
cursor.read_exact(&mut id).map_err(|_| missing)?;
|
||||
if &id != &C::ID {
|
||||
if id != C::ID {
|
||||
Err(different)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ impl<C: Curve, A: Algorithm<C>> Params<C, A> {
|
|||
included: &[u16],
|
||||
) -> Result<Params<C, A>, FrostError> {
|
||||
let mut included = included.to_vec();
|
||||
(&mut included).sort_unstable();
|
||||
included.sort_unstable();
|
||||
|
||||
// Included < threshold
|
||||
if included.len() < usize::from(keys.params.t) {
|
||||
|
@ -123,7 +123,7 @@ fn preprocess<R: RngCore + CryptoRng, C: Curve, A: Algorithm<C>>(
|
|||
// This could be further optimized with a multi-nonce proof.
|
||||
// See https://github.com/serai-dex/serai/issues/38
|
||||
for nonce in nonces {
|
||||
DLEqProof::prove(&mut *rng, &mut transcript, &generators, nonce)
|
||||
DLEqProof::prove(&mut *rng, &mut transcript, generators, nonce)
|
||||
.serialize(&mut serialized)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
.map_err(|_| FrostError::InvalidCommitment(*l))?
|
||||
.verify(
|
||||
&mut transcript,
|
||||
&nonce_generators,
|
||||
nonce_generators,
|
||||
&commitments[n].iter().map(|commitments| commitments[de]).collect::<Vec<_>>(),
|
||||
)
|
||||
.map_err(|_| FrostError::InvalidCommitment(*l))?;
|
||||
|
@ -236,7 +236,7 @@ fn sign_with_share<Re: Read, C: Curve, A: Algorithm<C>>(
|
|||
|
||||
// Re-format into the FROST-expected rho transcript
|
||||
let mut rho_transcript = A::Transcript::new(b"FROST_rho");
|
||||
rho_transcript.append_message(b"message", &C::hash_msg(&msg));
|
||||
rho_transcript.append_message(b"message", &C::hash_msg(msg));
|
||||
// This won't just be the commitments, yet the full existing transcript if used in an extended
|
||||
// protocol
|
||||
rho_transcript.append_message(
|
||||
|
|
|
@ -116,7 +116,7 @@ pub fn algorithm_machines<R: RngCore, C: Curve, A: Algorithm<C>>(
|
|||
keys
|
||||
.iter()
|
||||
.filter_map(|(i, keys)| {
|
||||
if included.contains(&i) {
|
||||
if included.contains(i) {
|
||||
Some((
|
||||
*i,
|
||||
AlgorithmMachine::new(algorithm.clone(), keys.clone(), &included.clone()).unwrap(),
|
||||
|
|
|
@ -59,7 +59,7 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
|
||||
assert_eq!(blame, 2);
|
||||
} else {
|
||||
assert!(false);
|
||||
panic!("batch verification considered a malleated signature valid");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ pub(crate) fn core_batch_verify<R: RngCore + CryptoRng, C: Curve>(rng: &mut R) {
|
|||
if let Err(blame) = schnorr::batch_verify(rng, &triplets) {
|
||||
assert_eq!(blame, u16::try_from(i + 1).unwrap());
|
||||
} else {
|
||||
assert!(false);
|
||||
panic!("batch verification considered an invalid signature valid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ fn sign_core<R: RngCore + CryptoRng, C: Curve>(
|
|||
group_key: C::G,
|
||||
keys: &HashMap<u16, Arc<FrostKeys<C>>>,
|
||||
) {
|
||||
const MESSAGE: &'static [u8] = b"Hello, World!";
|
||||
const MESSAGE: &[u8] = b"Hello, World!";
|
||||
|
||||
let machines = algorithm_machines(rng, Schnorr::<C, TestHram<C>>::new(), keys);
|
||||
let sig = sign_test(&mut *rng, machines, MESSAGE);
|
||||
|
|
|
@ -87,7 +87,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
|
|||
AlgorithmMachine::new(
|
||||
Schnorr::<C, H>::new(),
|
||||
Arc::new(keys[i].clone()),
|
||||
vectors.included.clone(),
|
||||
&vectors.included.to_vec().clone(),
|
||||
)
|
||||
.unwrap(),
|
||||
));
|
||||
|
|
|
@ -24,7 +24,7 @@ where
|
|||
pairs: I,
|
||||
) {
|
||||
// Define a unique scalar factor for this set of variables so individual items can't overlap
|
||||
let u = if self.0.len() == 0 {
|
||||
let u = if self.0.is_empty() {
|
||||
G::Scalar::one()
|
||||
} else {
|
||||
let mut weight;
|
||||
|
|
|
@ -25,6 +25,12 @@ use crate::{
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Output(SpendableOutput);
|
||||
impl From<SpendableOutput> for Output {
|
||||
fn from(output: SpendableOutput) -> Output {
|
||||
Output(output)
|
||||
}
|
||||
}
|
||||
|
||||
impl OutputTrait for Output {
|
||||
// While we could use (tx, o), using the key ensures we won't be susceptible to the burning bug.
|
||||
// While the Monero library offers a variant which allows senders to ensure their TXs have unique
|
||||
|
@ -44,13 +50,7 @@ impl OutputTrait for Output {
|
|||
}
|
||||
|
||||
fn deserialize<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
|
||||
SpendableOutput::deserialize(reader).map(|o| Output(o))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SpendableOutput> for Output {
|
||||
fn from(output: SpendableOutput) -> Output {
|
||||
Output(output)
|
||||
SpendableOutput::deserialize(reader).map(Output)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ impl Coin for Monero {
|
|||
&self,
|
||||
tx: &Self::Transaction,
|
||||
) -> Result<(Vec<u8>, Vec<<Self::Output as OutputTrait>::Id>), CoinError> {
|
||||
self.rpc.publish_transaction(&tx).await.map_err(|_| CoinError::ConnectionError)?;
|
||||
self.rpc.publish_transaction(tx).await.map_err(|_| CoinError::ConnectionError)?;
|
||||
|
||||
Ok((
|
||||
tx.hash().to_vec(),
|
||||
|
|
|
@ -159,22 +159,22 @@ fn refine_inputs<C: Coin>(
|
|||
|
||||
// Replace large inputs with smaller ones
|
||||
for s in (0 .. selected.len()).rev() {
|
||||
for i in 0 .. inputs.len() {
|
||||
for input in inputs.iter_mut() {
|
||||
// Doesn't break due to inputs no longer being sorted
|
||||
// This could be made faster if we prioritized small input usage over transaction size/fees
|
||||
// TODO: Consider. This would implicitly consolidate inputs which would be advantageous
|
||||
if selected[s].amount() < inputs[i].amount() {
|
||||
if selected[s].amount() < input.amount() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we can successfully replace this input, do so
|
||||
let diff = selected[s].amount() - inputs[i].amount();
|
||||
let diff = selected[s].amount() - input.amount();
|
||||
if remaining > diff {
|
||||
remaining -= diff;
|
||||
|
||||
let old = selected[s].clone();
|
||||
selected[s] = inputs[i].clone();
|
||||
inputs[i] = old;
|
||||
selected[s] = input.clone();
|
||||
*input = old;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -184,14 +184,14 @@ fn select_inputs_outputs<C: Coin>(
|
|||
inputs: &mut Vec<C::Output>,
|
||||
outputs: &mut Vec<(C::Address, u64)>,
|
||||
) -> (Vec<C::Output>, Vec<(C::Address, u64)>) {
|
||||
if inputs.len() == 0 {
|
||||
if inputs.is_empty() {
|
||||
return (vec![], vec![]);
|
||||
}
|
||||
|
||||
let (mut selected, mut value) = select_inputs::<C>(inputs);
|
||||
|
||||
let outputs = select_outputs::<C>(outputs, &mut value);
|
||||
if outputs.len() == 0 {
|
||||
if outputs.is_empty() {
|
||||
inputs.extend(selected);
|
||||
return (vec![], vec![]);
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
payments: Vec<(C::Address, u64)>,
|
||||
fee: C::Fee,
|
||||
) -> Result<(Vec<(C::Address, u64)>, Vec<C::SignableTransaction>), CoinError> {
|
||||
if payments.len() == 0 {
|
||||
if payments.is_empty() {
|
||||
return Ok((vec![], vec![]));
|
||||
}
|
||||
|
||||
|
@ -302,10 +302,10 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
|
||||
let mut txs = vec![];
|
||||
for (keys, outputs) in self.keys.iter_mut() {
|
||||
while outputs.len() != 0 {
|
||||
while !outputs.is_empty() {
|
||||
let (inputs, outputs) = select_inputs_outputs::<C>(outputs, &mut payments);
|
||||
// If we can no longer process any payments, move to the next set of keys
|
||||
if outputs.len() == 0 {
|
||||
if outputs.is_empty() {
|
||||
debug_assert_eq!(inputs.len(), 0);
|
||||
break;
|
||||
}
|
||||
|
@ -339,16 +339,16 @@ impl<D: CoinDb, C: Coin> Wallet<D, C> {
|
|||
included: Vec<u16>,
|
||||
) -> Result<(Vec<u8>, Vec<<C::Output as Output>::Id>), SignError> {
|
||||
let attempt =
|
||||
self.coin.attempt_send(prepared, &included).await.map_err(|e| SignError::CoinError(e))?;
|
||||
self.coin.attempt_send(prepared, &included).await.map_err(SignError::CoinError)?;
|
||||
|
||||
let (attempt, commitments) = attempt.preprocess(&mut OsRng);
|
||||
let commitments = network.round(commitments).await.map_err(|e| SignError::NetworkError(e))?;
|
||||
let commitments = network.round(commitments).await.map_err(SignError::NetworkError)?;
|
||||
|
||||
let (attempt, share) = attempt.sign(commitments, b"").map_err(|e| SignError::FrostError(e))?;
|
||||
let shares = network.round(share).await.map_err(|e| SignError::NetworkError(e))?;
|
||||
let (attempt, share) = attempt.sign(commitments, b"").map_err(SignError::FrostError)?;
|
||||
let shares = network.round(share).await.map_err(SignError::NetworkError)?;
|
||||
|
||||
let tx = attempt.complete(shares).map_err(|e| SignError::FrostError(e))?;
|
||||
let tx = attempt.complete(shares).map_err(SignError::FrostError)?;
|
||||
|
||||
self.coin.publish_transaction(&tx).await.map_err(|e| SignError::CoinError(e))
|
||||
self.coin.publish_transaction(&tx).await.map_err(SignError::CoinError)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn import_queue<S: sp_consensus::SelectChain<Block> + 'static>(
|
|||
client.clone(),
|
||||
algorithm::AcceptAny,
|
||||
0,
|
||||
select_chain.clone(),
|
||||
select_chain,
|
||||
|_, _| async { Ok(sp_timestamp::InherentDataProvider::from_system_time()) },
|
||||
sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()),
|
||||
));
|
||||
|
@ -116,7 +116,7 @@ pub fn authority<S: sp_consensus::SelectChain<Block> + 'static>(
|
|||
algorithm::AcceptAny,
|
||||
proposer,
|
||||
network.clone(),
|
||||
network.clone(),
|
||||
network,
|
||||
None,
|
||||
move |_, _| async { Ok(sp_timestamp::InherentDataProvider::from_system_time()) },
|
||||
Duration::from_secs(6),
|
||||
|
|
|
@ -32,7 +32,7 @@ fn testnet_genesis(wasm_binary: &[u8], endowed_accounts: Vec<AccountId>) -> Gene
|
|||
}
|
||||
|
||||
pub fn development_config() -> Result<ChainSpec, &'static str> {
|
||||
let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available")?;
|
||||
let wasm_binary = WASM_BINARY.ok_or("Development wasm not available")?;
|
||||
|
||||
Ok(ChainSpec::from_genesis(
|
||||
// Name
|
||||
|
|
|
@ -62,7 +62,7 @@ pub fn create_benchmark_extrinsic(
|
|||
sp_runtime::AccountId32::from(sender.public()).into(),
|
||||
runtime::Signature::Sr25519(
|
||||
runtime::SignedPayload::from_raw(
|
||||
call.clone(),
|
||||
call,
|
||||
extra.clone(),
|
||||
(
|
||||
(),
|
||||
|
|
|
@ -41,7 +41,7 @@ where
|
|||
let mut module = RpcModule::new(());
|
||||
let FullDeps { client, pool, deny_unsafe } = deps;
|
||||
|
||||
module.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?;
|
||||
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())?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue