diff --git a/Cargo.lock b/Cargo.lock index 3407a210..d69e713f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9469,7 +9469,6 @@ dependencies = [ "log", "pallet-contracts", "parity-scale-codec", - "pop-primitives", "rand", "sp-core", "sp-runtime", @@ -9543,10 +9542,6 @@ dependencies = [ [[package]] name = "pop-primitives" version = "0.0.0" -dependencies = [ - "parity-scale-codec", - "scale-info", -] [[package]] name = "pop-runtime-common" diff --git a/extension/Cargo.toml b/extension/Cargo.toml index 03b4221a..c611984d 100644 --- a/extension/Cargo.toml +++ b/extension/Cargo.toml @@ -16,9 +16,6 @@ targets = ["x86_64-unknown-linux-gnu"] codec.workspace = true log.workspace = true -# Local -pop-primitives.workspace = true - # Substrate frame-support.workspace = true frame-system.workspace = true @@ -33,19 +30,18 @@ rand = "0.8.5" [features] default = ["std"] std = [ - "log/std", - "codec/std", - "frame-support/std", - "frame-system/std", - "pallet-contracts/std", - "pop-primitives/std", - "sp-runtime/std", - "sp-core/std", - "sp-std/std", + "log/std", + "codec/std", + "frame-support/std", + "frame-system/std", + "pallet-contracts/std", + "sp-runtime/std", + "sp-core/std", + "sp-std/std", ] runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-contracts/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] diff --git a/extension/src/lib.rs b/extension/src/lib.rs index 3fb46b37..790c971e 100644 --- a/extension/src/lib.rs +++ b/extension/src/lib.rs @@ -272,9 +272,7 @@ impl TryFrom for FuncId { } /// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. -/// The contract calling the chain extension can optionally convert the status code to the descriptive `Error`. -/// -/// For `Error` see `pop_primitives::::error::Error`. +/// The contract calling the chain extension can optionally convert the status code to the descriptive `pop_api::Error`. /// /// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. /// As a result, contracts maintain compatibility across different versions of the runtime. diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index cc56630a..1b9558d7 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -11,6 +11,7 @@ frame-system = { version = "29.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } pallet-assets = { version = "30.0.0", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } +pop-api = { path = "../../pop-api", default-features = false } pop-primitives = { path = "../../primitives", default-features = false } pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } sp-io = { version = "31.0.0", default-features = false } @@ -25,6 +26,7 @@ std = [ "pallet-balances/std", "pallet-assets/std", "pallet-contracts/std", + "pop-api/std", "pop-primitives/std", "pop-runtime-devnet/std", "scale/std", diff --git a/pop-api/integration-tests/contracts/fungibles/lib.rs b/pop-api/integration-tests/contracts/fungibles/lib.rs index 239d3a2d..ab1b0e40 100755 --- a/pop-api/integration-tests/contracts/fungibles/lib.rs +++ b/pop-api/integration-tests/contracts/fungibles/lib.rs @@ -181,7 +181,7 @@ mod fungibles { #[ink::test] fn default_works() { - PopApiFungiblesExample::new(); + Fungibles::new(); } } } diff --git a/pop-api/integration-tests/src/fungibles/mod.rs b/pop-api/integration-tests/src/fungibles/mod.rs index 0ca7d4f9..691ed773 100644 --- a/pop-api/integration-tests/src/fungibles/mod.rs +++ b/pop-api/integration-tests/src/fungibles/mod.rs @@ -1,5 +1,5 @@ use super::*; -use pop_primitives::error::{ +use pop_api::{ ArithmeticError::*, Error::{self, *}, TokenError::*, diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index cc785c14..b1bf67fa 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -11,6 +11,7 @@ use constants::DECODING_FAILED; use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; #[cfg(feature = "assets")] pub use v0::assets; +pub use v0::{ArithmeticError, Error, TokenError, TransactionalError}; /// Module providing primitives types. pub mod primitives; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index c881f823..435e1789 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -11,9 +11,9 @@ use crate::{ primitives::{AccountId, AssetId, Balance}, Result, StatusCode, }; -pub use asset_management::*; use constants::*; use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; +pub use management::*; pub use metadata::*; // Helper method to build a dispatch call. @@ -485,13 +485,11 @@ mod tests { use super::FungiblesError; use crate::{ constants::{ASSETS, BALANCES}, - primitives::error::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }, + ArithmeticError::*, + Error::{self, *}, StatusCode, + TokenError::*, + TransactionalError::*, }; fn error_into_status_code(error: Error) -> StatusCode { diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index a4824327..ce8ccdd5 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,10 +1,9 @@ use crate::{ build_extension_method, constants::{DISPATCH, READ_STATE}, - primitives::error::Error, StatusCode, }; -use ink::env::chain_extension::ChainExtensionMethod; +use ink::{env::chain_extension::ChainExtensionMethod, scale::Decode}; /// APIs for asset-related use cases. #[cfg(feature = "assets")] @@ -12,12 +11,131 @@ pub mod assets; pub(crate) const V0: u8 = 0; +/// Reason why a Pop API call failed. +#[derive(Debug, Eq, PartialEq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +#[repr(u8)] +#[allow(clippy::unnecessary_cast)] +pub enum Error { + /// An unknown error occurred. This variant captures any unexpected errors that the + /// contract cannot specifically handle. It is useful for cases where there are breaking + /// changes in the runtime or when an error falls outside the predefined categories. The + /// variant includes: + Other { + /// The index within the `DispatchError`. + dispatch_error_index: u8, + /// The index within the `DispatchError` variant (e.g. a `TokenError`). + error_index: u8, + /// The specific error code or sub-index, providing additional context (e.g. + /// error` in `ModuleError`). + error: u8, + } = 0, + /// Failed to lookup some data. + CannotLookup = 1, + /// A bad origin. + BadOrigin = 2, + /// A custom error in a module. + /// + Module { + /// The pallet index. + index: u8, + /// The error within the pallet. + error: u8, + } = 3, + /// At least one consumer is remaining so the account cannot be destroyed. + ConsumerRemaining = 4, + /// There are no providers so the account cannot be created. + NoProviders = 5, + /// There are too many consumers so the account cannot be created. + TooManyConsumers = 6, + /// An error to do with tokens. + Token(TokenError) = 7, + /// An arithmetic error. + Arithmetic(ArithmeticError) = 8, + /// The number of transactional layers has been reached, or we are not in a transactional + /// layer. + Transactional(TransactionalError) = 9, + /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + Exhausted = 10, + /// The state is corrupt; this is generally not going to fix itself. + Corruption = 11, + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + Unavailable = 12, + /// Root origin is not allowed. + RootNotAllowed = 13, + /// Unknown call. + UnknownCall = 254, + /// Decoding failed. + DecodingFailed = 255, +} + impl From for Error { fn from(value: StatusCode) -> Self { value.0.into() } } +impl From for Error { + /// Converts a `u32` status code into an `Error`. + /// + /// This conversion maps a raw status code returned by the runtime into the more + /// descriptive `Error` enum variant, providing better context and understanding of the + /// error. + fn from(value: u32) -> Self { + let encoded = value.to_le_bytes(); + Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) + } +} + +/// Description of what went wrong when trying to complete an operation on a token. +#[derive(Debug, Eq, PartialEq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum TokenError { + /// Funds are unavailable. + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot + /// be (re)moved. + OnlyProvider, + /// Account cannot exist with the funds that would be given. + BelowMinimum, + /// Account cannot be created. + CannotCreate, + /// The asset in question is unknown. + UnknownAsset, + /// Funds exist but are frozen. + Frozen, + /// Operation is not supported by the asset. + Unsupported, + /// Account cannot be created for a held balance. + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + NotExpendable, + /// Account cannot receive the assets. + Blocked, +} + +/// Arithmetic errors. +#[derive(Debug, Eq, PartialEq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum ArithmeticError { + /// Underflow. + Underflow, + /// Overflow. + Overflow, + /// Division by zero. + DivisionByZero, +} + +/// Errors related to transactional storage layers. +#[derive(Debug, Eq, PartialEq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum TransactionalError { + /// Too many transactional layers have been spawned. + LimitReached, + /// A transactional layer was expected, but does not exist. + NoLayer, +} + // Helper method to build a dispatch call. // // Parameters: diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index e7d55ffe..9837d23d 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -5,13 +5,6 @@ license = "GPL-3.0-only" version = "0.0.0" edition = "2021" -[dependencies] -codec.workspace = true -scale-info.workspace = true - [features] default = ["std"] -std = [ - "codec/std", - "scale-info/std", -] \ No newline at end of file +std = [] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index a51661ea..c3c1345f 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,129 +1,6 @@ -#![cfg_attr(not(feature = "std"), no_std, no_main)] +//! The `pop-primitives` crate provides types used by both the Pop Network runtime and the `pop-api`. -use codec::{Decode, Encode}; -#[cfg(feature = "std")] -use scale_info::TypeInfo; -pub use v0::error; +#![cfg_attr(not(feature = "std"), no_std, no_main)] /// Identifier for the class of asset. pub type AssetId = u32; - -pub mod v0 { - use super::*; - pub mod error { - use super::*; - - /// Reason why a Pop API call failed. - #[derive(Encode, Decode, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "std", derive(TypeInfo))] - #[repr(u8)] - #[allow(clippy::unnecessary_cast)] - pub enum Error { - /// An unknown error occurred. This variant captures any unexpected errors that the - /// contract cannot specifically handle. It is useful for cases where there are breaking - /// changes in the runtime or when an error falls outside the predefined categories. The - /// variant includes: - /// - /// - `dispatch_error_index`: The index within the `DispatchError`. - /// - `error_index`: The index within the `DispatchError` variant (e.g. a `TokenError`). - /// - `error`: The specific error code or sub-index, providing additional context (e.g. - /// `error` in `ModuleError`). - Other { dispatch_error_index: u8, error_index: u8, error: u8 } = 0, - /// Failed to lookup some data. - CannotLookup = 1, - /// A bad origin. - BadOrigin = 2, - /// A custom error in a module. - /// - /// - `index`: The pallet index. - /// - `error`: The error within the pallet. - Module { index: u8, error: u8 } = 3, - /// At least one consumer is remaining so the account cannot be destroyed. - ConsumerRemaining = 4, - /// There are no providers so the account cannot be created. - NoProviders = 5, - /// There are too many consumers so the account cannot be created. - TooManyConsumers = 6, - /// An error to do with tokens. - Token(TokenError) = 7, - /// An arithmetic error. - Arithmetic(ArithmeticError) = 8, - /// The number of transactional layers has been reached, or we are not in a transactional - /// layer. - Transactional(TransactionalError) = 9, - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - Exhausted = 10, - /// The state is corrupt; this is generally not going to fix itself. - Corruption = 11, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - Unavailable = 12, - /// Root origin is not allowed. - RootNotAllowed = 13, - /// Unknown call. - UnknownCall = 254, - /// Decoding failed. - DecodingFailed = 255, - } - - impl From for Error { - /// Converts a `u32` status code into an `Error`. - /// - /// This conversion maps a raw status code returned by the runtime into the more - /// descriptive `Error` enum variant, providing better context and understanding of the - /// error. - fn from(value: u32) -> Self { - let encoded = value.to_le_bytes(); - Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) - } - } - - /// Description of what went wrong when trying to complete an operation on a token. - #[derive(Encode, Decode, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "std", derive(TypeInfo))] - pub enum TokenError { - /// Funds are unavailable. - FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot - /// be (re)moved. - OnlyProvider, - /// Account cannot exist with the funds that would be given. - BelowMinimum, - /// Account cannot be created. - CannotCreate, - /// The asset in question is unknown. - UnknownAsset, - /// Funds exist but are frozen. - Frozen, - /// Operation is not supported by the asset. - Unsupported, - /// Account cannot be created for a held balance. - CannotCreateHold, - /// Withdrawal would cause unwanted loss of account. - NotExpendable, - /// Account cannot receive the assets. - Blocked, - } - - /// Arithmetic errors. - #[derive(Encode, Decode, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "std", derive(TypeInfo))] - pub enum ArithmeticError { - /// Underflow. - Underflow, - /// Overflow. - Overflow, - /// Division by zero. - DivisionByZero, - } - - /// Errors related to transactional storage layers. - #[derive(Encode, Decode, Debug, Eq, PartialEq)] - #[cfg_attr(feature = "std", derive(TypeInfo))] - pub enum TransactionalError { - /// Too many transactional layers have been spawned. - LimitReached, - /// A transactional layer was expected, but does not exist. - NoLayer, - } - } -} diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index 1dcd44da..1ef83bc1 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,5 +1,6 @@ mod api; -mod assets; +// Public due to pop api integration tests crate. +pub mod assets; mod contracts; mod proxy; // Public due to integration tests crate.