Skip to content

Commit 870a13d

Browse files
authored
doc, refactor(apps/hermes/server): add code guidelines, enable extra clippy lints (#2777)
* refactor(apps/hermes/server): enable extra clippy lints * doc: add guidelines
1 parent 20df3a3 commit 870a13d

22 files changed

+912
-44
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ Use the [Conventional Commits](https://www.conventionalcommits.org) format for y
5656
In the PR description, please include a summary of the changes and any relevant context. Also, please make sure
5757
to update the package versions following the [Semantic Versioning](https://semver.org/) rules.
5858

59+
See also: [Code guidelines](doc/code-guidelines.md)
60+
5961
### Releases
6062

6163
The repository has several CI workflows that automatically release new versions of the various components when a new Github release is published.

apps/hermes/server/Cargo.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,46 @@ panic = 'abort'
7575

7676
[profile.dev]
7777
panic = 'abort'
78+
79+
80+
[lints.rust]
81+
unsafe_code = "deny"
82+
83+
[lints.clippy]
84+
# See [Rust code guidelines](../../doc/rust-code-guidelines.md)
85+
86+
wildcard_dependencies = "deny"
87+
88+
collapsible_if = "allow"
89+
collapsible_else_if = "allow"
90+
91+
allow_attributes_without_reason = "warn"
92+
93+
# Panics
94+
expect_used = "warn"
95+
fallible_impl_from = "warn"
96+
indexing_slicing = "warn"
97+
panic = "warn"
98+
panic_in_result_fn = "warn"
99+
string_slice = "warn"
100+
todo = "warn"
101+
unchecked_duration_subtraction = "warn"
102+
unreachable = "warn"
103+
unwrap_in_result = "warn"
104+
unwrap_used = "warn"
105+
106+
# Correctness
107+
cast_lossless = "warn"
108+
cast_possible_truncation = "warn"
109+
cast_possible_wrap = "warn"
110+
cast_sign_loss = "warn"
111+
collection_is_never_read = "warn"
112+
match_wild_err_arm = "warn"
113+
path_buf_push_overwrite = "warn"
114+
read_zero_byte_vec = "warn"
115+
same_name_method = "warn"
116+
suspicious_operation_groupings = "warn"
117+
suspicious_xor_used_as_pow = "warn"
118+
unused_self = "warn"
119+
used_underscore_binding = "warn"
120+
while_float = "warn"

apps/hermes/server/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ fn main() {
1313
// Build the wormhole and google protobufs using Rust's prost_build crate.
1414
// The generated Rust code is placed in the OUT_DIR (env var set by cargo).
1515
// `network/wormhole.rs` then includes the generated code into the source while compilation is happening.
16+
#[allow(clippy::expect_used, reason = "failing at build time is fine")]
1617
tonic_build::configure()
1718
.build_server(false)
1819
.compile(

apps/hermes/server/src/api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ where
140140
// Initialize Axum Router. Note the type here is a `Router<State>` due to the use of the
141141
// `with_state` method which replaces `Body` with `State` in the type signature.
142142
let app = Router::new();
143-
#[allow(deprecated)]
143+
#[allow(deprecated, reason = "serving deprecated API endpoints")]
144144
let app = app
145145
.merge(SwaggerUi::new("/docs").url("/docs/openapi.json", ApiDoc::openapi()))
146146
.route("/", get(rest::index))

apps/hermes/server/src/api/rest.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ where
119119
}
120120
}
121121
#[cfg(test)]
122+
#[allow(clippy::unwrap_used, reason = "tests")]
122123
mod tests {
123124
use {
124125
super::*,

apps/hermes/server/src/api/rest/get_vaa_ccip.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,16 @@ pub async fn get_vaa_ccip<S>(
5151
where
5252
S: Aggregates,
5353
{
54+
let data: [u8; 40] = *params.data;
5455
let price_id: PriceIdentifier = PriceIdentifier::new(
55-
params.data[0..32]
56+
data[0..32]
5657
.try_into()
5758
.map_err(|_| RestError::InvalidCCIPInput)?,
5859
);
5960
validate_price_ids(&state, &[price_id], false).await?;
6061

6162
let publish_time = UnixTimestamp::from_be_bytes(
62-
params.data[32..40]
63+
data[32..40]
6364
.try_into()
6465
.map_err(|_| RestError::InvalidCCIPInput)?,
6566
);

apps/hermes/server/src/api/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ impl Display for AssetType {
396396
}
397397

398398
#[cfg(test)]
399+
#[allow(clippy::unwrap_used, reason = "tests")]
399400
mod tests {
400401
use super::*;
401402

apps/hermes/server/src/config.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ mod wormhole;
1414
#[command(author = crate_authors!())]
1515
#[command(about = crate_description!())]
1616
#[command(version = crate_version!())]
17-
#[allow(clippy::large_enum_variant)]
17+
#[allow(
18+
clippy::large_enum_variant,
19+
reason = "performance is not a concern for config"
20+
)]
1821
pub enum Options {
1922
/// Run the Hermes Price Service.
2023
Run(RunOptions),

apps/hermes/server/src/config/cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ pub struct Options {
1414
#[arg(long = "cache-size-slots")]
1515
#[arg(env = "CACHE_SIZE_SLOTS")]
1616
#[arg(default_value = "1600")]
17-
pub size_slots: u64,
17+
pub size_slots: usize,
1818
}

apps/hermes/server/src/main.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use {
2-
anyhow::Result,
2+
anyhow::{Context, Result},
33
clap::{CommandFactory, Parser},
44
futures::future::join_all,
55
lazy_static::lazy_static,
@@ -53,9 +53,13 @@ async fn init() -> Result<()> {
5353
// Listen for Ctrl+C so we can set the exit flag and wait for a graceful shutdown.
5454
spawn(async move {
5555
tracing::info!("Registered shutdown signal handler...");
56-
tokio::signal::ctrl_c().await.unwrap();
57-
tracing::info!("Shut down signal received, waiting for tasks...");
58-
let _ = EXIT.send(true);
56+
match tokio::signal::ctrl_c().await {
57+
Ok(()) => {
58+
tracing::info!("Shut down signal received, waiting for tasks...");
59+
let _ = EXIT.send(true);
60+
}
61+
Err(err) => tracing::warn!("failed to register shutdown signal handler: {err}"),
62+
}
5963
});
6064

6165
// Spawn all worker tasks, and wait for all to complete (which will happen if a shutdown
@@ -83,8 +87,8 @@ async fn init() -> Result<()> {
8387
let defaults = arg
8488
.get_default_values()
8589
.iter()
86-
.map(|v| v.to_str().unwrap())
87-
.collect::<Vec<_>>()
90+
.map(|v| v.to_str().context("non-utf8 default arg value"))
91+
.collect::<Result<Vec<_>>>()?
8892
.join(",");
8993

9094
println!(

0 commit comments

Comments
 (0)