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

Improved error display #4209

Merged
merged 4 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl<'a, 'env, BaseRpcClient: base_rpc_api::BaseRpcApi + Send + Sync + 'static>
let result_bytes = self.base_rpc_client.dry_run(Encode::encode(&uxt).into(), None).await?;
let dry_run_result: ApplyExtrinsicResult = Decode::decode(&mut &*result_bytes)?;

debug!(target: "state_chain_client", "Dry run completed. Result: {:?}", &dry_run_result);
debug!(target: "state_chain_client", "Dry run completed. \nCall:{:?} \nResult: {:?}", call, &dry_run_result);

Ok(dry_run_result?.map_err(|e| self.error_decoder.decode_dispatch_error(e))?)
}
Expand Down
12 changes: 9 additions & 3 deletions state-chain/chains/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@ extern crate alloc;
use crate::{btc::ScriptPubkey, dot::PolkadotAccountId, eth::Address as EthereumAddress, Chain};
use cf_primitives::{ChannelId, ForeignChain, NetworkEnvironment};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::sp_runtime::DispatchError;
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use sp_core::H160;
use sp_std::{fmt::Debug, vec::Vec};

#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AddressDerivationError {
MissingPolkadotVault,
MissingBitcoinVault,
BitcoinChannelIdTooLarge,
}

/// Generates a deterministic deposit address for some combination of asset, chain and channel id.
pub trait AddressDerivationApi<C: Chain> {
// TODO: should also take root pubkey (vault) as an argument?
fn generate_address(
source_asset: C::ChainAsset,
channel_id: ChannelId,
) -> Result<C::ChainAccount, DispatchError>;
) -> Result<C::ChainAccount, AddressDerivationError>;

fn generate_address_and_state(
source_asset: C::ChainAsset,
channel_id: ChannelId,
) -> Result<(C::ChainAccount, C::DepositChannelState), DispatchError>;
) -> Result<(C::ChainAccount, C::DepositChannelState), AddressDerivationError>;
}

