Skip to content

Commit

Permalink
refactor(vouchers): Remove gear-pallet explicit dependency on vouchers (
Browse files Browse the repository at this point in the history
  • Loading branch information
breathx authored Dec 17, 2023
1 parent d684632 commit f6c13bd
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 139 deletions.
16 changes: 0 additions & 16 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,19 +350,3 @@ where
self.function.clone()
}
}

pub trait PaymentVoucher<AccountId, ProgramId, Balance> {
type VoucherId;
type Error;

fn voucher_id(who: AccountId, program: ProgramId) -> Self::VoucherId;
}

impl<AccountId: Default, ProgramId, Balance> PaymentVoucher<AccountId, ProgramId, Balance> for () {
type VoucherId = AccountId;
type Error = &'static str;

fn voucher_id(_who: AccountId, _program: ProgramId) -> Self::VoucherId {
unimplemented!()
}
}
5 changes: 5 additions & 0 deletions common/src/storage/complex/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ pub trait MailboxError {
fn element_not_found() -> Self;
}

impl MailboxError for () {
fn duplicate_key() -> Self {}
fn element_not_found() -> Self {}
}

/// `Mailbox` implementation based on `DoubleMapStorage`.
///
/// Generic parameter `Error` requires `MailboxError` implementation.
Expand Down
9 changes: 3 additions & 6 deletions gsdk/src/metadata/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2667,12 +2667,9 @@ pub mod runtime_types {
#[doc = "Program with the specified id is not found."]
ProgramNotFound,
#[codec(index = 14)]
#[doc = "Voucher can't be redeemed"]
FailureRedeemingVoucher,
#[codec(index = 15)]
#[doc = "Gear::run() already included in current block."]
GearRunAlreadyInBlock,
#[codec(index = 16)]
#[codec(index = 15)]
#[doc = "The program rent logic is disabled."]
ProgramRentDisabled,
}
Expand Down Expand Up @@ -3339,9 +3336,9 @@ pub mod runtime_types {
#[doc = "\n\t\t\tCustom [dispatch errors](https://docs.substrate.io/main-docs/build/events-errors/)\n\t\t\tof this pallet.\n\t\t\t"]
pub enum Error {
#[codec(index = 0)]
FailureToCreateVoucher,
InsufficientBalance,
#[codec(index = 1)]
FailureToRedeemVoucher,
InvalidVoucher,
}
#[derive(Debug, crate::gp::Decode, crate::gp::DecodeAsType, crate::gp::Encode)]
#[doc = "\n\t\t\tThe [event](https://docs.substrate.io/main-docs/build/events-errors/) emitted\n\t\t\tby this pallet.\n\t\t\t"]
Expand Down
4 changes: 2 additions & 2 deletions pallets/gear-voucher/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ benchmarks! {
let holder_lookup = T::Lookup::unlookup(holder.clone());
}: _(RawOrigin::Signed(issuer), holder_lookup, program_id, 10_000_000_000_000_u128.unique_saturated_into())
verify {
let voucher_account_id = GearVoucher::<T>::voucher_account_id(&holder, &program_id);
let voucher_id = GearVoucher::<T>::voucher_id(&holder, &program_id);
assert_eq!(
CurrencyOf::<T>::free_balance(&voucher_account_id),
CurrencyOf::<T>::free_balance(&voucher_id),
10_000_000_000_000_u128.unique_saturated_into(),
);
}
Expand Down
54 changes: 32 additions & 22 deletions pallets/gear-voucher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ mod mock;
#[cfg(test)]
mod tests;

use common::PaymentVoucher;
use frame_support::{
pallet_prelude::*,
traits::{Currency, ExistenceRequirement, ReservableCurrency, StorageVersion},
Expand All @@ -82,7 +81,9 @@ const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);
#[frame_support::pallet]
pub mod pallet {
use super::*;
use common::storage::Mailbox;
use frame_system::pallet_prelude::*;
use gear_core::message::UserStoredMessage;

#[pallet::config]
pub trait Config: frame_system::Config {
Expand All @@ -103,6 +104,8 @@ pub mod pallet {
AccountId = Self::AccountId,
Balance = BalanceOf<Self>,
>;

type Mailbox: Mailbox<Key1 = Self::AccountId, Key2 = MessageId, Value = UserStoredMessage>;
}

#[pallet::pallet]
Expand All @@ -124,8 +127,8 @@ pub mod pallet {
// Gas pallet error.
#[pallet::error]
pub enum Error<T> {
FailureToCreateVoucher,
FailureToRedeemVoucher,
InsufficientBalance,
InvalidVoucher,
}

#[pallet::hooks]
Expand Down Expand Up @@ -158,13 +161,13 @@ pub mod pallet {
let to = T::Lookup::lookup(to)?;

// Generate unique account id corresponding to the pair (user, program)
let voucher_id = Self::voucher_account_id(&to, &program);
let voucher_id = Self::voucher_id(&to, &program);

// Transfer funds to the keyless account
T::Currency::transfer(&who, &voucher_id, value, ExistenceRequirement::KeepAlive)
.map_err(|e| {
log::debug!("Failed to transfer funds to the voucher account: {:?}", e);
Error::<T>::FailureToCreateVoucher
Error::<T>::InsufficientBalance
})?;

Self::deposit_event(Event::VoucherIssued {
Expand All @@ -185,27 +188,33 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let origin = ensure_signed(origin)?;

T::CallsDispatcher::dispatch(origin, call)
let sponsor = Self::sponsor_of(&origin, &call).ok_or(Error::<T>::InvalidVoucher)?;

T::CallsDispatcher::dispatch(origin, sponsor, call)
}
}
}

impl<T: Config> Pallet<T> {
/// Derive a synthesized account ID from an account ID and a program ID.
pub fn voucher_account_id(who: &T::AccountId, program_id: &ProgramId) -> T::AccountId {
let entropy = (b"modlpy/voucher__", who, program_id).using_encoded(blake2_256);
Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
.expect("infinite length input; no invalid inputs for type; qed")
}
}

impl<T: Config> PaymentVoucher<T::AccountId, ProgramId, BalanceOf<T>> for Pallet<T> {
type VoucherId = T::AccountId;
type Error = DispatchError;
impl<T: Config> Pallet<T> {
/// Derive a synthesized account ID from an account ID and a program ID.
pub fn voucher_id(who: &T::AccountId, program_id: &ProgramId) -> T::AccountId {
let entropy = (b"modlpy/voucher__", who, program_id).using_encoded(blake2_256);
Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
.expect("infinite length input; no invalid inputs for type; qed")
}

#[inline]
fn voucher_id(who: T::AccountId, program: ProgramId) -> Self::VoucherId {
Self::voucher_account_id(&who, &program)
/// Return synthesized account ID based on call data.
pub fn sponsor_of(
who: &T::AccountId,
call: &PrepaidCall<BalanceOf<T>>,
) -> Option<T::AccountId> {
match call {
PrepaidCall::SendMessage { destination, .. } => {
Some(Self::voucher_id(who, destination))
}
PrepaidCall::SendReply { reply_to_id, .. } => T::Mailbox::peek(who, reply_to_id)
.map(|stored_message| Self::voucher_id(who, &stored_message.source())),
}
}
}
}

Expand Down Expand Up @@ -235,6 +244,7 @@ pub trait PrepaidCallsDispatcher {

fn dispatch(
account_id: Self::AccountId,
sponsor_id: Self::AccountId,
call: PrepaidCall<Self::Balance>,
) -> DispatchResultWithPostInfo;
}
34 changes: 34 additions & 0 deletions pallets/gear-voucher/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate as pallet_gear_voucher;
use common::storage::{Interval, Mailbox};
use frame_support::{
construct_runtime, parameter_types, weights::constants::RocksDbWeight, PalletId,
};
use frame_system as system;
use gear_core::{ids::MessageId, message::UserStoredMessage};
use primitive_types::H256;
use sp_runtime::{
generic,
Expand Down Expand Up @@ -71,18 +73,50 @@ impl crate::PrepaidCallsDispatcher for () {
}
fn dispatch(
_account_id: Self::AccountId,
_sponsor_id: Self::AccountId,
_call: pallet_gear_voucher::PrepaidCall<Balance>,
) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {
unimplemented!()
}
}

pub struct MailboxMock;

impl Mailbox for MailboxMock {
type BlockNumber = ();
type Error = ();
type Key1 = AccountId;
type Key2 = MessageId;
type Value = UserStoredMessage;
type OutputError = ();

fn clear() {
unimplemented!()
}
fn contains(_key1: &Self::Key1, _key2: &Self::Key2) -> bool {
unimplemented!()
}
fn insert(_value: Self::Value, _bn: Self::BlockNumber) -> Result<(), Self::OutputError> {
unimplemented!()
}
fn peek(_key1: &Self::Key1, _key2: &Self::Key2) -> Option<Self::Value> {
unimplemented!()
}
fn remove(
_key1: Self::Key1,
_key2: Self::Key2,
) -> Result<(Self::Value, Interval<Self::BlockNumber>), Self::OutputError> {
unimplemented!()
}
}

impl pallet_gear_voucher::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type PalletId = VoucherPalletId;
type WeightInfo = ();
type CallsDispatcher = ();
type Mailbox = MailboxMock;
}

// Build genesis storage according to the mock runtime.
Expand Down
10 changes: 5 additions & 5 deletions pallets/gear-voucher/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use primitive_types::H256;
fn voucher_issue_works() {
new_test_ext().execute_with(|| {
let program_id = H256::from(b"some//quasy//random//program//id").cast();
let synthesized = Voucher::voucher_account_id(&BOB, &program_id);
let synthesized = Voucher::voucher_id(&BOB, &program_id);

assert_ok!(Voucher::issue(
RuntimeOrigin::signed(ALICE),
Expand All @@ -47,7 +47,7 @@ fn voucher_issue_works() {
// Insufficient funds
assert_noop!(
Voucher::issue(RuntimeOrigin::signed(ALICE), BOB, program_id, 100_000_000,),
Error::<Test>::FailureToCreateVoucher
Error::<Test>::InsufficientBalance
);
});
}
Expand All @@ -56,7 +56,7 @@ fn voucher_issue_works() {
fn voucher_redemption_works() {
new_test_ext().execute_with(|| {
let program_id = H256::from(b"some//quasy//random//program//id").cast();
let synthesized = Voucher::voucher_account_id(&BOB, &program_id);
let synthesized = Voucher::voucher_id(&BOB, &program_id);

assert_ok!(Voucher::issue(
RuntimeOrigin::signed(ALICE),
Expand All @@ -69,13 +69,13 @@ fn voucher_redemption_works() {

// Redemption ok
assert_ok!(Balances::reserve(
&Voucher::voucher_id(BOB, program_id),
&Voucher::voucher_id(&BOB, &program_id),
2_000
));

// Redemption fails
assert_noop!(
Balances::reserve(&Voucher::voucher_id(BOB, program_id), 100_000_000),
Balances::reserve(&Voucher::voucher_id(&BOB, &program_id), 100_000_000),
pallet_balances::Error::<Test>::InsufficientBalance
);
});
Expand Down
Loading

0 comments on commit f6c13bd

Please sign in to comment.