--- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -29,10 +29,10 @@ use sp_runtime::sp_std::prelude::Vec; use sp_runtime::{ traits::{ - DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SignedExtension, Zero, + DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SaturatedConversion, SignedExtension, Zero, }, transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + TransactionPriority, InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, }, FixedPointOperand, FixedU128, }; @@ -2302,6 +2302,13 @@ >::compute_fee(len as u32, info, tip) } + fn get_priority(len: usize, info: &DispatchInfoOf, final_fee: BalanceOf) -> TransactionPriority { + let weight_saturation = T::MaximumBlockWeight::get() / info.weight.max(1); + let len_saturation = T::MaximumBlockLength::get() as u64 / (len as u64).max(1); + let coefficient: BalanceOf = weight_saturation.min(len_saturation).saturated_into::>(); + final_fee.saturating_mul(coefficient).saturated_into::() + } + fn withdraw_fee( &self, who: &T::AccountId, @@ -2525,12 +2532,16 @@ fn validate( &self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, ) -> TransactionValidity { - Ok(ValidTransaction::default()) + let (fee, _) = self.withdraw_fee(who, call, info, len)?; + Ok(ValidTransaction { + priority: Self::get_priority(len, info, fee), + ..Default::default() + }) } fn pre_dispatch( --- a/tests/src/accounts.ts +++ b/tests/src/accounts.ts @@ -1,2 +1,3 @@ export const bobsPublicKey = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'; export const alicesPublicKey = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; +export const ferdiesPublicKey = '5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL'; --- a/tests/src/transfer.test.ts +++ b/tests/src/transfer.test.ts @@ -1,6 +1,6 @@ -import { expect } from "chai"; +import { expect, assert } from "chai"; import { default as usingApi, submitTransactionAsync } from "./substrate/substrate-api"; -import { alicesPublicKey, bobsPublicKey } from "./accounts"; +import { alicesPublicKey, bobsPublicKey, ferdiesPublicKey } from "./accounts"; import privateKey from "./substrate/privateKey"; import getBalance from "./substrate/get-balance"; @@ -20,4 +20,22 @@ expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true; }); }); + + it('Inability to pay fees error message is correct', async () => { + await usingApi(async api => { + const pk = privateKey('//Ferdie'); + + console.log = function () {}; + console.error = function () {}; + + const badTransfer = api.tx.balances.transfer(bobsPublicKey, 1n); + const badTransaction = async function () { + const result = await submitTransactionAsync(pk, badTransfer); + }; + await expect(badTransaction()).to.be.rejectedWith("Inability to pay some fees"); + + delete console.log; + delete console.error; + }); + }); });