Ver código fonte

chore: switch to stable rust versions (#2093)

* chore(apps/hermes): switch to stable rust

* chore(apps/fortuna): update to stable rust

* chore: remove commented feature

* chore(governance): use proper Rust version for remote executor in CI

* chore(target_chains/cosmwasm): fix Rust version in CI

* chore(pythnet/message_buffer): use proper Rust version in CI

* chore(pythnet/pythnet_sdk): fix Rust version

* chore(target_chains/solana): fix Rust version in CI
Pavel Strakhov 1 ano atrás
pai
commit
ed0f273dcb
34 arquivos alterados com 151 adições e 121 exclusões
  1. 6 0
      .github/workflows/ci-cosmwasm-contract.yml
  2. 1 1
      .github/workflows/ci-fortuna.yml
  3. 1 1
      .github/workflows/ci-hermes-server.yml
  4. 1 1
      .github/workflows/ci-message-buffer-idl.yml
  5. 15 0
      .github/workflows/ci-pre-commit.yml
  6. 5 0
      .github/workflows/ci-solana-contract.yml
  7. 12 6
      .pre-commit-config.yaml
  8. 22 6
      apps/fortuna/Cargo.lock
  9. 1 4
      apps/fortuna/Dockerfile
  10. 1 1
      apps/fortuna/rust-toolchain
  11. 2 2
      apps/fortuna/src/api/revelation.rs
  12. 4 4
      apps/fortuna/src/chain/ethereum.rs
  13. 3 3
      apps/fortuna/src/chain/reader.rs
  14. 1 1
      apps/fortuna/src/command/generate.rs
  15. 4 4
      apps/fortuna/src/command/register_provider.rs
  16. 8 8
      apps/fortuna/src/command/run.rs
  17. 5 5
      apps/fortuna/src/command/setup_provider.rs
  18. 4 4
      apps/fortuna/src/command/withdraw_fees.rs
  19. 8 12
      apps/fortuna/src/config.rs
  20. 7 9
      apps/fortuna/src/keeper.rs
  21. 0 1
      apps/fortuna/src/main.rs
  22. 8 8
      apps/fortuna/src/state.rs
  23. 4 4
      apps/hermes/server/Cargo.lock
  24. 2 8
      apps/hermes/server/Dockerfile
  25. 3 3
      apps/hermes/server/README.md
  26. 1 1
      apps/hermes/server/rust-toolchain
  27. 0 3
      apps/hermes/server/src/main.rs
  28. 1 1
      apps/hermes/server/src/network/pythnet.rs
  29. 1 1
      apps/hermes/server/src/network/wormhole.rs
  30. 2 3
      apps/hermes/server/src/state/cache.rs
  31. 0 2
      pythnet/pythnet_sdk/examples/generate_pyth_data.rs
  32. 1 0
      pythnet/pythnet_sdk/rust-toolchain
  33. 7 4
      pythnet/pythnet_sdk/src/wire.rs
  34. 10 10
      target_chains/cosmwasm/contracts/pyth/src/contract.rs

+ 6 - 0
.github/workflows/ci-cosmwasm-contract.yml

@@ -23,6 +23,12 @@ jobs:
         working-directory: target_chains/cosmwasm/contracts/pyth
     steps:
       - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.82.0
+          components: rustfmt, clippy
+          override: true
       - name: Build
         run: cargo build --verbose
       - name: Run tests

+ 1 - 1
.github/workflows/ci-fortuna.yml

@@ -14,7 +14,7 @@ jobs:
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
-          toolchain: nightly-2023-07-23
+          toolchain: 1.82.0
           override: true
       - name: Run executor tests
         run: cargo test --manifest-path ./apps/fortuna/Cargo.toml

+ 1 - 1
.github/workflows/ci-hermes-server.yml

@@ -14,7 +14,7 @@ jobs:
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
-          toolchain: nightly-2024-03-26
+          toolchain: 1.82.0
           components: rustfmt, clippy
           override: true
       - name: Install protoc

+ 1 - 1
.github/workflows/ci-message-buffer-idl.yml

@@ -21,7 +21,7 @@ jobs:
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
-          toolchain: nightly-2023-03-01
+          toolchain: 1.66.1
           components: rustfmt, clippy
       - name: Install Solana
         run: |

+ 15 - 0
.github/workflows/ci-pre-commit.yml

@@ -37,6 +37,21 @@ jobs:
           profile: minimal
           toolchain: nightly-2024-08-04
           components: rustfmt, clippy
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.66.1
+          components: rustfmt, clippy
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.73.0
+          components: rustfmt, clippy
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.82.0
+          components: rustfmt, clippy
       - name: Install protoc
         uses: arduino/setup-protoc@v3
       - uses: actions/checkout@v4

+ 5 - 0
.github/workflows/ci-solana-contract.yml

@@ -23,6 +23,11 @@ jobs:
         working-directory: target_chains/solana
     steps:
       - uses: actions/checkout@v2
+      - uses: actions-rs/toolchain@v1
+        with:
+          profile: minimal
+          toolchain: 1.73.0
+          override: true
       - name: Install Solana
         run: |
           sh -c "$(curl -sSfL https://release.solana.com/v1.16.20/install)"

+ 12 - 6
.pre-commit-config.yaml

@@ -30,7 +30,7 @@ repos:
       - id: cargo-clippy-remote-executor
         name: Cargo clippy for remote executor
         language: "rust"
-        entry: cargo +nightly-2023-03-01 clippy --manifest-path ./governance/remote_executor/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        entry: cargo +1.66.1 clippy --manifest-path ./governance/remote_executor/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
         pass_filenames: false
         files: governance/remote_executor
       # Hooks for cosmwasm contract
@@ -43,7 +43,7 @@ repos:
       - id: cargo-clippy-cosmwasm
         name: Cargo clippy for cosmwasm contract
         language: "rust"
-        entry: cargo +nightly-2023-03-01 clippy --manifest-path ./target_chains/cosmwasm/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        entry: cargo +1.82.0 clippy --manifest-path ./target_chains/cosmwasm/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
         pass_filenames: false
         files: target_chains/cosmwasm
       # Hooks for Hermes
@@ -56,7 +56,7 @@ repos:
       - id: cargo-clippy-hermes
         name: Cargo clippy for Hermes
         language: "rust"
-        entry: cargo +nightly-2024-03-26 clippy --manifest-path ./apps/hermes/server/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        entry: cargo +1.82.0 clippy --manifest-path ./apps/hermes/server/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
         pass_filenames: false
         files: apps/hermes
       # Hooks for Fortuna
@@ -66,6 +66,12 @@ repos:
         entry: cargo +nightly-2023-07-23 fmt --manifest-path ./apps/fortuna/Cargo.toml --all -- --config-path rustfmt.toml
         pass_filenames: false
         files: apps/fortuna
+      - id: cargo-clippy-fortuna
+        name: Cargo clippy for Fortuna
+        language: "rust"
+        entry: cargo +1.82.0 clippy --manifest-path ./apps/fortuna/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        pass_filenames: false
+        files: apps/fortuna
       # Hooks for message buffer contract
       - id: cargo-fmt-message-buffer
         name: Cargo format for message buffer contract
@@ -76,7 +82,7 @@ repos:
       - id: cargo-clippy-message-buffer
         name: Cargo clippy for message buffer contract
         language: "rust"
-        entry: cargo +nightly-2023-03-01 clippy --manifest-path ./pythnet/message_buffer/Cargo.toml --tests --fix --allow-dirty --allow-staged --features test-bpf -- -D warnings
+        entry: cargo +1.66.1 clippy --manifest-path ./pythnet/message_buffer/Cargo.toml --tests --fix --allow-dirty --allow-staged --features test-bpf -- -D warnings
         pass_filenames: false
         files: pythnet/message_buffer
       # Hooks for pythnet_sdk
@@ -89,7 +95,7 @@ repos:
       - id: cargo-clippy-pythnet-sdk
         name: Cargo clippy for pythnet SDK
         language: "rust"
-        entry: cargo +nightly-2024-08-04 clippy --manifest-path ./pythnet/pythnet_sdk/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        entry: cargo +1.82.0 clippy --manifest-path ./pythnet/pythnet_sdk/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
         pass_filenames: false
         files: pythnet/pythnet_sdk
       # Hooks for solana receiver contract
@@ -102,7 +108,7 @@ repos:
       - id: cargo-clippy-pyth-solana-receiver
         name: Cargo clippy for solana target chain contract
         language: "rust"
-        entry: cargo +nightly-2023-03-01 clippy --manifest-path ./target_chains/solana/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
+        entry: cargo +1.73.0 clippy --manifest-path ./target_chains/solana/Cargo.toml --tests --fix --allow-dirty --allow-staged -- -D warnings
         pass_filenames: false
         files: target_chains/solana
       # For express relay python files

+ 22 - 6
apps/fortuna/Cargo.lock

@@ -876,10 +876,11 @@ dependencies = [
 
 [[package]]
 name = "deranged"
-version = "0.3.8"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
 dependencies = [
+ "powerfmt",
  "serde",
 ]
 
@@ -2337,6 +2338,12 @@ dependencies = [
  "num-traits",
 ]
 
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
 [[package]]
 name = "num-integer"
 version = "0.1.45"
@@ -2728,6 +2735,12 @@ version = "0.3.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
 
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.17"
@@ -3837,12 +3850,14 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.29"
+version = "0.3.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
 dependencies = [
  "deranged",
  "itoa",
+ "num-conv",
+ "powerfmt",
  "serde",
  "time-core",
  "time-macros",
@@ -3856,10 +3871,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
 
 [[package]]
 name = "time-macros"
-version = "0.2.15"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
 dependencies = [
+ "num-conv",
  "time-core",
 ]
 

+ 1 - 4
apps/fortuna/Dockerfile

@@ -1,10 +1,7 @@
-ARG RUST_VERSION=1.66.1
+ARG RUST_VERSION=1.82.0
 
 FROM rust:${RUST_VERSION} AS build
 
-# Set default toolchain
-RUN rustup default nightly-2023-07-23
-
 # Build
 WORKDIR /src
 COPY apps/fortuna apps/fortuna

+ 1 - 1
apps/fortuna/rust-toolchain

@@ -1 +1 @@
-nightly-2023-07-23
+1.82.0

+ 2 - 2
apps/fortuna/src/api/revelation.rs

@@ -58,7 +58,7 @@ pub async fn revelation(
     let state = state
         .chains
         .get(&chain_id)
-        .ok_or_else(|| RestError::InvalidChainId)?;
+        .ok_or(RestError::InvalidChainId)?;
 
     let maybe_request_fut = state.contract.get_request(state.provider_address, sequence);
 
@@ -85,7 +85,7 @@ pub async fn revelation(
                 );
                 RestError::Unknown
             })?;
-            let encoded_value = Blob::new(encoding.unwrap_or(BinaryEncoding::Hex), value.clone());
+            let encoded_value = Blob::new(encoding.unwrap_or(BinaryEncoding::Hex), *value);
 
             Ok(Json(GetRandomValueResponse {
                 value: encoded_value,

+ 4 - 4
apps/fortuna/src/chain/ethereum.rs

@@ -204,10 +204,10 @@ impl<T: JsonRpcClient + 'static + Clone> SignablePythContractInner<T> {
             if let PythRandomEvents::RequestedFilter(r) = PythRandomEvents::decode_log(&l)? {
                 Ok(r.request.sequence_number)
             } else {
-                Err(anyhow!("No log with sequence number").into())
+                Err(anyhow!("No log with sequence number"))
             }
         } else {
-            Err(anyhow!("Request failed").into())
+            Err(anyhow!("Request failed"))
         }
     }
 
@@ -238,10 +238,10 @@ impl<T: JsonRpcClient + 'static + Clone> SignablePythContractInner<T> {
             {
                 Ok(r.random_number)
             } else {
-                Err(anyhow!("No log with randomnumber").into())
+                Err(anyhow!("No log with randomnumber"))
             }
         } else {
-            Err(anyhow!("Request failed").into())
+            Err(anyhow!("Request failed"))
         }
     }
 

+ 3 - 3
apps/fortuna/src/chain/reader.rs

@@ -23,9 +23,9 @@ pub enum BlockStatus {
     Safe,
 }
 
-impl Into<EthersBlockNumber> for BlockStatus {
-    fn into(self) -> EthersBlockNumber {
-        match self {
+impl From<BlockStatus> for EthersBlockNumber {
+    fn from(val: BlockStatus) -> Self {
+        match val {
             BlockStatus::Latest => EthersBlockNumber::Latest,
             BlockStatus::Finalized => EthersBlockNumber::Finalized,
             BlockStatus::Safe => EthersBlockNumber::Safe,

+ 1 - 1
apps/fortuna/src/command/generate.rs

@@ -56,7 +56,7 @@ pub async fn generate(opts: &GenerateOptions) -> Result<()> {
             &provider,
             sequence_number,
             &user_randomness,
-            &provider_randomness,
+            provider_randomness,
         )
         .await?;
 

+ 4 - 4
apps/fortuna/src/command/register_provider.rs

@@ -56,7 +56,7 @@ pub async fn register_provider_from_config(
 
     // Initialize a Provider to interface with the EVM contract.
     let contract =
-        Arc::new(SignablePythContract::from_config(&chain_config, &private_key_string).await?);
+        Arc::new(SignablePythContract::from_config(chain_config, &private_key_string).await?);
     // Create a new random hash chain.
     let random = rand::random::<[u8; 32]>();
     let secret = provider_config
@@ -68,7 +68,7 @@ pub async fn register_provider_from_config(
     tracing::info!("Generating hash chain");
     let chain = PebbleHashChain::from_config(
         &secret,
-        &chain_id,
+        chain_id,
         &private_key_string.parse::<LocalWallet>()?.address(),
         &chain_config.contract_addr,
         &random,
@@ -86,7 +86,7 @@ pub async fn register_provider_from_config(
         seed:         random,
         chain_length: commitment_length,
     };
-    let uri = get_register_uri(&provider_config.uri, &chain_id)?;
+    let uri = get_register_uri(&provider_config.uri, chain_id)?;
     let call = contract.register(
         fee_in_wei,
         commitment,
@@ -98,7 +98,7 @@ pub async fn register_provider_from_config(
     );
     let mut gas_estimate = call.estimate_gas().await?;
     let gas_multiplier = U256::from(2); //TODO: smarter gas estimation
-    gas_estimate = gas_estimate * gas_multiplier;
+    gas_estimate *= gas_multiplier;
     let call_with_gas = call.gas(gas_estimate);
     if let Some(r) = call_with_gas.send().await?.await? {
         tracing::info!("Registered provider: {:?}", r);

+ 8 - 8
apps/fortuna/src/command/run.rs

@@ -237,7 +237,7 @@ pub async fn run(opts: &RunOptions) -> Result<()> {
         rpc_metrics.clone(),
     ));
 
-    run_api(opts.addr.clone(), chains, metrics_registry, rx_exit).await?;
+    run_api(opts.addr, chains, metrics_registry, rx_exit).await?;
 
     Ok(())
 }
@@ -251,11 +251,11 @@ async fn setup_chain_state(
     rpc_metrics: Arc<RpcMetrics>,
 ) -> Result<BlockchainState> {
     let contract = Arc::new(InstrumentedPythContract::from_config(
-        &chain_config,
+        chain_config,
         chain_id.clone(),
         rpc_metrics,
     )?);
-    let mut provider_commitments = chain_config.commitments.clone().unwrap_or(Vec::new());
+    let mut provider_commitments = chain_config.commitments.clone().unwrap_or_default();
     provider_commitments.sort_by(|c1, c2| {
         c1.original_commitment_sequence_number
             .cmp(&c2.original_commitment_sequence_number)
@@ -301,9 +301,9 @@ async fn setup_chain_state(
         offsets.push(offset);
 
         let pebble_hash_chain = PebbleHashChain::from_config(
-            &secret,
-            &chain_id,
-            &provider,
+            secret,
+            chain_id,
+            provider,
             &chain_config.contract_addr,
             &commitment.seed,
             commitment.chain_length,
@@ -321,7 +321,7 @@ async fn setup_chain_state(
     if chain_state.reveal(provider_info.original_commitment_sequence_number)?
         != provider_info.original_commitment
     {
-        return Err(anyhow!("The root of the generated hash chain for chain id {} does not match the commitment. Are the secret and chain length configured correctly?", &chain_id).into());
+        return Err(anyhow!("The root of the generated hash chain for chain id {} does not match the commitment. Are the secret and chain length configured correctly?", &chain_id));
     } else {
         tracing::info!("Root of chain id {} matches commitment", &chain_id);
     }
@@ -330,7 +330,7 @@ async fn setup_chain_state(
         id: chain_id.clone(),
         state: Arc::new(chain_state),
         contract,
-        provider_address: provider.clone(),
+        provider_address: *provider,
         reveal_delay_blocks: chain_config.reveal_delay_blocks,
         confirmed_block_status: chain_config.confirmed_block_status,
     };

+ 5 - 5
apps/fortuna/src/command/setup_provider.rs

@@ -99,7 +99,7 @@ async fn setup_chain_provider(
     ))?;
     let provider_address = private_key.clone().parse::<LocalWallet>()?.address();
     // Initialize a Provider to interface with the EVM contract.
-    let contract = Arc::new(SignablePythContract::from_config(&chain_config, &private_key).await?);
+    let contract = Arc::new(SignablePythContract::from_config(chain_config, &private_key).await?);
 
     tracing::info!("Fetching provider info");
     let provider_info = contract.get_provider_info(provider_address).call().await?;
@@ -140,7 +140,7 @@ async fn setup_chain_provider(
         } else {
             let hash_chain = PebbleHashChain::from_config(
                 &secret,
-                &chain_id,
+                chain_id,
                 &provider_address,
                 &chain_config.contract_addr,
                 &metadata.seed,
@@ -167,7 +167,7 @@ async fn setup_chain_provider(
     }
     if register {
         tracing::info!("Registering");
-        register_provider_from_config(&provider_config, &chain_id, &chain_config)
+        register_provider_from_config(provider_config, chain_id, chain_config)
             .await
             .map_err(|e| anyhow!("Chain: {} - Failed to register provider: {}", &chain_id, e))?;
         tracing::info!("Registered");
@@ -180,7 +180,7 @@ async fn setup_chain_provider(
         .in_current_span()
         .await?;
 
-    let uri = get_register_uri(&provider_config.uri, &chain_id)?;
+    let uri = get_register_uri(&provider_config.uri, chain_id)?;
     sync_uri(&contract, &provider_info, uri)
         .in_current_span()
         .await?;
@@ -210,7 +210,7 @@ async fn sync_uri(
     uri: String,
 ) -> Result<()> {
     let uri_as_bytes: Bytes = AbiBytes::from(uri.as_str()).into();
-    if &provider_info.uri != &uri_as_bytes {
+    if provider_info.uri != uri_as_bytes {
         tracing::info!("Updating provider uri to {}", uri);
         if let Some(receipt) = contract
             .set_provider_uri(uri_as_bytes)

+ 4 - 4
apps/fortuna/src/command/withdraw_fees.rs

@@ -32,11 +32,11 @@ pub async fn withdraw_fees(opts: &WithdrawFeesOptions) -> Result<()> {
         Some(chain_id) => {
             let chain_config = &config.get_chain_config(&chain_id)?;
             let contract =
-                SignablePythContract::from_config(&chain_config, &private_key_string).await?;
+                SignablePythContract::from_config(chain_config, &private_key_string).await?;
 
             withdraw_fees_for_chain(
                 contract,
-                config.provider.address.clone(),
+                config.provider.address,
                 opts.keeper,
                 opts.retain_balance_wei,
             )
@@ -46,11 +46,11 @@ pub async fn withdraw_fees(opts: &WithdrawFeesOptions) -> Result<()> {
             for (chain_id, chain_config) in config.chains.iter() {
                 tracing::info!("Withdrawing fees for chain: {}", chain_id);
                 let contract =
-                    SignablePythContract::from_config(&chain_config, &private_key_string).await?;
+                    SignablePythContract::from_config(chain_config, &private_key_string).await?;
 
                 withdraw_fees_for_chain(
                     contract,
-                    config.provider.address.clone(),
+                    config.provider.address,
                     opts.keeper,
                     opts.retain_balance_wei,
                 )

+ 8 - 12
apps/fortuna/src/config.rs

@@ -118,10 +118,10 @@ impl Config {
     }
 
     pub fn get_chain_config(&self, chain_id: &ChainId) -> Result<EthereumConfig> {
-        self.chains
-            .get(chain_id)
-            .map(|x| x.clone())
-            .ok_or(anyhow!("Could not find chain id {} in the configuration", &chain_id).into())
+        self.chains.get(chain_id).cloned().ok_or(anyhow!(
+            "Could not find chain id {} in the configuration",
+            &chain_id
+        ))
     }
 }
 
@@ -261,16 +261,12 @@ pub struct SecretString {
 
 impl SecretString {
     pub fn load(&self) -> Result<Option<String>> {
-        match &self.value {
-            Some(v) => return Ok(Some(v.clone())),
-            _ => {}
+        if let Some(v) = &self.value {
+            return Ok(Some(v.clone()));
         }
 
-        match &self.file {
-            Some(v) => {
-                return Ok(Some(fs::read_to_string(v)?.trim().to_string()));
-            }
-            _ => {}
+        if let Some(v) = &self.file {
+            return Ok(Some(fs::read_to_string(v)?.trim().to_string()));
         }
 
         Ok(None)

+ 7 - 9
apps/fortuna/src/keeper.rs

@@ -296,7 +296,7 @@ pub async fn run_keeper_threads(
     spawn(
         withdraw_fees_wrapper(
             contract.clone(),
-            chain_state.provider_address.clone(),
+            chain_state.provider_address,
             WITHDRAW_INTERVAL,
             U256::from(chain_eth_config.min_keeper_balance),
         )
@@ -307,7 +307,7 @@ pub async fn run_keeper_threads(
     spawn(
         adjust_fee_wrapper(
             contract.clone(),
-            chain_state.provider_address.clone(),
+            chain_state.provider_address,
             ADJUST_FEE_INTERVAL,
             chain_eth_config.legacy_tx,
             chain_eth_config.gas_limit,
@@ -327,7 +327,7 @@ pub async fn run_keeper_threads(
         async move {
             let chain_id = chain_state.id.clone();
             let chain_config = chain_eth_config.clone();
-            let provider_address = chain_state.provider_address.clone();
+            let provider_address = chain_state.provider_address;
             let keeper_metrics = metrics.clone();
             let contract = match InstrumentedPythContract::from_config(
                 &chain_config,
@@ -349,7 +349,7 @@ pub async fn run_keeper_threads(
                     track_provider(
                         chain_id.clone(),
                         contract.clone(),
-                        provider_address.clone(),
+                        provider_address,
                         keeper_metrics.clone(),
                     )
                     .in_current_span(),
@@ -358,7 +358,7 @@ pub async fn run_keeper_threads(
                     track_balance(
                         chain_id.clone(),
                         contract.client(),
-                        keeper_address.clone(),
+                        keeper_address,
                         keeper_metrics.clone(),
                     )
                     .in_current_span(),
@@ -738,9 +738,7 @@ pub async fn watch_blocks(
 
         let latest_safe_block = get_latest_safe_block(&chain_state).in_current_span().await;
         if latest_safe_block > *last_safe_block_processed {
-            let mut from = latest_safe_block
-                .checked_sub(RETRY_PREVIOUS_BLOCKS)
-                .unwrap_or(0);
+            let mut from = latest_safe_block.saturating_sub(RETRY_PREVIOUS_BLOCKS);
 
             // In normal situation, the difference between latest and last safe block should not be more than 2-3 (for arbitrum it can be 10)
             // TODO: add a metric for this in separate PR. We need alerts
@@ -1068,7 +1066,7 @@ pub async fn update_commitments_if_necessary(
     chain_state: &BlockchainState,
 ) -> Result<()> {
     //TODO: we can reuse the result from the last call from the watch_blocks thread to reduce RPCs
-    let latest_safe_block = get_latest_safe_block(&chain_state).in_current_span().await;
+    let latest_safe_block = get_latest_safe_block(chain_state).in_current_span().await;
     let provider_address = chain_state.provider_address;
     let provider_info = contract
         .get_provider_info(provider_address)

+ 0 - 1
apps/fortuna/src/main.rs

@@ -1,5 +1,4 @@
 #![allow(clippy::just_underscores_and_digits)]
-#![feature(slice_flatten)]
 
 use {
     anyhow::Result,

+ 8 - 8
apps/fortuna/src/state.rs

@@ -31,9 +31,9 @@ impl PebbleHashChain {
         let mut hash = Vec::<[u8; 32]>::with_capacity(length);
         let mut current: [u8; 32] = Keccak256::digest(secret).into();
 
-        hash.push(current.clone());
+        hash.push(current);
         for i in 1..length {
-            current = Keccak256::digest(&current).into();
+            current = Keccak256::digest(current).into();
             if i % sample_interval == 0 {
                 hash.push(current);
             }
@@ -60,9 +60,9 @@ impl PebbleHashChain {
     ) -> Result<Self> {
         let mut input: Vec<u8> = vec![];
         input.extend_from_slice(&hex::decode(secret.trim())?);
-        input.extend_from_slice(&chain_id.as_bytes());
-        input.extend_from_slice(&provider_address.as_bytes());
-        input.extend_from_slice(&contract_address.as_bytes());
+        input.extend_from_slice(chain_id.as_bytes());
+        input.extend_from_slice(provider_address.as_bytes());
+        input.extend_from_slice(contract_address.as_bytes());
         input.extend_from_slice(random);
 
         let secret: [u8; 32] = Keccak256::digest(input).into();
@@ -80,7 +80,7 @@ impl PebbleHashChain {
         // actually at the *front* of the list. Thus, it's easier to compute indexes from the end of the list.
         let index_from_end_of_subsampled_list = ((self.len() - 1) - i) / self.sample_interval;
         let mut i_index = self.len() - 1 - index_from_end_of_subsampled_list * self.sample_interval;
-        let mut val = self.hash[self.hash.len() - 1 - index_from_end_of_subsampled_list].clone();
+        let mut val = self.hash[self.hash.len() - 1 - index_from_end_of_subsampled_list];
 
         while i_index > i {
             val = Keccak256::digest(val).into();
@@ -139,9 +139,9 @@ mod test {
         // Calculate the hash chain the naive way as a comparison point to the subsampled implementation.
         let mut basic_chain = Vec::<[u8; 32]>::with_capacity(length);
         let mut current: [u8; 32] = Keccak256::digest(secret).into();
-        basic_chain.push(current.clone());
+        basic_chain.push(current);
         for _ in 1..length {
-            current = Keccak256::digest(&current).into();
+            current = Keccak256::digest(current).into();
             basic_chain.push(current);
         }
 

+ 4 - 4
apps/hermes/server/Cargo.lock

@@ -5243,9 +5243,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.34"
+version = "0.3.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
 dependencies = [
  "deranged",
  "itoa",
@@ -5264,9 +5264,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
 
 [[package]]
 name = "time-macros"
-version = "0.2.17"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
 dependencies = [
  "num-conv",
  "time-core",

+ 2 - 8
apps/hermes/server/Dockerfile

@@ -1,15 +1,9 @@
-# The rust version itself is not so important as we install a fixed
-# nightly version. We use the latest stable version to get the latest
-# updates and dependencies.
-FROM rust:1.77.0 AS build
+FROM rust:1.82.0 AS build
 
 # Install OS packages
 RUN apt-get update && apt-get install --yes \
     build-essential curl clang libssl-dev protobuf-compiler
 
-# Set default toolchain
-RUN rustup default nightly-2024-03-26
-
 # Build
 WORKDIR /src
 COPY apps/hermes/server apps/hermes/server
@@ -20,7 +14,7 @@ WORKDIR /src/apps/hermes/server
 
 RUN --mount=type=cache,target=/root/.cargo/registry cargo build --release
 
-FROM rust:1.77.0
+FROM rust:1.82.0
 
 # Copy artifacts from other images
 COPY --from=build /src/apps/hermes/server/target/release/hermes /usr/local/bin/

+ 3 - 3
apps/hermes/server/README.md

@@ -19,11 +19,11 @@ To set up and run a Hermes node, follow the steps below:
    [here](https://docs.pyth.network/documentation/pythnet-price-feeds/hermes#hermes-node-providers) and instructions
    for running a Wormhole spy RPC instance [here](https://docs.wormhole.com/wormhole/explore-wormhole/spy). We recommend
    using [Beacon](https://github.com/pyth-network/beacon), a highly available rewrite for spy, for production purposes.
-1. **Install Rust nightly-2023-07-23**: If you haven't already, you'll need to install Rust. You can
+1. **Install Rust 1.82.0**: If you haven't already, you'll need to install Rust. You can
    do so by following the official instructions. Then, run the following command to install the required
-   nightly version of Rust:
+   version of Rust:
    ```bash
-    rustup toolchain install nightly-2023-07-23
+    rustup toolchain install 1.82.0
    ```
 2. **Install Go**: If you haven't already, you'll also need to install Go. You can
    do so by following the official instructions. If you are on a Mac with M series

+ 1 - 1
apps/hermes/server/rust-toolchain

@@ -1,2 +1,2 @@
 [toolchain]
-channel = "nightly-2024-03-26"
+channel = "1.82.0"

+ 0 - 3
apps/hermes/server/src/main.rs

@@ -1,6 +1,3 @@
-#![feature(never_type)]
-#![feature(btree_cursors)]
-
 use {
     anyhow::Result,
     clap::{

+ 1 - 1
apps/hermes/server/src/network/pythnet.rs

@@ -141,7 +141,7 @@ async fn fetch_bridge_data(
     }
 }
 
-pub async fn run<S>(store: Arc<S>, pythnet_ws_endpoint: String) -> Result<!>
+pub async fn run<S>(store: Arc<S>, pythnet_ws_endpoint: String) -> Result<()>
 where
     S: Aggregates,
     S: Wormhole,

+ 1 - 1
apps/hermes/server/src/network/wormhole.rs

@@ -140,7 +140,7 @@ where
 }
 
 #[tracing::instrument(skip(opts, state))]
-async fn run<S>(opts: RunOptions, state: Arc<S>) -> Result<!>
+async fn run<S>(opts: RunOptions, state: Arc<S>) -> Result<()>
 where
     S: Wormhole,
     S: Send + Sync + 'static,

+ 2 - 3
apps/hermes/server/src/state/cache.rs

@@ -25,7 +25,6 @@ use {
             HashMap,
             HashSet,
         },
-        ops::Bound,
         sync::Arc,
     },
     strum::IntoEnumIterator,
@@ -300,8 +299,8 @@ async fn retrieve_message_state(
 
                     // Get the first element that is greater than or equal to the lookup time.
                     key_cache
-                        .lower_bound(Bound::Included(&lookup_time))
-                        .peek_next()
+                        .range(lookup_time..)
+                        .next()
                         .map(|(_, v)| v)
                         .cloned()
                 }

+ 0 - 2
pythnet/pythnet_sdk/examples/generate_pyth_data.rs

@@ -1,8 +1,6 @@
 // Use the Solana client library to pull the addresses of all relevant accounts from PythNet so we
 // can test locally.
 
-// #![feature(proc_macro_hygiene)]
-
 use {
     pythnet_sdk::pythnet::PYTH_PID,
     serde_json::json,

+ 1 - 0
pythnet/pythnet_sdk/rust-toolchain

@@ -0,0 +1 @@
+1.82.0

+ 7 - 4
pythnet/pythnet_sdk/src/wire.rs

@@ -84,10 +84,13 @@ pub mod v1 {
                 Error::InvalidMagic
             );
             require!(message.major_version == 1, Error::InvalidVersion);
-            require!(
-                message.minor_version >= CURRENT_MINOR_VERSION,
-                Error::InvalidVersion
-            );
+            #[allow(clippy::absurd_extreme_comparisons)]
+            {
+                require!(
+                    message.minor_version >= CURRENT_MINOR_VERSION,
+                    Error::InvalidVersion
+                );
+            }
             Ok(message)
         }
     }

+ 10 - 10
target_chains/cosmwasm/contracts/pyth/src/contract.rs

@@ -261,7 +261,7 @@ fn update_price_feeds(
     data: &[Binary],
 ) -> StdResult<Response<MsgWrapper>> {
     if !is_fee_sufficient(&deps.as_ref(), info, data)? {
-        return Err(PythContractError::InsufficientFee)?;
+        Err(PythContractError::InsufficientFee)?;
     }
 
     let (num_total_attestations, total_new_feeds) = apply_updates(&mut deps, &env, data)?;
@@ -308,7 +308,7 @@ fn execute_governance_instruction(
     // Governance messages must be applied in order. This check prevents replay attacks where
     // previous messages are re-applied.
     if vaa.sequence <= state.governance_sequence_number {
-        return Err(PythContractError::OldGovernanceMessage)?;
+        Err(PythContractError::OldGovernanceMessage)?;
     } else {
         updated_config.governance_sequence_number = vaa.sequence;
     }
@@ -320,13 +320,13 @@ fn execute_governance_instruction(
     // Check that the instruction is intended for this chain.
     // chain_id = 0 means the instruction applies to all chains
     if instruction.target_chain_id != state.chain_id && instruction.target_chain_id != 0 {
-        return Err(PythContractError::InvalidGovernancePayload)?;
+        Err(PythContractError::InvalidGovernancePayload)?;
     }
 
     // Check that the instruction is intended for this target chain contract (as opposed to
     // other Pyth contracts that may live on the same chain).
     if instruction.module != GovernanceModule::Target {
-        return Err(PythContractError::InvalidGovernancePayload)?;
+        Err(PythContractError::InvalidGovernancePayload)?;
     }
 
     let response = match instruction.action {
@@ -463,7 +463,7 @@ fn verify_vaa_from_data_source(state: &ConfigInfo, vaa: &ParsedVAA) -> StdResult
         chain_id: vaa.emitter_chain,
     };
     if !state.data_sources.contains(&vaa_data_source) {
-        return Err(PythContractError::InvalidUpdateEmitter)?;
+        Err(PythContractError::InvalidUpdateEmitter)?;
     }
     Ok(())
 }
@@ -475,7 +475,7 @@ fn verify_vaa_from_governance_source(state: &ConfigInfo, vaa: &ParsedVAA) -> Std
         chain_id: vaa.emitter_chain,
     };
     if state.governance_source != vaa_data_source {
-        return Err(PythContractError::InvalidUpdateEmitter)?;
+        Err(PythContractError::InvalidUpdateEmitter)?;
     }
     Ok(())
 }
@@ -533,7 +533,7 @@ fn parse_accumulator(deps: &Deps, env: &Env, data: &[u8]) -> StdResult<Vec<Price
             for update in updates {
                 let message_vec = Vec::from(update.message);
                 if !root.check(update.proof, &message_vec) {
-                    return Err(PythContractError::InvalidMerkleProof)?;
+                    Err(PythContractError::InvalidMerkleProof)?;
                 }
 
                 let msg = from_slice::<BigEndian, Message>(&message_vec)
@@ -683,7 +683,7 @@ pub fn parse_price_feed_updates(
 ) -> StdResult<Response<MsgWrapper>> {
     let _config = config_read(deps.storage).load()?;
     if !is_fee_sufficient(&deps.as_ref(), info, updates)? {
-        return Err(PythContractError::InsufficientFee)?;
+        Err(PythContractError::InsufficientFee)?;
     }
     let mut found_feeds = 0;
     let mut results: Vec<(Identifier, Option<PriceFeed>)> =
@@ -709,7 +709,7 @@ pub fn parse_price_feed_updates(
         }
     }
     if found_feeds != price_feeds.len() {
-        return Err(PythContractError::InvalidUpdatePayload)?;
+        Err(PythContractError::InvalidUpdatePayload)?;
     }
 
     let _unwrapped_feeds = results
@@ -1894,7 +1894,7 @@ mod test {
             })
             .unwrap();
 
-        let updates = vec![Binary::from([1u8]), Binary::from([2u8])];
+        let updates = [Binary::from([1u8]), Binary::from([2u8])];
 
         assert_eq!(
             get_update_fee(&deps.as_ref(), &updates[0..0]),