Move Protocol to monero-wallet

This commit is contained in:
Luke Parker
2024-06-21 14:14:15 -04:00
parent 6f61861d4b
commit b5b9d4a871
14 changed files with 233 additions and 253 deletions

View File

@@ -1,26 +1,19 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
// #![deny(missing_docs)] // TODO
#![cfg_attr(not(feature = "std"), no_std)]
use std_shims::io as stdio;
use zeroize::Zeroize;
pub use monero_io as io;
pub use monero_generators as generators;
pub use monero_primitives as primitives;
mod merkle;
use monero_io as serialize;
use serialize::{read_byte, read_u16};
/// Ring Signature structs and functionality.
pub mod ring_signatures;
/// RingCT structs and functionality.
pub mod ringct;
use ringct::RctType;
/// Transaction structs.
pub mod transaction;
@@ -30,123 +23,3 @@ pub mod block;
pub const DEFAULT_LOCK_WINDOW: usize = 10;
pub const COINBASE_LOCK_WINDOW: usize = 60;
pub const BLOCK_TIME: usize = 120;
/// Monero protocol version.
///
/// v15 is omitted as v15 was simply v14 and v16 being active at the same time, with regards to the
/// transactions supported. Accordingly, v16 should be used during v15.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
#[allow(non_camel_case_types)]
pub enum Protocol {
v14,
v16,
Custom {
ring_len: usize,
bp_plus: bool,
optimal_rct_type: RctType,
view_tags: bool,
v16_fee: bool,
},
}
impl Protocol {
/// Amount of ring members under this protocol version.
pub fn ring_len(&self) -> usize {
match self {
Protocol::v14 => 11,
Protocol::v16 => 16,
Protocol::Custom { ring_len, .. } => *ring_len,
}
}
/// Whether or not the specified version uses Bulletproofs or Bulletproofs+.
///
/// This method will likely be reworked when versions not using Bulletproofs at all are added.
pub fn bp_plus(&self) -> bool {
match self {
Protocol::v14 => false,
Protocol::v16 => true,
Protocol::Custom { bp_plus, .. } => *bp_plus,
}
}
// TODO: Make this an Option when we support pre-RCT protocols
pub fn optimal_rct_type(&self) -> RctType {
match self {
Protocol::v14 => RctType::Clsag,
Protocol::v16 => RctType::BulletproofsPlus,
Protocol::Custom { optimal_rct_type, .. } => *optimal_rct_type,
}
}
/// Whether or not the specified version uses view tags.
pub fn view_tags(&self) -> bool {
match self {
Protocol::v14 => false,
Protocol::v16 => true,
Protocol::Custom { view_tags, .. } => *view_tags,
}
}
/// Whether or not the specified version uses the fee algorithm from Monero
/// hard fork version 16 (released in v18 binaries).
pub fn v16_fee(&self) -> bool {
match self {
Protocol::v14 => false,
Protocol::v16 => true,
Protocol::Custom { v16_fee, .. } => *v16_fee,
}
}
pub fn write<W: stdio::Write>(&self, w: &mut W) -> stdio::Result<()> {
match self {
Protocol::v14 => w.write_all(&[0, 14]),
Protocol::v16 => w.write_all(&[0, 16]),
Protocol::Custom { ring_len, bp_plus, optimal_rct_type, view_tags, v16_fee } => {
// Custom, version 0
w.write_all(&[1, 0])?;
w.write_all(&u16::try_from(*ring_len).unwrap().to_le_bytes())?;
w.write_all(&[u8::from(*bp_plus)])?;
w.write_all(&[optimal_rct_type.to_byte()])?;
w.write_all(&[u8::from(*view_tags)])?;
w.write_all(&[u8::from(*v16_fee)])
}
}
}
pub fn read<R: stdio::Read>(r: &mut R) -> stdio::Result<Protocol> {
Ok(match read_byte(r)? {
// Monero protocol
0 => match read_byte(r)? {
14 => Protocol::v14,
16 => Protocol::v16,
_ => Err(stdio::Error::other("unrecognized monero protocol"))?,
},
// Custom
1 => match read_byte(r)? {
0 => Protocol::Custom {
ring_len: read_u16(r)?.into(),
bp_plus: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
optimal_rct_type: RctType::from_byte(read_byte(r)?)
.ok_or_else(|| stdio::Error::other("invalid RctType serialization"))?,
view_tags: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
v16_fee: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
},
_ => Err(stdio::Error::other("unrecognized custom protocol serialization"))?,
},
_ => Err(stdio::Error::other("unrecognized protocol serialization"))?,
})
}
}

View File

@@ -17,7 +17,6 @@ use crate::{
io::*,
generators::hash_to_point,
ringct::{mlsag::Mlsag, clsag::Clsag, borromean::BorromeanRange, bulletproofs::Bulletproof},
Protocol,
};
/// Generate a key image for a given key. Defined as `x * hash_to_point(xG)`.
@@ -227,10 +226,13 @@ pub enum RctPrunable {
}
impl RctPrunable {
pub fn fee_weight(protocol: Protocol, inputs: usize, outputs: usize) -> usize {
#[rustfmt::skip]
pub fn fee_weight(bp_plus: bool, ring_len: usize, inputs: usize, outputs: usize) -> usize {
// 1 byte for number of BPs (technically a VarInt, yet there's always just zero or one)
1 + Bulletproof::fee_weight(protocol.bp_plus(), outputs) +
(inputs * (Clsag::fee_weight(protocol.ring_len()) + 32))
1 +
Bulletproof::fee_weight(bp_plus, outputs) +
// There's both the CLSAG and the pseudo-out
(inputs * (Clsag::fee_weight(ring_len) + 32))
}
pub fn write<W: Write>(&self, w: &mut W, rct_type: RctType) -> io::Result<()> {
@@ -383,8 +385,14 @@ impl RctSignatures {
}
}
pub fn fee_weight(protocol: Protocol, inputs: usize, outputs: usize, fee: u64) -> usize {
RctBase::fee_weight(outputs, fee) + RctPrunable::fee_weight(protocol, inputs, outputs)
pub fn fee_weight(
bp_plus: bool,
ring_len: usize,
inputs: usize,
outputs: usize,
fee: u64,
) -> usize {
RctBase::fee_weight(outputs, fee) + RctPrunable::fee_weight(bp_plus, ring_len, inputs, outputs)
}
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {

View File

@@ -13,7 +13,6 @@ use crate::{
primitives::keccak256,
ring_signatures::RingSignature,
ringct::{bulletproofs::Bulletproof, RctType, RctBase, RctPrunable, RctSignatures},
Protocol,
};
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -254,15 +253,19 @@ pub struct Transaction {
}
impl Transaction {
// TODO: Replace ring_len, decoy_weights for &[&[usize]], where the inner buf is the decoy
// offsets
pub fn fee_weight(
protocol: Protocol,
view_tags: bool,
bp_plus: bool,
ring_len: usize,
decoy_weights: &[usize],
outputs: usize,
extra: usize,
fee: u64,
) -> usize {
TransactionPrefix::fee_weight(decoy_weights, outputs, protocol.view_tags(), extra) +
RctSignatures::fee_weight(protocol, decoy_weights.len(), outputs, fee)
TransactionPrefix::fee_weight(decoy_weights, outputs, view_tags, extra) +
RctSignatures::fee_weight(bp_plus, ring_len, decoy_weights.len(), outputs, fee)
}
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {