Skip to content

Commit

Permalink
Diversify ViewPair/Scanner into ViewPair/GuaranteedViewPair and Scann…
Browse files Browse the repository at this point in the history
…er/GuaranteedScanner

Also cleans the Scanner impl.
  • Loading branch information
kayabaNerve committed Jul 3, 2024
1 parent 6eff8db commit 94ce9ae
Show file tree
Hide file tree
Showing 32 changed files with 1,460 additions and 1,235 deletions.
11 changes: 11 additions & 0 deletions coins/monero/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ impl Decoys {
}

/// Write the Decoys.
///
/// This is not a Monero protocol defined struct, and this is accordingly not a Monero protocol
/// defined serialization.
pub fn write(&self, w: &mut impl io::Write) -> io::Result<()> {
write_vec(write_varint, &self.offsets, w)?;
w.write_all(&[self.signer_index])?;
Expand All @@ -181,14 +184,22 @@ impl Decoys {
w,
)
}

/// Serialize the Decoys to a `Vec<u8>`.
///
/// This is not a Monero protocol defined struct, and this is accordingly not a Monero protocol
/// defined serialization.
pub fn serialize(&self) -> Vec<u8> {
let mut res =
Vec::with_capacity((1 + (2 * self.offsets.len())) + 1 + 1 + (self.ring.len() * 64));
self.write(&mut res).unwrap();
res
}

