From 66b7258874d6d0797eb83af25e49960359e5bfde Mon Sep 17 00:00:00 2001 From: albert Date: Fri, 17 Jan 2025 17:11:51 +0100 Subject: [PATCH] chore: refactor critical nonce into get_number_of_available_sol_nonce_accounts --- state-chain/chains/src/sol.rs | 8 ++++--- .../solana_vault_swap_accounts.rs | 9 +++----- state-chain/pallets/cf-environment/src/lib.rs | 13 +++++++++--- state-chain/runtime/src/chainflip.rs | 21 +++++++------------ .../runtime/src/chainflip/solana_elections.rs | 4 ++-- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/state-chain/chains/src/sol.rs b/state-chain/chains/src/sol.rs index ab7e0795a6..d3a388cf37 100644 --- a/state-chain/chains/src/sol.rs +++ b/state-chain/chains/src/sol.rs @@ -53,12 +53,14 @@ pub const CCM_BYTES_PER_ACCOUNT: usize = 33usize; pub const MAX_CCM_BYTES_SOL: usize = MAX_TRANSACTION_LENGTH - 527usize; // 705 bytes left pub const MAX_CCM_BYTES_USDC: usize = MAX_TRANSACTION_LENGTH - 740usize; // 492 bytes left +// Nonce management values +pub const NONCE_NUMBER_CRITICAL_NONCES: usize = 1; +pub const NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_TRANSFER: usize = 1; + // Values used when closing vault swap accounts. pub const MAX_BATCH_SIZE_OF_VAULT_SWAP_ACCOUNT_CLOSURES: usize = 5; pub const MAX_WAIT_BLOCKS_FOR_SWAP_ACCOUNT_CLOSURE_APICALLS: u32 = 14400; -pub const NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_SWAP_ACCOUNT_CLOSURES: usize = 4; -// Leaving always one nonce for a potential rotation. -pub const NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH: usize = 1; +pub const NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_SWAP_ACCOUNT_CLOSURES: usize = 3; // Use serialized transaction #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug, Default, PartialEq, Eq)] diff --git a/state-chain/pallets/cf-elections/src/electoral_systems/solana_vault_swap_accounts.rs b/state-chain/pallets/cf-elections/src/electoral_systems/solana_vault_swap_accounts.rs index c782a22532..f849fe8ff6 100644 --- a/state-chain/pallets/cf-elections/src/electoral_systems/solana_vault_swap_accounts.rs +++ b/state-chain/pallets/cf-elections/src/electoral_systems/solana_vault_swap_accounts.rs @@ -21,7 +21,6 @@ use crate::{ use cf_chains::sol::{ MAX_BATCH_SIZE_OF_VAULT_SWAP_ACCOUNT_CLOSURES, MAX_WAIT_BLOCKS_FOR_SWAP_ACCOUNT_CLOSURE_APICALLS, - NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH, NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_SWAP_ACCOUNT_CLOSURES, }; @@ -37,7 +36,7 @@ use sp_std::vec::Vec; pub trait SolanaVaultSwapAccountsHook { fn maybe_fetch_and_close_accounts(accounts: Vec) -> Result<(), E>; fn initiate_vault_swap(swap_details: SwapDetails); - fn get_number_of_available_sol_nonce_accounts() -> usize; + fn get_number_of_available_sol_nonce_accounts(critical: bool) -> usize; } pub trait FromSolOrNot { @@ -192,13 +191,11 @@ impl< ElectoralAccess::new_election(Default::default(), known_accounts, ())?; } - let no_of_available_nonces = Hook::get_number_of_available_sol_nonce_accounts(); + let no_of_available_nonces = Hook::get_number_of_available_sol_nonce_accounts(false); let mut known_accounts = election_access.properties()?; // We need to have at least two nonces available since we need to have one nonce // reserved for solana rotation - if no_of_available_nonces > NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH && - !known_accounts.witnessed_open_accounts.is_empty() - { + if no_of_available_nonces > 0 && !known_accounts.witnessed_open_accounts.is_empty() { known_accounts.witnessed_open_accounts.sort_by_key(|a| Reverse(a.1)); // Native Vault swaps assets need to be fetched from the Swap Endpoint's Vault. // Therefore initiating a fetch is a high priority action after a native Vault diff --git a/state-chain/pallets/cf-environment/src/lib.rs b/state-chain/pallets/cf-environment/src/lib.rs index 6fd92c09e7..2158bcdfe1 100644 --- a/state-chain/pallets/cf-environment/src/lib.rs +++ b/state-chain/pallets/cf-environment/src/lib.rs @@ -14,7 +14,7 @@ use cf_chains::{ eth::Address as EvmAddress, sol::{ api::{DurableNonceAndAccount, SolanaApi, SolanaEnvironment, SolanaGovCall}, - SolAddress, SolApiEnvironment, SolHash, Solana, + SolAddress, SolApiEnvironment, SolHash, Solana, NONCE_NUMBER_CRITICAL_NONCES, }, Chain, }; @@ -779,8 +779,15 @@ impl Pallet { nonce_accounts } - pub fn get_number_of_available_sol_nonce_accounts() -> usize { - SolanaAvailableNonceAccounts::::decode_len().unwrap_or(0) + // Get the number of available nonce accounts. We want to leave a number of available nonces + // at all time for critical operations such as vault rotations or governance actions. + pub fn get_number_of_available_sol_nonce_accounts(critical: bool) -> usize { + let number_nonces = SolanaAvailableNonceAccounts::::decode_len().unwrap_or(0); + if !critical { + number_nonces.saturating_sub(NONCE_NUMBER_CRITICAL_NONCES) + } else { + number_nonces + } } pub fn update_sol_nonce(nonce_account: SolAddress, durable_nonce: SolHash) { diff --git a/state-chain/runtime/src/chainflip.rs b/state-chain/runtime/src/chainflip.rs index 4575c9ed36..dbc4a59364 100644 --- a/state-chain/runtime/src/chainflip.rs +++ b/state-chain/runtime/src/chainflip.rs @@ -55,7 +55,7 @@ use cf_chains::{ SolanaEnvironment, }, SolAddress, SolAmount, SolApiEnvironment, SolanaCrypto, SolanaTransactionData, - NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH, + NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_TRANSFER, }, AnyChain, ApiCall, Arbitrum, CcmChannelMetadata, CcmDepositMetadata, Chain, ChainCrypto, ChainEnvironment, ChainState, ChannelRefundParametersDecoded, ForeignChain, @@ -946,9 +946,8 @@ impl FetchesTransfersLimitProvider for SolanaLimit { // we need to leave one nonce for the fetch tx and one nonce reserved for rotation tx since // rotation tx can fail to build if all nonce accounts are occupied Some( - Environment::get_number_of_available_sol_nonce_accounts().saturating_sub( - NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH.saturating_add(1), - ), + Environment::get_number_of_available_sol_nonce_accounts(false) + .saturating_sub(NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_TRANSFER), ) } @@ -961,15 +960,11 @@ impl FetchesTransfersLimitProvider for SolanaLimit { fn maybe_fetches_limit() -> Option { // only fetch if we have more than once nonce account available since one nonce is // reserved for rotations. See above - Some( - if Environment::get_number_of_available_sol_nonce_accounts() > - NONCE_AVAILABILITY_THRESHOLD_FOR_INITIATING_FETCH - { - cf_chains::sol::MAX_SOL_FETCHES_PER_TX - } else { - 0 - }, - ) + Some(if Environment::get_number_of_available_sol_nonce_accounts(false) > 0 { + cf_chains::sol::MAX_SOL_FETCHES_PER_TX + } else { + 0 + }) } } diff --git a/state-chain/runtime/src/chainflip/solana_elections.rs b/state-chain/runtime/src/chainflip/solana_elections.rs index 627a9bf280..10d5eee697 100644 --- a/state-chain/runtime/src/chainflip/solana_elections.rs +++ b/state-chain/runtime/src/chainflip/solana_elections.rs @@ -610,8 +610,8 @@ impl }) } - fn get_number_of_available_sol_nonce_accounts() -> usize { - Environment::get_number_of_available_sol_nonce_accounts() + fn get_number_of_available_sol_nonce_accounts(critical: bool) -> usize { + Environment::get_number_of_available_sol_nonce_accounts(critical) } }