#[derive(
Expand Down
2 changes: 1 addition & 1 deletion state-chain/chains/src/deposit_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<C: Chain> DepositChannel<C> {
pub fn generate_new<A: AddressDerivationApi<C>>(
channel_id: ChannelId,
asset: C::ChainAsset,
) -> Result<Self, DispatchError> {
) -> Result<Self, AddressDerivationError> {
let (address, state) = A::generate_address_and_state(asset, channel_id)?;
Ok(Self { channel_id, address, asset, state })
}
Expand Down
2 changes: 1 addition & 1 deletion state-chain/chains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::{fmt::Display, iter::Step};

use crate::benchmarking_value::{BenchmarkValue, BenchmarkValueExtended};
pub use address::ForeignChainAddress;
use address::{AddressDerivationApi, ToHumanreadableAddress};
use address::{AddressDerivationApi, AddressDerivationError, ToHumanreadableAddress};
use cf_primitives::{AssetAmount, ChannelId, EgressId, EthAmount, TransactionHash};
use codec::{Decode, Encode, FullCodec, MaxEncodedLen};
use frame_support::{
Expand Down
2 changes: 1 addition & 1 deletion state-chain/pallets/cf-account-roles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ pub mod pallet {

#[pallet::error]
pub enum Error<T> {
/// The account has never been created.
UnknownAccount,
AccountNotInitialised,
/// The account already has a registered role.
AccountRoleAlreadyRegistered,
/// Initially when swapping features are deployed to the chain, they will be disabled.
Expand Down
21 changes: 16 additions & 5 deletions state-chain/pallets/cf-ingress-egress/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use frame_support::{sp_runtime::SaturatedConversion, traits::OnRuntimeUpgrade, t
pub use weights::WeightInfo;

use cf_chains::{
address::{AddressConverter, AddressDerivationApi},
address::{AddressConverter, AddressDerivationApi, AddressDerivationError},
AllBatch, AllBatchError, CcmCfParameters, CcmChannelMetadata, CcmDepositMetadata, CcmMessage,
Chain, ChannelLifecycleHooks, DepositChannel, ExecutexSwapAndCall, FetchAssetParams,
ForeignChainAddress, SwapOrigin, TransferAssetParams,
Expand Down Expand Up @@ -409,6 +409,12 @@ pub mod pallet {
AssetMismatch,
/// Channel ID has reached maximum
ChannelIdsExhausted,
/// Polkadot's Vault Account does not exist in storage.
MissingPolkadotVault,
/// Bitcoin's Vault key does not exist for the current epoch.
MissingBitcoinVault,
/// Channel ID is too large for Bitcoin address derivation
BitcoinChannelIdTooLarge,
}

#[pallet::hooks]
Expand Down Expand Up @@ -926,10 +932,15 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Ok(*id)
})?;
(
DepositChannel::generate_new::<T::AddressDerivation>(
next_channel_id,
source_asset,
)?,
DepositChannel::generate_new::<T::AddressDerivation>(next_channel_id, source_asset)
.map_err(|e| match e {
AddressDerivationError::MissingPolkadotVault =>
Error::<T, I>::MissingPolkadotVault,
AddressDerivationError::MissingBitcoinVault =>
Error::<T, I>::MissingBitcoinVault,
AddressDerivationError::BitcoinChannelIdTooLarge =>
Error::<T, I>::BitcoinChannelIdTooLarge,
})?,
next_channel_id,
)
};
Expand Down
6 changes: 3 additions & 3 deletions state-chain/pallets/cf-ingress-egress/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub use crate::{self as pallet_cf_ingress_egress};
use crate::{DepositBalances, DepositWitness};

pub use cf_chains::{
address::{AddressDerivationApi, ForeignChainAddress},
address::{AddressDerivationApi, AddressDerivationError, ForeignChainAddress},
eth::{api::EthereumApi, Address as EthereumAddress},
CcmDepositMetadata, Chain, ChainEnvironment, DepositChannel,
};
Expand Down Expand Up @@ -81,7 +81,7 @@ impl AddressDerivationApi<Ethereum> for MockAddressDerivation {
fn generate_address(
_source_asset: assets::eth::Asset,
channel_id: ChannelId,
) -> Result<<Ethereum as Chain>::ChainAccount, sp_runtime::DispatchError> {
) -> Result<<Ethereum as Chain>::ChainAccount, AddressDerivationError> {
Ok([channel_id as u8; 20].into())
}

Expand All @@ -90,7 +90,7 @@ impl AddressDerivationApi<Ethereum> for MockAddressDerivation {
channel_id: ChannelId,
) -> Result<
(<Ethereum as Chain>::ChainAccount, <Ethereum as Chain>::DepositChannelState),
sp_runtime::DispatchError,
AddressDerivationError,
> {
Ok((Self::generate_address(source_asset, channel_id)?, Default::default()))
}
Expand Down
24 changes: 10 additions & 14 deletions state-chain/pallets/cf-lp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,22 @@ pub mod pallet {

#[pallet::error]
pub enum Error<T> {
// The user does not have enough fund.
/// The user does not have enough fund.
InsufficientBalance,
// The user has reached the maximum balance.
/// The user has reached the maximum balance.
BalanceOverflow,
// The caller is not authorized to modify the trading position.
/// The caller is not authorized to modify the trading position.
UnauthorisedToModify,
// The Asset cannot be egressed to the destination chain.
/// The Asset cannot be egressed because the destination address is not invalid.
InvalidEgressAddress,
// Then given encoded address cannot be decoded into a valid ForeignChainAddress.
/// Then given encoded address cannot be decoded into a valid ForeignChainAddress.
InvalidEncodedAddress,
// An liquidity refund address must be set by the user for the chain before
// deposit address can be requested.
/// An liquidity refund address must be set by the user for the chain before
/// deposit address can be requested.
NoLiquidityRefundAddressRegistered,
// Liquidity deposit is disabled due to Safe Mode.
/// Liquidity deposit is disabled due to Safe Mode.
LiquidityDepositDisabled,
// Withdrawals are disabled due to Safe Mode.
/// Withdrawals are disabled due to Safe Mode.
WithdrawalsDisabled,
}

Expand Down Expand Up @@ -208,11 +208,7 @@ pub mod pallet {

let destination_address_internal =
T::AddressConverter::try_from_encoded_address(destination_address.clone())
.map_err(|_| {
DispatchError::Other(
"Invalid Egress Address, cannot decode the address",
)
})?;
.map_err(|_| Error::<T>::InvalidEgressAddress)?;

// Check validity of Chain and Asset
ensure!(
Expand Down
9 changes: 6 additions & 3 deletions state-chain/pallets/cf-lp/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate as pallet_cf_lp;
use crate::PalletSafeMode;
use cf_chains::{address::AddressDerivationApi, AnyChain, Chain, Ethereum};
use cf_chains::{
address::{AddressDerivationApi, AddressDerivationError},
AnyChain, Chain, Ethereum,
};
use cf_primitives::{chains::assets, AccountId, ChannelId};
use cf_traits::{
impl_mock_chainflip, impl_mock_runtime_safe_mode,
Expand All @@ -26,7 +29,7 @@ impl AddressDerivationApi<Ethereum> for MockAddressDerivation {
fn generate_address(
_source_asset: assets::eth::Asset,
_channel_id: ChannelId,
) -> Result<<Ethereum as Chain>::ChainAccount, sp_runtime::DispatchError> {
) -> Result<<Ethereum as Chain>::ChainAccount, AddressDerivationError> {
Ok(H160::from_str("F29aB9EbDb481BE48b80699758e6e9a3DBD609C6").unwrap())
}

Expand All @@ -35,7 +38,7 @@ impl AddressDerivationApi<Ethereum> for MockAddressDerivation {
channel_id: ChannelId,
) -> Result<
(<Ethereum as Chain>::ChainAccount, <Ethereum as Chain>::DepositChannelState),
sp_runtime::DispatchError,
AddressDerivationError,
> {
Ok((Self::generate_address(source_asset, channel_id)?, Default::default()))
}
Expand Down
2 changes: 1 addition & 1 deletion state-chain/pallets/cf-swapping/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ pub mod pallet {
pub enum Error<T> {
/// The provided asset and withdrawal address are incompatible.
IncompatibleAssetAndAddress,
/// The Asset cannot be egressed to the destination chain.
/// The Asset cannot be egressed because the destination address is not invalid.
InvalidEgressAddress,
/// The withdrawal is not possible because not enough funds are available.
NoFundsAvailable,
Expand Down
13 changes: 7 additions & 6 deletions state-chain/runtime/src/chainflip/address_derivation/btc.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use super::AddressDerivation;
use crate::BitcoinVault;
use cf_chains::{
address::AddressDerivationApi, btc::deposit_address::DepositAddress, Bitcoin, Chain,
address::{AddressDerivationApi, AddressDerivationError},
btc::deposit_address::DepositAddress,
Bitcoin, Chain,
};
use cf_primitives::ChannelId;
use cf_traits::KeyProvider;
use frame_support::sp_runtime::DispatchError;

impl AddressDerivationApi<Bitcoin> for AddressDerivation {
fn generate_address(
source_asset: <Bitcoin as Chain>::ChainAsset,
channel_id: ChannelId,
) -> Result<<Bitcoin as Chain>::ChainAccount, DispatchError> {
) -> Result<<Bitcoin as Chain>::ChainAccount, AddressDerivationError> {
<Self as AddressDerivationApi<Bitcoin>>::generate_address_and_state(
source_asset,
channel_id,
Expand All @@ -24,16 +25,16 @@ impl AddressDerivationApi<Bitcoin> for AddressDerivation {
channel_id: ChannelId,
) -> Result<
(<Bitcoin as Chain>::ChainAccount, <Bitcoin as Chain>::DepositChannelState),
DispatchError,
AddressDerivationError,
> {
let channel_id: u32 = channel_id
.try_into()
.map_err(|_| "Intent ID is too large for BTC address derivation")?;
.map_err(|_| AddressDerivationError::BitcoinChannelIdTooLarge)?;

let channel_state = DepositAddress::new(
// TODO: The key should be passed as an argument (or maybe KeyProvider type arg).
BitcoinVault::active_epoch_key()
.ok_or(DispatchError::Other("No vault for epoch"))?
.ok_or(AddressDerivationError::MissingBitcoinVault)?
.key
.current,
channel_id,
Expand Down
17 changes: 9 additions & 8 deletions state-chain/runtime/src/chainflip/address_derivation/dot.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::Vec;
use cf_chains::{address::AddressDerivationApi, dot::PolkadotAccountId, Chain, Polkadot};
use cf_chains::{
address::{AddressDerivationApi, AddressDerivationError},
dot::PolkadotAccountId,
Chain, Polkadot,
};
use cf_primitives::ChannelId;
use cf_utilities::SliceToArray;
use frame_support::sp_runtime::{
traits::{BlakeTwo256, Hash},
DispatchError,
};
use frame_support::sp_runtime::traits::{BlakeTwo256, Hash};
use sp_std::mem::size_of;

use crate::Environment;
Expand All @@ -16,13 +17,13 @@ impl AddressDerivationApi<Polkadot> for AddressDerivation {
fn generate_address(
_source_asset: <Polkadot as Chain>::ChainAsset,
channel_id: ChannelId,
) -> Result<<Polkadot as Chain>::ChainAccount, DispatchError> {
) -> Result<<Polkadot as Chain>::ChainAccount, AddressDerivationError> {
const PREFIX: &[u8; 16] = b"modlpy/utilisuba";
const RAW_PUBLIC_KEY_SIZE: usize = 32;
const PAYLOAD_LENGTH: usize = PREFIX.len() + RAW_PUBLIC_KEY_SIZE + size_of::<u16>();

let master_account = Environment::polkadot_vault_account()
.ok_or(DispatchError::Other("Vault Account does not exist."))?;
.ok_or(AddressDerivationError::MissingPolkadotVault)?;

let mut layers = channel_id
.to_be_bytes()
Expand Down Expand Up @@ -55,7 +56,7 @@ impl AddressDerivationApi<Polkadot> for AddressDerivation {
channel_id: ChannelId,
) -> Result<
(<Polkadot as Chain>::ChainAccount, <Polkadot as Chain>::DepositChannelState),
DispatchError,
AddressDerivationError,
> {
Ok((
<Self as AddressDerivationApi<Polkadot>>::generate_address(source_asset, channel_id)?,
Expand Down
11 changes: 6 additions & 5 deletions state-chain/runtime/src/chainflip/address_derivation/eth.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use super::AddressDerivation;
use crate::{Environment, EthEnvironment};
use cf_chains::{
address::AddressDerivationApi, eth::deposit_address::get_create_2_address,
evm::api::EthEnvironmentProvider, Chain, Ethereum,
address::{AddressDerivationApi, AddressDerivationError},
eth::deposit_address::get_create_2_address,
evm::api::EthEnvironmentProvider,
Chain, Ethereum,
};
use cf_primitives::{chains::assets::eth, ChannelId};
use frame_support::sp_runtime::DispatchError;

impl AddressDerivationApi<Ethereum> for AddressDerivation {
fn generate_address(
source_asset: eth::Asset,
channel_id: ChannelId,
) -> Result<<Ethereum as Chain>::ChainAccount, DispatchError> {
) -> Result<<Ethereum as Chain>::ChainAccount, AddressDerivationError> {
Ok(get_create_2_address(
Environment::eth_vault_address(),
EthEnvironment::token_address(source_asset),
Expand All @@ -24,7 +25,7 @@ impl AddressDerivationApi<Ethereum> for AddressDerivation {
channel_id: ChannelId,
) -> Result<
(<Ethereum as Chain>::ChainAccount, <Ethereum as Chain>::DepositChannelState),
DispatchError,
AddressDerivationError,
> {
Ok((
<Self as AddressDerivationApi<Ethereum>>::generate_address(source_asset, channel_id)?,
Expand Down