Skip to content

Commit

Permalink
Fixed all the minor Clippy rants
Browse files Browse the repository at this point in the history
  • Loading branch information
kirushik committed Mar 4, 2024
1 parent cebef9c commit 2aec22f
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 65 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ shadow_reuse = "warn"
shadow_same = "warn"
shadow_unrelated = "warn"
cargo_common_metadata = "warn"

[package.metadata.scripts]
full_clippy = "cargo clippy --all-targets --all-features -- -D warnings -D clippy::pedantic -D clippy::correctness -D clippy::complexity -D clippy::perf"
57 changes: 44 additions & 13 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::{
use anyhow::{Context, Result};
use redb::{
backends::InMemoryBackend, AccessGuard, ReadOnlyTable, ReadableTable, RedbValue, Table,
TableDefinition, TableHandle, TypeName,
TableDefinition, TableHandle, TypeName, Database as RedbDatabase
};
use std::sync::Arc;
use std::{borrow::Borrow, sync::Arc};
use subxt::{
ext::{
codec::{Compact, Decode, Encode},
Expand Down Expand Up @@ -65,6 +65,18 @@ impl Invoice {

Ok(PairSigner::new(invoice_pair))
}

pub fn price_as_u128(&self) -> u128 {
match self.status {
InvoiceStatus::Unpaid(price) | InvoiceStatus::Paid(price) => price,
}
}

#[allow(clippy::cast_precision_loss)] // We're converting from u128 to f64 for prices, possibly rounding things a bit. Should be fine 🤞
pub fn price_as_float(&self, decimals: u64) -> Result<f64> {
let mul = 10f64.powi(decimals.try_into()?);
Ok(self.price_as_u128() as f64 / mul)
}
}

#[derive(Debug, Encode, Decode)]
Expand All @@ -74,6 +86,15 @@ pub enum InvoiceStatus {
Paid(Balance),
}

impl InvoiceStatus {
pub fn status_string(&self) -> String {
match self {
InvoiceStatus::Unpaid(_) => "unpaid".to_owned(),
InvoiceStatus::Paid(_) => "paid".to_owned(),
}
}
}

impl RedbValue for Invoice {
type SelfType<'a> = Self;

Expand Down Expand Up @@ -107,7 +128,7 @@ struct DaemonInfo {
}

pub struct Database {
database: redb::Database,
underlying_db: RedbDatabase,
properties: Arc<RwLock<ChainProperties>>,
pair: Pair,
rpc: String,
Expand Down Expand Up @@ -203,7 +224,7 @@ impl Database {
}

if let Some(encoded_last_block) = last_block_option {
Some(decode_slot::<Compact<BlockNumber>>(encoded_last_block, LAST_BLOCK)?.0)
Some(decode_slot::<Compact<BlockNumber>, Vec<u8>>(encoded_last_block, LAST_BLOCK)?.0)
} else {
None
}
Expand All @@ -222,16 +243,16 @@ impl Database {
.context("failed to compact the database")?;

if compacted {
log::debug!("The database was successfully compacted.")
log::debug!("The database was successfully compacted.");
} else {
log::debug!("The database doesn't need the compaction.")
log::debug!("The database doesn't need the compaction.");
}

log::info!("Public key from the given seed: \"{public_formatted}\".");

Ok((
Arc::new(Self {
database,
underlying_db: database,
properties: chain,
pair,
rpc: given_rpc,
Expand All @@ -250,14 +271,14 @@ impl Database {
}

pub fn write(&self) -> Result<WriteTransaction<'_>> {
self.database
self.underlying_db
.begin_write()
.map(WriteTransaction)
.context("failed to begin a write transaction for the database")
}

pub fn read(&self) -> Result<ReadTransaction<'_>> {
self.database
self.underlying_db
.begin_read()
.map(ReadTransaction)
.context("failed to begin a read transaction for the database")
Expand Down Expand Up @@ -292,7 +313,7 @@ impl ReadInvoices<'_> {
.context("failed to get an invoice from the database")
}

pub fn iter(
pub fn try_getting_iterator(
&self,
) -> Result<impl Iterator<Item = Result<(AccessGuard<'_, &[u8; 32]>, AccessGuard<'_, Invoice>)>>>
{
Expand All @@ -303,6 +324,16 @@ impl ReadInvoices<'_> {
}
}

impl IntoIterator for ReadInvoices<'_> {
type Item = Result<(AccessGuard<'_, &[u8; 32]>, AccessGuard<'_, Invoice>)>;

type IntoIter = Box<dyn Iterator<Item = Self::Item>>;

fn into_iter(self) -> Self::IntoIter {
Box::new(self.0.into_iter().map(|item| item.context("failed to get an invoice from the iterator")))
}
}

pub struct WriteTransaction<'db>(redb::WriteTransaction<'db>);

impl<'db> WriteTransaction<'db> {
Expand Down Expand Up @@ -356,12 +387,12 @@ impl Root<'_, '_> {
fn get_slot(table: &Table<'_, '_, &str, Vec<u8>>, key: &str) -> Result<Option<Vec<u8>>> {
table
.get(key)
.map(|slot_option| slot_option.map(|slot| slot.value().to_vec()))
.map(|slot_option| slot_option.map(|slot| slot.value().clone()))
.with_context(|| format!("failed to get the {key:?} slot"))
}

fn decode_slot<T: Decode>(slot: Vec<u8>, key: &str) -> Result<T> {
T::decode(&mut slot.as_ref()).with_context(|| format!("failed to decode the {key:?} slot"))
fn decode_slot<T: Decode, B: Borrow<[u8]>>(slot: B, key: &str) -> Result<T> {
T::decode(&mut slot.borrow()).with_context(|| format!("failed to decode the {key:?} slot"))
}

fn insert_daemon_info(
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::{Context, Error, Result};
use database::Database;
use env_logger::{Builder, Env};
use environment_variables::*;
use environment_variables::{DATABASE, DECIMALS, DESTINATION, HOST, IN_MEMORY_DB, LOG, LOG_STYLE, OVERRIDE_RPC, RPC, SEED};
use log::LevelFilter;
use rpc::Processor;
use std::{
Expand Down Expand Up @@ -88,6 +88,7 @@ impl Config for RuntimeConfig {

#[doc(hidden)]
#[tokio::main]
#[allow(clippy::too_many_lines)] // FIXME: Better structured main() is needed
pub async fn main() -> Result<()> {
let mut builder = Builder::new();

Expand Down
37 changes: 10 additions & 27 deletions src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub struct ChainProperties {
}

impl ChainProperties {
async fn fetch_only_constants(
fn fetch_only_constants(
constants: &ConstantsClient<RuntimeConfig, OnlineClient>,
decimals: Decimals,
) -> Result<Self> {
Expand Down Expand Up @@ -154,7 +154,7 @@ impl ChainProperties {
"failed to decode the decimal places number, expected a positive integer, got \"{encoded_decimals}\""
))?;

Self::fetch_only_constants(constants, decimals).await
Self::fetch_only_constants(constants, decimals)
}
}

Expand Down Expand Up @@ -213,7 +213,7 @@ pub async fn prepare(

let (properties_result, decimals_set) = if let Some(decimals) = decimals_option {
(
ChainProperties::fetch_only_constants(&constants, decimals).await,
ChainProperties::fetch_only_constants(&constants, decimals),
true,
)
} else {
Expand Down Expand Up @@ -331,8 +331,7 @@ impl Updater {
let (mut current_properties, new_properties_result) = if self.decimals_set {
let current_properties = self.properties.write().await;
let new_properties_result =
ChainProperties::fetch_only_constants(&self.constants, current_properties.decimals)
.await;
ChainProperties::fetch_only_constants(&self.constants, current_properties.decimals);

(current_properties, new_properties_result)
} else {
Expand Down Expand Up @@ -464,7 +463,7 @@ impl ProcessorFinalized {
// TODO:
// Design a new DB format to store unpaid accounts in a separate table.

for invoice_result in self.database.read()?.invoices()?.iter()? {
for invoice_result in self.database.read()?.invoices()?.try_getting_iterator()? {
let invoice = invoice_result?;

match invoice.1.value().status {
Expand Down Expand Up @@ -599,9 +598,6 @@ impl ProcessorFinalized {
let event = event_result.context("failed to decode an event")?;
let metadata = event.event_metadata();

const UPDATE: &str = "CodeUpdated";
const TRANSFER: &str = "Transfer";

match (metadata.pallet.name(), &*metadata.variant.name) {
(SYSTEM, UPDATE) => update = true,
(BALANCES, TRANSFER) => Transfer::deserialize(
Expand Down Expand Up @@ -694,6 +690,9 @@ pub struct Processor {
shutdown_notification: CancellationToken,
}

const UPDATE: &str = "CodeUpdated";
const TRANSFER: &str = "Transfer";

impl Processor {
pub fn new(
ApiConfig {
Expand Down Expand Up @@ -981,9 +980,6 @@ impl Processor {
let event = event_result.context("failed to decode an event")?;
let metadata = event.event_metadata();

const UPDATE: &str = "CodeUpdated";
const TRANSFER: &str = "Transfer";

match (metadata.pallet.name(), &*metadata.variant.name) {
(SYSTEM, UPDATE) => update = true,
(BALANCES, TRANSFER) => Transfer::deserialize(
Expand All @@ -998,14 +994,11 @@ impl Processor {
}

for (invoice, changes) in invoices_changes {
let price = match changes.invoice.status {
InvoiceStatus::Unpaid(price) => price,
InvoiceStatus::Paid(price) => price,
};
let price = changes.invoice.price_as_u128();

self.process_unpaid(&block, changes, hash, invoice, price)
.await
.context("failed to process an unpaid invoice")?
.context("failed to process an unpaid invoice")?;
}

if update {
Expand Down Expand Up @@ -1188,16 +1181,6 @@ impl Processor {

Ok(())
}

async fn process_paid(
&self,
_invoice: Account,
_block: &Block<RuntimeConfig, OnlineClient>,
_changes: InvoiceChanges,
_hash: Hash,
) -> Result<()> {
Ok(())
}
}

fn construct_transfer(to: &Account, _amount: Balance) -> Value {
Expand Down
38 changes: 14 additions & 24 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,20 @@ async fn handler(

async fn abcd(
database: Arc<Database>,
rrecipient: Option<String>,
recipient_option: Option<String>,
order: String,
pprice: f64,
price: f64,
) -> Result<Success, anyhow::Error> {
let recipient = rrecipient.context("destionation address isn't set")?;
let recipient = recipient_option.context("destination address isn't set")?;
let decoded_recip = hex::decode(&recipient[2..])?;
let recipient_account = Account::try_from(decoded_recip.as_ref())
.map_err(|()| anyhow::anyhow!("Unknown address length"))?;
let properties = database.properties().await;
let mul = 10u128.pow(properties.decimals.try_into()?) as f64;
let price = (pprice * mul).round() as u128;
let mul = 10f64.powi(properties.decimals.try_into()?);

#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] // Price is positive, and mul is natural; in case of overflow, the price was too high to begin with
let price_in_plancks = (price * mul).round() as u128;

let order_encoded = DeriveJunction::hard(&order).unwrap_inner();
let invoice_account: Account = database
.pair()
Expand All @@ -146,26 +149,19 @@ async fn abcd(
let invoice = encoded_invoice.value();

if let InvoiceStatus::Unpaid(saved_price) = invoice.status {
if saved_price != price {
anyhow::bail!("The invoice was created with different price ({price}).");
if saved_price != price_in_plancks {
anyhow::bail!("The invoice was created with different price ({price_in_plancks}).");
}
}

Ok(Success {
pay_account: format!("0x{}", HexDisplay::from(&invoice_account.as_ref())),
price: match invoice.status {
InvoiceStatus::Unpaid(uprice) => convert(properties.decimals, uprice)?,
InvoiceStatus::Paid(uprice) => convert(properties.decimals, uprice)?,
},
price: invoice.price_as_float(properties.decimals)?,
wss: database.rpc().to_string(),
mul: properties.decimals,
recipient,
order,
result: match invoice.status {
InvoiceStatus::Unpaid(_) => "waiting",
InvoiceStatus::Paid(_) => "paid",
}
.into(),
result: invoice.status.status_string(),
version: env!("CARGO_PKG_VERSION").into(),
})
} else {
Expand All @@ -176,15 +172,15 @@ async fn abcd(
&Invoice {
recipient: recipient_account,
order: order_encoded,
status: InvoiceStatus::Unpaid(price),
status: InvoiceStatus::Unpaid(price_in_plancks),
},
)?;

tx.commit()?;

Ok(Success {
pay_account: format!("0x{}", HexDisplay::from(&invoice_account.as_ref())),
price: pprice,
price,
wss: database.rpc().to_string(),
mul: properties.decimals,
recipient,
Expand All @@ -195,9 +191,3 @@ async fn abcd(
}
}

fn convert(dec: u64, num: u128) -> Result<f64> {
let numfl = num as f64;
let mul = 10u128.pow(dec.try_into()?) as f64;

Ok(numfl / mul)
}

0 comments on commit 2aec22f

Please sign in to comment.