Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable clippy nursery and pedantic checks #188

Merged
merged 8 commits into from
Oct 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ jobs:
run: dprint check

- name: cargo fmt
run: cargo fmt --all -- --check
run: cargo +nightly fmt --all -- --check

- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master
@@ -51,7 +51,7 @@ jobs:
components: clippy

- name: cargo clippy
run: cargo clippy --locked --workspace --examples --tests --all-features -- -D warnings
run: cargo clippy --locked --workspace --examples --tests --all-features -- -D warnings -D clippy::unwrap_used -D clippy::expect_used -D clippy::nursery -D clippy::pedantic -A clippy::module_name_repetitions

cargo-deny:
runs-on: self-hosted
24 changes: 24 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Basic
edition = "2021"
# hard_tabs = true
max_width = 100
use_small_heuristics = "Max"
# Imports
imports_granularity = "Crate"
reorder_imports = true
# Consistency
newline_style = "Unix"
# Misc
chain_width = 80
spaces_around_ranges = false
binop_separator = "Back"
reorder_impl_items = false
match_arm_leading_pipes = "Preserve"
match_arm_blocks = true
match_block_trailing_comma = true
trailing_comma = "Vertical"
trailing_semicolon = true
use_field_init_shorthand = true
# Format comments
comment_width = 100
wrap_comments = true
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions chains/astar/config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,10 @@ pub mod metadata {
pub mod dev {}
}

/// Retrieve the [`BlockchainConfig`] from the provided `network`
///
/// # Errors
/// Returns `Err` if the network is not supported
pub fn config(network: &str) -> Result<BlockchainConfig> {
// All available networks are listed here:
// https://github.com/AstarNetwork/Astar/blob/v5.15.0/bin/collator/src/command.rs#L88-L100
87 changes: 40 additions & 47 deletions chains/astar/server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -40,20 +40,25 @@ pub struct AstarClient {
}

impl AstarClient {
/// Creates a new polkadot client, loading the config from `network` and connects to `addr`
///
/// # Errors
/// Will return `Err` when the network is invalid, or when the provided `addr` is unreacheable.
pub async fn new(network: &str, url: &str) -> Result<Self> {
let config = rosetta_config_astar::config(network)?;
Self::from_config(config, url).await
}

/// Creates a new polkadot client using the provided `config` and connects to `addr`
///
/// # Errors
/// Will return `Err` when the network is invalid, or when the provided `addr` is unreacheable.
pub async fn from_config(config: BlockchainConfig, url: &str) -> Result<Self> {
let client = default_client(url, None).await?;
let substrate_client =
OnlineClient::<PolkadotConfig>::from_rpc_client(Arc::new(client.clone())).await?;
let ethereum_client = MaybeWsEthereumClient::from_jsonrpsee(config, client).await?;
Ok(Self {
client: ethereum_client,
ws_client: substrate_client,
})
Ok(Self { client: ethereum_client, ws_client: substrate_client })
}

async fn account_info(
@@ -80,30 +85,28 @@ impl AstarClient {
.ok_or_else(|| anyhow::anyhow!("no block hash found"))?
};

let account_info = self
.ws_client
.storage()
.at(block_hash)
.fetch(&storage_query)
.await?;

if let Some(account_info) = account_info {
<AccountInfo<u32, AccountData<u128>>>::decode(&mut account_info.encoded())
.map_err(|_| anyhow::anyhow!("invalid format"))
} else {
Ok(AccountInfo::<u32, AccountData<u128>> {
nonce: 0,
consumers: 0,
providers: 0,
sufficients: 0,
data: AccountData {
free: 0,
reserved: 0,
frozen: 0,
flags: astar_metadata::runtime_types::pallet_balances::types::ExtraFlags(0),
},
})
}
let account_info = self.ws_client.storage().at(block_hash).fetch(&storage_query).await?;

account_info.map_or_else(
|| {
Ok(AccountInfo::<u32, AccountData<u128>> {
nonce: 0,
consumers: 0,
providers: 0,
sufficients: 0,
data: AccountData {
free: 0,
reserved: 0,
frozen: 0,
flags: astar_metadata::runtime_types::pallet_balances::types::ExtraFlags(0),
},
})
},
|account_info| {
<AccountInfo<u32, AccountData<u128>>>::decode(&mut account_info.encoded())
.map_err(|_| anyhow::anyhow!("invalid format"))
},
)
}
}

@@ -138,7 +141,7 @@ impl BlockchainClient for AstarClient {
AddressFormat::Ss58(_) => {
let account_info = self.account_info(address, Some(block)).await?;
account_info.data.free
}
},
AddressFormat::Eip55 => {
// Frontier `eth_getBalance` returns the reducible_balance instead the free balance:
// https://github.com/paritytech/frontier/blob/polkadot-v0.9.43/frame/evm/src/lib.rs#L853-L855
@@ -148,10 +151,8 @@ impl BlockchainClient for AstarClient {
.map_err(|err| anyhow::anyhow!("{}", err))?;
let account_info = self.account_info(&address, Some(block)).await?;
account_info.data.free
}
_ => {
return Err(anyhow::anyhow!("invalid address format"));
}
},
AddressFormat::Bech32(_) => return Err(anyhow::anyhow!("invalid address format")),
};
Ok(balance)
}
@@ -192,9 +193,7 @@ impl BlockchainClient for AstarClient {
public_key: &PublicKey,
options: &Self::MetadataParams,
) -> Result<Self::Metadata> {
Ok(AstarMetadata(
self.client.metadata(public_key, &options.0).await?,
))
Ok(AstarMetadata(self.client.metadata(public_key, &options.0).await?))
}