/// Read a set of Decoys.
///
/// This is not a Monero protocol defined struct, and this is accordingly not a Monero protocol
/// defined serialization.
pub fn read(r: &mut impl io::Read) -> io::Result<Decoys> {
Decoys::new(
read_vec(read_varint, r)?,
Expand Down
94 changes: 47 additions & 47 deletions coins/monero/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ use monero_serai::{
// src/wallet/wallet2.cpp#L121
const GRACE_BLOCKS_FOR_FEE_ESTIMATE: u64 = 10;

/// An error from the RPC.
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum RpcError {
/// An internal error.
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(String),
/// A connection error with the node.
#[cfg_attr(feature = "std", error("connection error ({0})"))]
ConnectionError(String),
/// The node is invalid per the expected protocol.
#[cfg_attr(feature = "std", error("invalid node ({0})"))]
InvalidNode(String),
/// Requested transactions weren't found.
#[cfg_attr(feature = "std", error("transactions not found"))]
TransactionsNotFound(Vec<[u8; 32]>),
/// The transaction was pruned.
///
/// Pruned transactions are not supported at this time.
#[cfg_attr(feature = "std", error("pruned transaction"))]
PrunedTransaction,
/// A transaction (sent or received) was invalid.
#[cfg_attr(feature = "std", error("invalid transaction ({0:?})"))]
InvalidTransaction([u8; 32]),
/// The returned fee was unusable.
#[cfg_attr(feature = "std", error("unexpected fee response"))]
InvalidFee,
/// The priority intended for use wasn't usable.
#[cfg_attr(feature = "std", error("invalid priority"))]
InvalidPriority,
}

/// A struct containing a fee rate.
///
/// The fee rate is defined as a per-weight cost, along with a mask for rounding purposes.
Expand Down Expand Up @@ -147,7 +179,7 @@ struct TransactionsResponse {
#[derive(Deserialize, Debug)]
pub struct OutputResponse {
/// The height of the block this output was added to the chain in.
pub height: u32,
pub height: usize,
/// If the output is unlocked, per the node's local view.
pub unlocked: bool,
/// The output's key.
Expand All @@ -158,38 +190,6 @@ pub struct OutputResponse {
pub txid: String,
}

/// An error from the RPC.
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum RpcError {
/// An internal error.
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(&'static str),
/// A connection error with the node.
#[cfg_attr(feature = "std", error("connection error ({0})"))]
ConnectionError(String),
/// The node is invalid per the expected protocol.
#[cfg_attr(feature = "std", error("invalid node ({0})"))]
InvalidNode(String),
/// Requested transactions weren't found.
#[cfg_attr(feature = "std", error("transactions not found"))]
TransactionsNotFound(Vec<[u8; 32]>),
/// The transaction was pruned.
///
/// Pruned transactions are not supported at this time.
#[cfg_attr(feature = "std", error("pruned transaction"))]
PrunedTransaction,
/// A transaction (sent or received) was invalid.
#[cfg_attr(feature = "std", error("invalid transaction ({0:?})"))]
InvalidTransaction([u8; 32]),
/// The returned fee was unusable.
#[cfg_attr(feature = "std", error("unexpected fee response"))]
InvalidFee,
/// The priority intended for use wasn't usable.
#[cfg_attr(feature = "std", error("invalid priority"))]
InvalidPriority,
}

fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
hex::decode(value).map_err(|_| RpcError::InvalidNode("expected hex wasn't hex".to_string()))
}
Expand Down Expand Up @@ -309,10 +309,10 @@ pub trait Rpc: Sync + Clone + Debug {
///
/// The height is defined as the amount of blocks on the blockchain. For a blockchain with only
/// its genesis block, the height will be 1.
async fn get_height(&self) -> Result<u32, RpcError> {
async fn get_height(&self) -> Result<usize, RpcError> {
#[derive(Deserialize, Debug)]
struct HeightResponse {
height: u32,
height: usize,
}
Ok(self.rpc_call::<Option<()>, HeightResponse>("get_height", None).await?.height)
}
Expand Down Expand Up @@ -397,7 +397,7 @@ pub trait Rpc: Sync + Clone + Debug {
///
/// `number` is the block's zero-indexed position on the blockchain (`0` for the genesis block,
/// `height - 1` for the latest block).
async fn get_block_hash(&self, number: u32) -> Result<[u8; 32], RpcError> {
async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> {
#[derive(Deserialize, Debug)]
struct BlockHeaderResponse {
hash: String,
Expand Down Expand Up @@ -436,7 +436,7 @@ pub trait Rpc: Sync + Clone + Debug {
///
/// `number` is the block's zero-indexed position on the blockchain (`0` for the genesis block,
/// `height - 1` for the latest block).
async fn get_block_by_number(&self, number: u32) -> Result<Block, RpcError> {
async fn get_block_by_number(&self, number: usize) -> Result<Block, RpcError> {
#[derive(Deserialize, Debug)]
struct BlockResponse {
blob: String,
Expand All @@ -449,16 +449,16 @@ pub trait Rpc: Sync + Clone + Debug {
.map_err(|_| RpcError::InvalidNode("invalid block".to_string()))?;

// Make sure this is actually the block for this number
match block.miner_tx.prefix().inputs.first() {
match block.miner_transaction.prefix().inputs.first() {
Some(Input::Gen(actual)) => {
if u32::try_from(*actual) == Ok(number) {
if usize::try_from(*actual) == Ok(number) {
Ok(block)
} else {
Err(RpcError::InvalidNode("different block than requested (number)".to_string()))
}
}
_ => Err(RpcError::InvalidNode(
"block's miner_tx didn't have an input of kind Input::Gen".to_string(),
"block's miner_transaction didn't have an input of kind Input::Gen".to_string(),
)),
}
}
Expand All @@ -471,8 +471,8 @@ pub trait Rpc: Sync + Clone + Debug {
/// block's header.
async fn get_block_transactions(&self, hash: [u8; 32]) -> Result<Vec<Transaction>, RpcError> {
let block = self.get_block(hash).await?;
let mut res = vec![block.miner_tx];
res.extend(self.get_transactions(&block.txs).await?);
let mut res = vec![block.miner_transaction];
res.extend(self.get_transactions(&block.transactions).await?);
Ok(res)
}

Expand All @@ -484,7 +484,7 @@ pub trait Rpc: Sync + Clone + Debug {
/// block's header.
async fn get_block_transactions_by_number(
&self,
number: u32,
number: usize,
) -> Result<Vec<Transaction>, RpcError> {
self.get_block_transactions(self.get_block_hash(number).await?).await
}
Expand Down Expand Up @@ -647,7 +647,7 @@ pub trait Rpc: Sync + Clone + Debug {
/// Get the output distribution.
///
/// `from` and `to` are heights, not block numbers, and inclusive.
async fn get_output_distribution(&self, from: u32, to: u32) -> Result<Vec<u64>, RpcError> {
async fn get_output_distribution(&self, from: usize, to: usize) -> Result<Vec<u64>, RpcError> {
#[derive(Deserialize, Debug)]
struct Distribution {
distribution: Vec<u64>,
Expand Down Expand Up @@ -716,7 +716,7 @@ pub trait Rpc: Sync + Clone + Debug {
async fn get_unlocked_outputs(
&self,
indexes: &[u64],
height: u32,
height: usize,
fingerprintable_canonical: bool,
) -> Result<Vec<Option<[EdwardsPoint; 2]>>, RpcError> {
let outs: Vec<OutputResponse> = self.get_outs(indexes).await?;
Expand Down Expand Up @@ -857,11 +857,11 @@ pub trait Rpc: Sync + Clone + Debug {
&self,
address: &str,
block_count: usize,
) -> Result<(Vec<[u8; 32]>, u32), RpcError> {
) -> Result<(Vec<[u8; 32]>, usize), RpcError> {
#[derive(Debug, Deserialize)]
struct BlocksResponse {
blocks: Vec<String>,
height: u32,
height: usize,
}

let res = self
Expand Down
26 changes: 14 additions & 12 deletions coins/monero/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl BlockHeader {
w.write_all(&self.nonce.to_le_bytes())
}

/// Serialize the BlockHeader to a Vec<u8>.
/// Serialize the BlockHeader to a `Vec<u8>`.
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();
Expand All @@ -72,9 +72,9 @@ pub struct Block {
/// The block's header.
pub header: BlockHeader,
/// The miner's transaction.
pub miner_tx: Transaction,
pub miner_transaction: Transaction,
/// The transactions within this block.
pub txs: Vec<[u8; 32]>,
pub transactions: Vec<[u8; 32]>,
}

impl Block {
Expand All @@ -83,7 +83,7 @@ impl Block {
/// This information comes from the Block's miner transaction. If the miner transaction isn't
/// structed as expected, this will return None.
pub fn number(&self) -> Option<u64> {
match &self.miner_tx {
match &self.miner_transaction {
Transaction::V1 { prefix, .. } | Transaction::V2 { prefix, .. } => {
match prefix.inputs.first() {
Some(Input::Gen(number)) => Some(*number),
Expand All @@ -96,15 +96,15 @@ impl Block {
/// Write the Block.
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
self.header.write(w)?;
self.miner_tx.write(w)?;
write_varint(&self.txs.len(), w)?;
for tx in &self.txs {
self.miner_transaction.write(w)?;
write_varint(&self.transactions.len(), w)?;
for tx in &self.transactions {
w.write_all(tx)?;
}
Ok(())
}

/// Serialize the Block to a Vec<u8>.
/// Serialize the Block to a `Vec<u8>`.
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();
Expand All @@ -117,8 +117,8 @@ impl Block {
/// use the [`Block::hash`] function.
pub fn serialize_pow_hash(&self) -> Vec<u8> {
let mut blob = self.header.serialize();
blob.extend_from_slice(&merkle_root(self.miner_tx.hash(), &self.txs));
write_varint(&(1 + u64::try_from(self.txs.len()).unwrap()), &mut blob).unwrap();
blob.extend_from_slice(&merkle_root(self.miner_transaction.hash(), &self.transactions));
write_varint(&(1 + u64::try_from(self.transactions.len()).unwrap()), &mut blob).unwrap();
blob
}

Expand All @@ -142,8 +142,10 @@ impl Block {
pub fn read<R: Read>(r: &mut R) -> io::Result<Block> {
Ok(Block {
header: BlockHeader::read(r)?,
miner_tx: Transaction::read(r)?,
txs: (0_usize .. read_varint(r)?).map(|_| read_bytes(r)).collect::<Result<_, _>>()?,
miner_transaction: Transaction::read(r)?,
transactions: (0_usize .. read_varint(r)?)
.map(|_| read_bytes(r))
.collect::<Result<_, _>>()?,
})
}
}
4 changes: 2 additions & 2 deletions coins/monero/src/ringct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl RctPrunable {
}
}

/// Serialize the RctPrunable to a Vec<u8>.
/// Serialize the RctPrunable to a `Vec<u8>`.
pub fn serialize(&self, rct_type: RctType) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized, rct_type).unwrap();
Expand Down Expand Up @@ -437,7 +437,7 @@ impl RctProofs {
self.prunable.write(w, rct_type)
}

/// Serialize the RctProofs to a Vec<u8>.
/// Serialize the RctProofs to a `Vec<u8>`.
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();
Expand Down
Loading

0 comments on commit 94ce9ae

Please sign in to comment.