async fn submit(&self, transaction: &[u8]) -> Result<Vec<u8>> {
@@ -225,12 +224,10 @@ impl BlockchainClient for AstarClient {
#[cfg(test)]
mod tests {
use super::*;
use ethers_solc::artifacts::Source;
use ethers_solc::{CompilerInput, EvmVersion, Solc};
use ethers_solc::{artifacts::Source, CompilerInput, EvmVersion, Solc};
use rosetta_docker::Env;
use sha3::Digest;
use std::collections::BTreeMap;
use std::path::Path;
use std::{collections::BTreeMap, path::Path};

pub async fn client_from_config(config: BlockchainConfig) -> Result<AstarClient> {
let url = config.node_uri.to_string();
@@ -301,13 +298,9 @@ mod tests {
let tx_hash = wallet.eth_deploy_contract(bytes).await?;

let receipt = wallet.eth_transaction_receipt(&tx_hash).await?;
let contract_address = receipt
.get("contractAddress")
.and_then(Value::as_str)
.unwrap();
let tx_hash = wallet
.eth_send_call(contract_address, "function emitEvent()", &[], 0)
.await?;
let contract_address = receipt.get("contractAddress").and_then(Value::as_str).unwrap();
let tx_hash =
wallet.eth_send_call(contract_address, "function emitEvent()", &[], 0).await?;
let receipt = wallet.eth_transaction_receipt(&tx_hash).await?;
let logs = receipt.get("logs").and_then(Value::as_array).unwrap();
assert_eq!(logs.len(), 1);
11 changes: 8 additions & 3 deletions chains/bitcoin/config/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use anyhow::Result;
use rosetta_core::crypto::address::AddressFormat;
use rosetta_core::crypto::Algorithm;
use rosetta_core::{BlockchainConfig, NodeUri};
use rosetta_core::{
crypto::{address::AddressFormat, Algorithm},
BlockchainConfig, NodeUri,
};
use std::sync::Arc;

/// Retrieve the [`BlockchainConfig`] from the provided `network`
///
/// # Errors
/// Returns `Err` if the network is not supported
pub fn config(network: &str) -> Result<BlockchainConfig> {
let (network, symbol, bip44_id) = match network {
"regtest" => ("regtest", "tBTC", 1),
85 changes: 35 additions & 50 deletions chains/bitcoin/server/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{Context, Result};
use bitcoincore_rpc_async::bitcoin::BlockHash;
use bitcoincore_rpc_async::{Auth, Client, RpcApi};
use bitcoincore_rpc_async::{bitcoin::BlockHash, Auth, Client, RpcApi};
use rosetta_core::{
crypto::{address::Address, PublicKey},
types::{
@@ -22,35 +21,35 @@ pub struct BitcoinClient {
}

impl BitcoinClient {
/// Creates a new bitcoin client from `network`and `addr`
///
/// # Errors
/// Will return `Err` when the network is invalid, or when the provided `addr` is unreacheable.
pub async fn new(network: &str, addr: &str) -> Result<Self> {
let config = rosetta_config_bitcoin::config(network)?;
Self::from_config(config, addr).await
}

/// Creates a new bitcoin client from `config` and `addr`
///
/// # Errors
/// Will return `Err` when the network is invalid, or when the provided `addr` is unreacheable.
pub async fn from_config(config: BlockchainConfig, addr: &str) -> Result<Self> {
let client = Client::new(
addr.to_string(),
Auth::UserPass("rosetta".into(), "rosetta".into()),
)
.await?;
let client =
Client::new(addr.to_string(), Auth::UserPass("rosetta".into(), "rosetta".into()))
.await?;
let genesis = client.get_block_hash(0).await?;
let genesis_block = BlockIdentifier {
index: 0,
hash: genesis.to_string(),
};
let genesis_block = BlockIdentifier { index: 0, hash: genesis.to_string() };

Ok(Self {
config,
client,
genesis_block,
})
Ok(Self { config, client, genesis_block })
}
}

/// Bitcoin community has adopted 6 blocks as a standard confirmation period.
/// That is, once a transaction is included in a block in the blockchain which is followed up by at least 6 additional blocks
/// the transaction is called “confirmed.” While this was chosen somewhat arbitrarily, it is a reasonably safe value in practice
/// as the only time this would have left users vulnerable to double-spending was the atypical March 2013 fork.
/// That is, once a transaction is included in a block in the blockchain which is followed up by at
/// least 6 additional blocks the transaction is called “confirmed.” While this was chosen somewhat
/// arbitrarily, it is a reasonably safe value in practice as the only time this would have left
/// users vulnerable to double-spending was the atypical March 2013 fork.
const CONFIRMATION_PERIOD: u64 = 6;

#[async_trait::async_trait]
@@ -79,23 +78,13 @@ impl BlockchainClient for BitcoinClient {
async fn current_block(&self) -> Result<BlockIdentifier> {
let hash = self.client.get_best_block_hash().await?;
let info = self.client.get_block_info(&hash).await?;
Ok(BlockIdentifier {
index: info.height as u64,
hash: hash.to_string(),
})
Ok(BlockIdentifier { index: info.height as u64, hash: hash.to_string() })
}

async fn finalized_block(&self) -> Result<BlockIdentifier> {
let index = self
.client
.get_block_count()
.await?
.saturating_sub(CONFIRMATION_PERIOD);
let index = self.client.get_block_count().await?.saturating_sub(CONFIRMATION_PERIOD);
let hash = self.client.get_block_hash(index).await?;
Ok(BlockIdentifier {
index,
hash: hash.to_string(),
})
Ok(BlockIdentifier { index, hash: hash.to_string() })
}

async fn balance(&self, _address: &Address, _block: &BlockIdentifier) -> Result<u128> {
@@ -127,28 +116,24 @@ impl BlockchainClient for BitcoinClient {
(Some(block_hash), _) => {
let hash = BlockHash::from_str(block_hash).context("Invalid block hash")?;
self.client.get_block(&hash).await?
}
},
(None, Some(height)) => {
let block_bash = self
.client
.get_block_hash(height)
.await
.context("cannot find by index")?;
let block_bash =
self.client.get_block_hash(height).await.context("cannot find by index")?;
self.client.get_block(&block_bash).await?
}
},
(None, None) => anyhow::bail!("the block hash or index must be specified"),
};

let block_height = match block.bip34_block_height().ok() {
Some(height) => height,
None => {
let info = self
.client
.get_block_info(&block.block_hash())
.await
.context("Cannot find block height")?;
info.height as u64
}
let block_height = if let Ok(height) = block.bip34_block_height() {
height
} else {
let info = self
.client
.get_block_info(&block.block_hash())
.await
.context("Cannot find block height")?;
info.height as u64
};

let transactions = block
@@ -171,7 +156,7 @@ impl BlockchainClient for BitcoinClient {
index: block_height.saturating_sub(1),
hash: block.header.prev_blockhash.to_string(),
},
timestamp: (block.header.time as i64) * 1000,
timestamp: i64::from(block.header.time) * 1000,
transactions,
metadata: None,
})
Loading
Loading