difftreelog
Merge pull request #577 from UniqueNetwork/fix/fee-multiplier-update
in: master
16 files changed
pallets/configuration/src/lib.rsdiffbeforeafterboth--- a/pallets/configuration/src/lib.rs
+++ b/pallets/configuration/src/lib.rs
@@ -25,12 +25,14 @@
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
-use sp_arithmetic::traits::{BaseArithmetic, Unsigned};
+use sp_arithmetic::{
+ per_things::{Perbill, PerThing},
+ traits::{BaseArithmetic, Unsigned},
+};
use smallvec::smallvec;
pub use pallet::*;
use sp_core::U256;
-use sp_runtime::Perbill;
#[pallet]
mod pallet {
@@ -46,8 +48,7 @@
#[pallet::config]
pub trait Config: frame_system::Config {
#[pallet::constant]
- type DefaultWeightToFeeCoefficient: Get<u32>;
-
+ type DefaultWeightToFeeCoefficient: Get<u64>;
#[pallet::constant]
type DefaultMinGasPrice: Get<u64>;
@@ -66,7 +67,7 @@
#[pallet::storage]
pub type WeightToFeeCoefficientOverride<T: Config> = StorageValue<
- Value = u32,
+ Value = u64,
QueryKind = ValueQuery,
OnEmpty = T::DefaultWeightToFeeCoefficient,
>;
@@ -90,7 +91,7 @@
#[pallet::weight(T::DbWeight::get().writes(1))]
pub fn set_weight_to_fee_coefficient_override(
origin: OriginFor<T>,
- coeff: Option<u32>,
+ coeff: Option<u64>,
) -> DispatchResult {
ensure_root(origin)?;
if let Some(coeff) = coeff {
@@ -156,14 +157,17 @@
impl<T, B> WeightToFeePolynomial for WeightToFee<T, B>
where
T: Config,
- B: BaseArithmetic + From<u32> + Copy + Unsigned,
+ B: BaseArithmetic + From<u32> + From<u64> + Copy + Unsigned,
{
type Balance = B;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
smallvec!(WeightToFeeCoefficient {
- coeff_integer: <WeightToFeeCoefficientOverride<T>>::get().into(),
- coeff_frac: Perbill::zero(),
+ coeff_integer: (<WeightToFeeCoefficientOverride<T>>::get() / Perbill::ACCURACY as u64)
+ .into(),
+ coeff_frac: Perbill::from_parts(
+ (<WeightToFeeCoefficientOverride<T>>::get() % Perbill::ACCURACY as u64) as u32
+ ),
negative: false,
degree: 1,
})
primitives/common/src/constants.rsdiffbeforeafterboth--- a/primitives/common/src/constants.rs
+++ b/primitives/common/src/constants.rs
@@ -43,10 +43,10 @@
pub const UNIQUE: Balance = 100 * CENTIUNIQUE;
// Targeting 0.1 UNQ per transfer
-pub const WEIGHT_TO_FEE_COEFF: u32 = /*<weight2fee>*/175_199_920/*</weight2fee>*/;
+pub const WEIGHT_TO_FEE_COEFF: u64 = /*<weight2fee>*/77_083_524_944_487_510/*</weight2fee>*/;
// Targeting 0.15 UNQ per transfer via ETH
-pub const MIN_GAS_PRICE: u64 = /*<mingasprice>*/1_014_919_410_810/*</mingasprice>*/;
+pub const MIN_GAS_PRICE: u64 = /*<mingasprice>*/1_014_919_313_914/*</mingasprice>*/;
/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
@@ -60,5 +60,5 @@
.set_proof_size(MAX_POV_SIZE as u64);
parameter_types! {
- pub const TransactionByteFee: Balance = 501 * MICROUNIQUE;
+ pub const TransactionByteFee: Balance = 501 * MICROUNIQUE / 2;
}
runtime/common/config/pallets/mod.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/mod.rs
+++ b/runtime/common/config/pallets/mod.rs
@@ -104,7 +104,7 @@
pub const DayRelayBlocks: BlockNumber = RELAY_DAYS;
}
impl pallet_configuration::Config for Runtime {
- type DefaultWeightToFeeCoefficient = ConstU32<{ up_common::constants::WEIGHT_TO_FEE_COEFF }>;
+ type DefaultWeightToFeeCoefficient = ConstU64<{ up_common::constants::WEIGHT_TO_FEE_COEFF }>;
type DefaultMinGasPrice = ConstU64<{ up_common::constants::MIN_GAS_PRICE }>;
type MaxXcmAllowedLocations = ConstU32<16>;
type AppPromotionDailyRate = AppPromotionDailyRate;
runtime/common/config/substrate.rsdiffbeforeafterboth--- a/runtime/common/config/substrate.rs
+++ b/runtime/common/config/substrate.rs
@@ -28,10 +28,12 @@
traits::{BlakeTwo256, AccountIdLookup},
Perbill, Permill, Percent,
};
+use sp_arithmetic::traits::One;
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot,
};
+use pallet_transaction_payment::{Multiplier, ConstFeeMultiplier};
use crate::{
runtime_common::DealWithFees, Runtime, RuntimeEvent, RuntimeCall, RuntimeOrigin, PalletInfo,
System, Balances, Treasury, SS58Prefix, Version,
@@ -152,6 +154,8 @@
/// This value increases the priority of `Operational` transactions by adding
/// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
pub const OperationalFeeMultiplier: u8 = 5;
+
+ pub FeeMultiplier: Multiplier = Multiplier::one();
}
impl pallet_transaction_payment::Config for Runtime {
@@ -160,7 +164,7 @@
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
type OperationalFeeMultiplier = OperationalFeeMultiplier;
type WeightToFee = pallet_configuration::WeightToFee<Self, Balance>;
- type FeeMultiplierUpdate = ();
+ type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
}
parameter_types! {
tests/src/calibrate.tsdiffbeforeafterboth1import {IKeyringPair} from '@polkadot/types/types';23import {usingEthPlaygrounds, EthUniqueHelper} from './eth/util';456function linearRegression(points: { x: bigint, y: bigint }[]) {7 let sumxy = 0n;8 let sumx = 0n;9 let sumy = 0n;10 let sumx2 = 0n;11 const n = points.length;12 for (let i = 0; i < n; i++) {13 const p = points[i];14 sumxy += p.x * p.y;15 sumx += p.x;16 sumy += p.y;17 sumx2 += p.x * p.x;18 }1920 const nb = BigInt(n);2122 const a = (nb * sumxy - sumx * sumy) / (nb * sumx2 - sumx * sumx);23 const b = (sumy - a * sumx) / nb;2425 return {a, b};26}2728// JS has no builtin function to calculate sqrt of bigint29// https://stackoverflow.com/a/53684036/619016930function sqrt(value: bigint) {31 if (value < 0n) {32 throw 'square root of negative numbers is not supported';33 }3435 if (value < 2n) {36 return value;37 }3839 function newtonIteration(n: bigint, x0: bigint): bigint {40 const x1 = ((n / x0) + x0) >> 1n;41 if (x0 === x1 || x0 === (x1 - 1n)) {42 return x0;43 }44 return newtonIteration(n, x1);45 }4647 return newtonIteration(value, 1n);48}4950function _error(points: { x: bigint, y: bigint }[], hypothesis: (a: bigint) => bigint) {51 return sqrt(points.map(p => {52 const v = hypothesis(p.x);53 const vv = p.y;5455 return (v - vv) ** 2n;56 }).reduce((a, b) => a + b, 0n) / BigInt(points.length));57}5859async function calibrateWeightToFee(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {60 const alice = await privateKey('//Alice');61 const bob = await privateKey('//Bob');62 const dataPoints = [];6364 {65 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});66 const token = await collection.mintToken(alice, {Substrate: alice.address});67 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);68 await token.transfer(alice, {Substrate: bob.address});69 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);7071 console.log(`Original price: ${Number(aliceBalanceBefore-aliceBalanceAfter)/Number(helper.balance.getOneTokenNominal())} UNQ`);72 }7374 const api = helper.getApi();75 const defaultCoeff = (api.consts.configuration.defaultWeightToFeeCoefficient as any).toBigInt();76 for (let i = -5; i < 5; i++) {77 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(defaultCoeff + defaultCoeff / 1000n * BigInt(i))));7879 const coefficient = (await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt();80 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});81 const token = await collection.mintToken(alice, {Substrate: alice.address});8283 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);84 await token.transfer(alice, {Substrate: bob.address});85 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);8687 const transferPrice = aliceBalanceBefore - aliceBalanceAfter;8889 dataPoints.push({x: transferPrice, y: coefficient});90 }91 const {a, b} = linearRegression(dataPoints);9293 // console.log(`Error: ${error(dataPoints, x => a*x+b)}`);9495 const perfectValue = a * helper.balance.getOneTokenNominal() / 10n + b;96 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(perfectValue.toString())));9798 {99 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});100 const token = await collection.mintToken(alice, {Substrate: alice.address});101 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);102 await token.transfer(alice, {Substrate: bob.address});103 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);104105 console.log(`Calibrated price: ${Number(aliceBalanceBefore-aliceBalanceAfter)/Number(helper.balance.getOneTokenNominal())} UNQ`);106 }107}108109async function calibrateMinGasPrice(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {110 const alice = await privateKey('//Alice');111 const caller = await helper.eth.createAccountWithBalance(alice);112 const receiver = helper.eth.createAccount();113 const dataPoints = [];114115 {116 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});117 const token = await collection.mintToken(alice, {Ethereum: caller});118119 const address = helper.ethAddress.fromCollectionId(collection.collectionId);120 const contract = helper.ethNativeContract.collection(address, 'nft', caller);121122 const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));123124 console.log(`Original price: ${Number(cost)/Number(helper.balance.getOneTokenNominal())} UNQ`);125 }126127 const api = helper.getApi();128 const defaultCoeff = (api.consts.configuration.defaultMinGasPrice as any).toBigInt();129 for (let i = -8; i < 8; i++) {130 const gasPrice = defaultCoeff + defaultCoeff / 100000n * BigInt(i);131 const gasPriceStr = '0x' + gasPrice.toString(16);132 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(gasPrice)));133134 const coefficient = (await api.query.configuration.minGasPriceOverride() as any).toBigInt();135 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});136 const token = await collection.mintToken(alice, {Ethereum: caller});137138 const address = helper.ethAddress.fromCollectionId(collection.collectionId);139 const contract = helper.ethNativeContract.collection(address, 'nft', caller);140141 const transferPrice = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gasPrice: gasPriceStr, gas: helper.eth.DEFAULT_GAS}));142143 dataPoints.push({x: transferPrice, y: coefficient});144 }145146 const {a, b} = linearRegression(dataPoints);147148 // console.log(`Error: ${error(dataPoints, x => a*x+b)}`);149150 // * 0.15 = * 10000 / 66666151 const perfectValue = a * helper.balance.getOneTokenNominal() * 1000000n / 6666666n + b;152 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(perfectValue.toString())));153154 {155 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});156 const token = await collection.mintToken(alice, {Ethereum: caller});157158 const address = helper.ethAddress.fromCollectionId(collection.collectionId);159 const contract = helper.ethNativeContract.collection(address, 'nft', caller);160161 const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));162163 console.log(`Calibrated price: ${Number(cost)/Number(helper.balance.getOneTokenNominal())} UNQ`);164 }165}166167(async () => {168 await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {169 // Second run slightly reduces error sometimes, as price line is not actually straight, this is a curve170171 await calibrateWeightToFee(helper, privateKey);172 await calibrateWeightToFee(helper, privateKey);173174 await calibrateMinGasPrice(helper, privateKey);175 await calibrateMinGasPrice(helper, privateKey);176 });177})();1import {IKeyringPair} from '@polkadot/types/types';2import {usingEthPlaygrounds, EthUniqueHelper} from './eth/util';34class Fract {5 static ZERO = new Fract(0n);6 constructor(public readonly a: bigint, public readonly b: bigint = 1n) {7 if (b === 0n) throw new Error('division by zero');8 if (b < 0n) throw new Error('missing normalization');9 }1011 mul(other: Fract) {12 return new Fract(this.a * other.a, this.b * other.b).optimize();13 }1415 div(other: Fract) {16 return this.mul(other.inv());17 }1819 plus(other: Fract) {20 if (this.b === other.b) {21 return new Fract(this.a + other.a, this.b);22 }23 return new Fract(this.a * other.b + other.a * this.b, this.b * other.b).optimize();24 }2526 minus(other: Fract) {27 return this.plus(other.neg());28 }2930 neg() {31 return new Fract(-this.a, this.b);32 }33 inv() {34 if (this.a < 0) {35 return new Fract(-this.b, -this.a);36 } else {37 return new Fract(this.b, this.a);38 }39 }4041 optimize() {42 function gcd(x: bigint, y: bigint) {43 if (x < 0n)44 x = -x;45 if (y < 0n)46 y = -y;47 while(y) {48 const t = y;49 y = x % y;50 x = t;51 }52 return x;53 }54 const v = gcd(this.a, this.b);55 return new Fract(this.a / v, this.b / v);56 }5758 toBigInt() {59 return this.a / this.b;60 }61 toNumber() {62 const v = this.optimize();63 return Number(v.a) / Number(v.b);64 }65 toString() {66 const v = this.optimize();67 return `${v.a} / ${v.b}`;68 }6970 lt(other: Fract) {71 return this.a * other.b < other.a * this.b;72 }73 eq(other: Fract) {74 return this.a * other.b === other.a * this.b;75 }7677 sqrt() {78 if (this.a < 0n) {79 throw 'square root of negative numbers is not supported';80 }8182 if (this.lt(new Fract(2n))) {83 return this;84 }8586 function newtonIteration(n: Fract, x0: Fract): Fract {87 const x1 = rpn(n, x0, '/', x0, '+', new Fract(2n), '/');88 if (x0.eq(x1) || x0.eq(x1.minus(new Fract(1n)))) {89 return x0;90 }91 return newtonIteration(n, x1);92 }9394 return newtonIteration(this, new Fract(1n));95 }96}9798type Op = Fract | '+' | '-' | '*' | '/' | 'dup' | Op[];99function rpn(...ops: (Op)[]) {100 const stack: Fract[] = [];101 for (const op of ops) {102 if (op instanceof Fract) {103 stack.push(op);104 } else if (op === '+') {105 if (stack.length < 2)106 throw new Error('stack underflow');107 const b = stack.pop()!;108 const a = stack.pop()!;109 stack.push(a.plus(b));110 } else if (op === '*') {111 if (stack.length < 2)112 throw new Error('stack underflow');113 const b = stack.pop()!;114 const a = stack.pop()!;115 stack.push(a.mul(b));116 } else if (op === '-') {117 if (stack.length < 2)118 throw new Error('stack underflow');119 const b = stack.pop()!;120 const a = stack.pop()!;121 stack.push(a.minus(b));122 } else if (op === '/') {123 if (stack.length < 2)124 throw new Error('stack underflow');125 const b = stack.pop()!;126 const a = stack.pop()!;127 stack.push(a.div(b));128 } else if (op === 'dup') {129 if (stack.length < 1)130 throw new Error('stack underflow');131 const a = stack.pop()!;132 stack.push(a);133 stack.push(a);134 } else if (Array.isArray(op)) {135 stack.push(rpn(...op));136 } else {137 throw new Error(`unknown operand: ${op}`);138 }139 }140 if (stack.length != 1)141 throw new Error('one element should be left on stack');142 return stack[0]!;143}144145function linearRegression(points: { x: Fract, y: Fract }[]) {146 let sumxy = Fract.ZERO;147 let sumx = Fract.ZERO;148 let sumy = Fract.ZERO;149 let sumx2 = Fract.ZERO;150 const n = points.length;151 for (let i = 0; i < n; i++) {152 const p = points[i];153 sumxy = rpn(p.x, p.y, '*', sumxy, '+');154 sumx = sumx.plus(p.x);155 sumy = sumy.plus(p.y);156 sumx2 = rpn(p.x, p.x, '*', sumx2, '+');157 }158159 const nb = new Fract(BigInt(n));160161 const a = rpn(162 [nb, sumxy, '*', sumx, sumy, '*', '-'],163 [nb, sumx2, '*', sumx, sumx, '*', '-'],164 '/',165 );166 const b = rpn(167 [sumy, a, sumx, '*', '-'],168 nb,169 '/',170 );171172 return {a, b};173}174175const hypothesisLinear = (a: Fract, b: Fract) => (x: Fract) => rpn(x, a, '*', b, '+');176177function _error(points: { x: Fract, y: Fract }[], hypothesis: (a: Fract) => Fract) {178 return points.map(p => {179 const v = hypothesis(p.x);180 const vv = p.y;181182 return rpn(v, vv, '-', 'dup', '*');183 }).reduce((a, b) => a.plus(b), Fract.ZERO).sqrt().div(new Fract(BigInt(points.length)));184}185186async function calibrateWeightToFee(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {187 const alice = await privateKey('//Alice');188 const bob = await privateKey('//Bob');189 const dataPoints = [];190191 {192 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});193 const token = await collection.mintToken(alice, {Substrate: alice.address});194 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);195 await token.transfer(alice, {Substrate: bob.address});196 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);197198 console.log(`\t[NFT transfer] Original price: ${Number(aliceBalanceBefore-aliceBalanceAfter)/Number(helper.balance.getOneTokenNominal())} UNQ`);199 }200201 const api = helper.getApi();202 const base = (await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt();203 for (let i = -5; i < 5; i++) {204 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(base + base / 1000n * BigInt(i))));205206 const coefficient = new Fract((await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt());207 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});208 const token = await collection.mintToken(alice, {Substrate: alice.address});209210 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);211 await token.transfer(alice, {Substrate: bob.address});212 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);213214 const transferPrice = new Fract(aliceBalanceBefore - aliceBalanceAfter);215216 dataPoints.push({x: transferPrice, y: coefficient});217 }218 const {a, b} = linearRegression(dataPoints);219220 const hyp = hypothesisLinear(a, b);221 // console.log(`\t[NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);222223 // 0.1 UNQ224 const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(1n, 10n), '*'));225 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(perfectValue.toBigInt())));226227 {228 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});229 const token = await collection.mintToken(alice, {Substrate: alice.address});230 const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);231 await token.transfer(alice, {Substrate: bob.address});232 const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);233234 console.log(`\t[NFT transfer] Calibrated price: ${Number(aliceBalanceBefore-aliceBalanceAfter)/Number(helper.balance.getOneTokenNominal())} UNQ`);235 }236}237238async function calibrateMinGasPrice(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {239 const alice = await privateKey('//Alice');240 const caller = await helper.eth.createAccountWithBalance(alice);241 const receiver = helper.eth.createAccount();242 const dataPoints = [];243244 {245 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});246 const token = await collection.mintToken(alice, {Ethereum: caller});247248 const address = helper.ethAddress.fromCollectionId(collection.collectionId);249 const contract = helper.ethNativeContract.collection(address, 'nft', caller);250251 const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));252253 console.log(`\t[ETH NFT transfer] Original price: ${Number(cost)/Number(helper.balance.getOneTokenNominal())} UNQ`);254 }255256 const api = helper.getApi();257 // const defaultCoeff = (api.consts.configuration.defaultMinGasPrice as any).toBigInt();258 const base = (await api.query.configuration.minGasPriceOverride() as any).toBigInt();259 for (let i = -8; i < 8; i++) {260 const gasPrice = base + base / 100000n * BigInt(i);261 const gasPriceStr = '0x' + gasPrice.toString(16);262 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(gasPrice)));263264 const coefficient = new Fract((await api.query.configuration.minGasPriceOverride() as any).toBigInt());265 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});266 const token = await collection.mintToken(alice, {Ethereum: caller});267268 const address = helper.ethAddress.fromCollectionId(collection.collectionId);269 const contract = helper.ethNativeContract.collection(address, 'nft', caller);270271 const transferPrice = new Fract(await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gasPrice: gasPriceStr, gas: helper.eth.DEFAULT_GAS})));272273 dataPoints.push({x: transferPrice, y: coefficient});274 }275276 const {a, b} = linearRegression(dataPoints);277278 const hyp = hypothesisLinear(a, b);279 // console.log(`\t[ETH NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);280281 // 0.15 UNQ282 const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(15n, 100n), '*'));283 await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(perfectValue.toBigInt())));284285 {286 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});287 const token = await collection.mintToken(alice, {Ethereum: caller});288289 const address = helper.ethAddress.fromCollectionId(collection.collectionId);290 const contract = helper.ethNativeContract.collection(address, 'nft', caller);291292 const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));293294 console.log(`\t[ETH NFT transfer] Calibrated price: ${Number(cost)/Number(helper.balance.getOneTokenNominal())} UNQ`);295 }296}297298(async () => {299 await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {300 // Subsequent runs reduce error, as price line is not actually straight, this is a curve301302 const iterations = 3;303304 console.log('[Calibrate WeightToFee]');305 for (let i = 0; i < iterations; i++) {306 await calibrateWeightToFee(helper, privateKey);307 }308309 console.log();310311 console.log('[Calibrate MinGasPrice]');312 for (let i = 0; i < iterations; i++) {313 await calibrateMinGasPrice(helper, privateKey);314 }315 });316})();tests/src/eth/ethFeesAreCorrect.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/ethFeesAreCorrect.test.ts
@@ -0,0 +1,66 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://witww.gnu.org/licenses/>.
+
+import {IKeyringPair} from '@polkadot/types/types';
+import {itEth, usingEthPlaygrounds, expect} from './util';
+
+describe('Eth fees are correct', () => {
+ let donor: IKeyringPair;
+ let minter: IKeyringPair;
+ let alice: IKeyringPair;
+
+ before(async () => {
+ await usingEthPlaygrounds(async (helper, privateKey) => {
+ donor = await privateKey({filename: __filename});
+ [minter, alice] = await helper.arrange.createAccounts([100n, 200n], donor);
+ });
+ });
+
+
+ itEth('web3 fees are the same as evm.call fees', async ({helper}) => {
+ const collection = await helper.nft.mintCollection(minter, {});
+
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const receiver = await helper.eth.createAccountWithBalance(donor);
+ const aliceEth = helper.address.substrateToEth(alice.address);
+
+ const {tokenId: tokenA} = await collection.mintToken(minter, {Ethereum: owner});
+ const {tokenId: tokenB} = await collection.mintToken(minter, {Ethereum: aliceEth});
+
+ const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+
+ const balanceBeforeWeb3Transfer = await helper.balance.getEthereum(owner);
+ await contract.methods.transfer(receiver, tokenA).send({from: owner});
+ const balanceAfterWeb3Transfer = await helper.balance.getEthereum(owner);
+ const web3Diff = balanceBeforeWeb3Transfer - balanceAfterWeb3Transfer;
+
+ const encodedCall = contract.methods.transfer(receiver, tokenB)
+ .encodeABI();
+
+ const balanceBeforeEvmCall = await helper.balance.getSubstrate(alice.address);
+ await helper.eth.sendEVM(
+ alice,
+ collectionAddress,
+ encodedCall,
+ '0',
+ );
+ const balanceAfterEvmCall = await helper.balance.getSubstrate(alice.address);
+ const evmCallDiff = balanceBeforeEvmCall - balanceAfterEvmCall;
+
+ expect(web3Diff).to.be.equal(evmCallDiff);
+ });
+});
tests/src/interfaces/augment-api-consts.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-consts.ts
+++ b/tests/src/interfaces/augment-api-consts.ts
@@ -82,7 +82,7 @@
appPromotionDailyRate: Perbill & AugmentedConst<ApiType>;
dayRelayBlocks: u32 & AugmentedConst<ApiType>;
defaultMinGasPrice: u64 & AugmentedConst<ApiType>;
- defaultWeightToFeeCoefficient: u32 & AugmentedConst<ApiType>;
+ defaultWeightToFeeCoefficient: u64 & AugmentedConst<ApiType>;
maxXcmAllowedLocations: u32 & AugmentedConst<ApiType>;
/**
* Generic const
tests/src/interfaces/augment-api-query.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-query.ts
+++ b/tests/src/interfaces/augment-api-query.ts
@@ -162,7 +162,7 @@
configuration: {
appPromomotionConfigurationOverride: AugmentedQuery<ApiType, () => Observable<PalletConfigurationAppPromotionConfiguration>, []> & QueryableStorageEntry<ApiType, []>;
minGasPriceOverride: AugmentedQuery<ApiType, () => Observable<u64>, []> & QueryableStorageEntry<ApiType, []>;
- weightToFeeCoefficientOverride: AugmentedQuery<ApiType, () => Observable<u32>, []> & QueryableStorageEntry<ApiType, []>;
+ weightToFeeCoefficientOverride: AugmentedQuery<ApiType, () => Observable<u64>, []> & QueryableStorageEntry<ApiType, []>;
xcmAllowedLocationsOverride: AugmentedQuery<ApiType, () => Observable<Option<Vec<XcmV1MultiLocation>>>, []> & QueryableStorageEntry<ApiType, []>;
/**
* Generic query
tests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -16,7 +16,7 @@
import type { BlockHash } from '@polkadot/types/interfaces/chain';
import type { PrefixedStorageKey } from '@polkadot/types/interfaces/childstate';
import type { AuthorityId } from '@polkadot/types/interfaces/consensus';
-import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequest } from '@polkadot/types/interfaces/contracts';
+import type { CodeUploadRequest, CodeUploadResult, ContractCallRequest, ContractExecResult, ContractInstantiateResult, InstantiateRequestV1 } from '@polkadot/types/interfaces/contracts';
import type { BlockStats } from '@polkadot/types/interfaces/dev';
import type { CreatedBlock } from '@polkadot/types/interfaces/engine';
import type { EthAccount, EthCallRequest, EthFeeHistory, EthFilter, EthFilterChanges, EthLog, EthReceipt, EthRichBlock, EthSubKind, EthSubParams, EthSyncStatus, EthTransaction, EthTransactionRequest, EthWork } from '@polkadot/types/interfaces/eth';
@@ -24,7 +24,7 @@
import type { EncodedFinalityProofs, JustificationNotification, ReportedRoundStates } from '@polkadot/types/interfaces/grandpa';
import type { MmrLeafBatchProof, MmrLeafProof } from '@polkadot/types/interfaces/mmr';
import type { StorageKind } from '@polkadot/types/interfaces/offchain';
-import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';
+import type { FeeDetails, RuntimeDispatchInfoV1 } from '@polkadot/types/interfaces/payment';
import type { RpcMethods } from '@polkadot/types/interfaces/rpc';
import type { AccountId, AccountId32, BlockNumber, H160, H256, H64, Hash, Header, Index, Justification, KeyValue, SignedBlock, StorageData } from '@polkadot/types/interfaces/runtime';
import type { MigrationStatusResult, ReadProof, RuntimeVersion, TraceBlockResponse } from '@polkadot/types/interfaces/state';
@@ -174,7 +174,7 @@
* @deprecated Use the runtime interface `api.call.contractsApi.instantiate` instead
* Instantiate a new contract
**/
- instantiate: AugmentedRpc<(request: InstantiateRequest | { origin?: any; value?: any; gasLimit?: any; storageDepositLimit?: any; code?: any; data?: any; salt?: any } | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<ContractInstantiateResult>>;
+ instantiate: AugmentedRpc<(request: InstantiateRequestV1 | { origin?: any; value?: any; gasLimit?: any; code?: any; data?: any; salt?: any } | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<ContractInstantiateResult>>;
/**
* @deprecated Not available in newer versions of the contracts interfaces
* Returns the projected time a given contract will be able to sustain paying its rent
@@ -426,13 +426,15 @@
};
payment: {
/**
+ * @deprecated Use `api.call.transactionPaymentApi.queryFeeDetails` instead
* Query the detailed fee of a given encoded extrinsic
**/
queryFeeDetails: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<FeeDetails>>;
/**
+ * @deprecated Use `api.call.transactionPaymentApi.queryInfo` instead
* Retrieves the fee information for an encoded extrinsic
**/
- queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<RuntimeDispatchInfo>>;
+ queryInfo: AugmentedRpc<(extrinsic: Bytes | string | Uint8Array, at?: BlockHash | string | Uint8Array) => Observable<RuntimeDispatchInfoV1>>;
};
rmrk: {
/**
tests/src/interfaces/augment-api-runtime.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-runtime.ts
+++ b/tests/src/interfaces/augment-api-runtime.ts
@@ -6,7 +6,7 @@
import '@polkadot/api-base/types/calls';
import type { ApiTypes, AugmentedCall, DecoratedCallBase } from '@polkadot/api-base/types';
-import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u64 } from '@polkadot/types-codec';
+import type { Bytes, Null, Option, Result, U256, Vec, bool, u256, u32, u64 } from '@polkadot/types-codec';
import type { AnyNumber, ITuple } from '@polkadot/types-codec/types';
import type { CheckInherentsResult, InherentData } from '@polkadot/types/interfaces/blockbuilder';
import type { BlockHash } from '@polkadot/types/interfaces/chain';
@@ -16,6 +16,7 @@
import type { EvmAccount, EvmCallInfo, EvmCreateInfo } from '@polkadot/types/interfaces/evm';
import type { Extrinsic } from '@polkadot/types/interfaces/extrinsics';
import type { OpaqueMetadata } from '@polkadot/types/interfaces/metadata';
+import type { FeeDetails, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';
import type { AccountId, Block, H160, H256, Header, Index, KeyTypeId, Permill, SlotDuration } from '@polkadot/types/interfaces/runtime';
import type { RuntimeVersion } from '@polkadot/types/interfaces/state';
import type { ApplyExtrinsicResult, DispatchError } from '@polkadot/types/interfaces/system';
@@ -228,5 +229,20 @@
**/
[key: string]: DecoratedCallBase<ApiType>;
};
+ /** 0x37c8bb1350a9a2a8/2 */
+ transactionPaymentApi: {
+ /**
+ * The transaction fee details
+ **/
+ queryFeeDetails: AugmentedCall<ApiType, (uxt: Extrinsic | IExtrinsic | string | Uint8Array, len: u32 | AnyNumber | Uint8Array) => Observable<FeeDetails>>;
+ /**
+ * The transaction info
+ **/
+ queryInfo: AugmentedCall<ApiType, (uxt: Extrinsic | IExtrinsic | string | Uint8Array, len: u32 | AnyNumber | Uint8Array) => Observable<RuntimeDispatchInfo>>;
+ /**
+ * Generic call
+ **/
+ [key: string]: DecoratedCallBase<ApiType>;
+ };
} // AugmentedCalls
} // declare module
tests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -217,7 +217,7 @@
configuration: {
setAppPromotionConfigurationOverride: AugmentedSubmittable<(configuration: PalletConfigurationAppPromotionConfiguration | { recalculationInterval?: any; pendingInterval?: any; intervalIncome?: any; maxStakersPerCalculation?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [PalletConfigurationAppPromotionConfiguration]>;
setMinGasPriceOverride: AugmentedSubmittable<(coeff: Option<u64> | null | Uint8Array | u64 | AnyNumber) => SubmittableExtrinsic<ApiType>, [Option<u64>]>;
- setWeightToFeeCoefficientOverride: AugmentedSubmittable<(coeff: Option<u32> | null | Uint8Array | u32 | AnyNumber) => SubmittableExtrinsic<ApiType>, [Option<u32>]>;
+ setWeightToFeeCoefficientOverride: AugmentedSubmittable<(coeff: Option<u64> | null | Uint8Array | u64 | AnyNumber) => SubmittableExtrinsic<ApiType>, [Option<u64>]>;
setXcmAllowedLocations: AugmentedSubmittable<(locations: Option<Vec<XcmV1MultiLocation>> | null | Uint8Array | Vec<XcmV1MultiLocation> | (XcmV1MultiLocation | { parents?: any; interior?: any } | string | Uint8Array)[]) => SubmittableExtrinsic<ApiType>, [Option<Vec<XcmV1MultiLocation>>]>;
/**
* Generic tx
@@ -1432,6 +1432,23 @@
**/
destroyCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
/**
+ * Repairs a collection if the data was somehow corrupted.
+ *
+ * # Arguments
+ *
+ * * `collection_id`: ID of the collection to repair.
+ **/
+ forceRepairCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
+ /**
+ * Repairs a token if the data was somehow corrupted.
+ *
+ * # Arguments
+ *
+ * * `collection_id`: ID of the collection the item belongs to.
+ * * `item_id`: ID of the item.
+ **/
+ forceRepairItem: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32]>;
+ /**
* Remove admin of a collection.
*
* An admin address can remove itself. List of admins may become empty,
@@ -1474,15 +1491,6 @@
* * `address`: ID of the address to be removed from the allowlist.
**/
removeFromAllowList: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, address: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, PalletEvmAccountBasicCrossAccountIdRepr]>;
- /**
- * Repairs a broken item
- *
- * # Arguments
- *
- * * `collection_id`: ID of the collection the item belongs to.
- * * `item_id`: ID of the item.
- **/
- repairItem: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32]>;
/**
* Re-partition a refungible token, while owning all of its parts/pieces.
*
tests/src/interfaces/augment-types.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-types.ts
+++ b/tests/src/interfaces/augment-types.ts
@@ -24,7 +24,7 @@
import type { StatementKind } from '@polkadot/types/interfaces/claims';
import type { CollectiveOrigin, MemberCount, ProposalIndex, Votes, VotesTo230 } from '@polkadot/types/interfaces/collective';
import type { AuthorityId, RawVRFOutput } from '@polkadot/types/interfaces/consensus';
-import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';
+import type { AliveContractInfo, CodeHash, CodeSource, CodeUploadRequest, CodeUploadResult, CodeUploadResultValue, ContractCallFlags, ContractCallRequest, ContractExecResult, ContractExecResultOk, ContractExecResultResult, ContractExecResultSuccessTo255, ContractExecResultSuccessTo260, ContractExecResultTo255, ContractExecResultTo260, ContractExecResultTo267, ContractExecResultU64, ContractInfo, ContractInstantiateResult, ContractInstantiateResultTo267, ContractInstantiateResultTo299, ContractInstantiateResultU64, ContractReturnFlags, ContractStorageKey, DeletedContract, ExecReturnValue, Gas, HostFnWeights, HostFnWeightsTo264, InstantiateRequest, InstantiateRequestV1, InstantiateRequestV2, InstantiateReturnValue, InstantiateReturnValueOk, InstantiateReturnValueTo267, InstructionWeights, Limits, LimitsTo264, PrefabWasmModule, RentProjection, Schedule, ScheduleTo212, ScheduleTo258, ScheduleTo264, SeedOf, StorageDeposit, TombstoneContractInfo, TrieId } from '@polkadot/types/interfaces/contracts';
import type { ContractConstructorSpecLatest, ContractConstructorSpecV0, ContractConstructorSpecV1, ContractConstructorSpecV2, ContractConstructorSpecV3, ContractContractSpecV0, ContractContractSpecV1, ContractContractSpecV2, ContractContractSpecV3, ContractContractSpecV4, ContractCryptoHasher, ContractDiscriminant, ContractDisplayName, ContractEventParamSpecLatest, ContractEventParamSpecV0, ContractEventParamSpecV2, ContractEventSpecLatest, ContractEventSpecV0, ContractEventSpecV1, ContractEventSpecV2, ContractLayoutArray, ContractLayoutCell, ContractLayoutEnum, ContractLayoutHash, ContractLayoutHashingStrategy, ContractLayoutKey, ContractLayoutStruct, ContractLayoutStructField, ContractMessageParamSpecLatest, ContractMessageParamSpecV0, ContractMessageParamSpecV2, ContractMessageSpecLatest, ContractMessageSpecV0, ContractMessageSpecV1, ContractMessageSpecV2, ContractMetadata, ContractMetadataLatest, ContractMetadataV0, ContractMetadataV1, ContractMetadataV2, ContractMetadataV3, ContractMetadataV4, ContractProject, ContractProjectContract, ContractProjectInfo, ContractProjectSource, ContractProjectV0, ContractSelector, ContractStorageLayout, ContractTypeSpec } from '@polkadot/types/interfaces/contractsAbi';
import type { FundIndex, FundInfo, LastContribution, TrieIndex } from '@polkadot/types/interfaces/crowdloan';
import type { CollationInfo, CollationInfoV1, ConfigData, MessageId, OverweightIndex, PageCounter, PageIndexData } from '@polkadot/types/interfaces/cumulus';
@@ -47,7 +47,7 @@
import type { StorageKind } from '@polkadot/types/interfaces/offchain';
import type { DeferredOffenceOf, Kind, OffenceDetails, Offender, OpaqueTimeSlot, ReportIdOf, Reporter } from '@polkadot/types/interfaces/offences';
import type { AbridgedCandidateReceipt, AbridgedHostConfiguration, AbridgedHrmpChannel, AssignmentId, AssignmentKind, AttestedCandidate, AuctionIndex, AuthorityDiscoveryId, AvailabilityBitfield, AvailabilityBitfieldRecord, BackedCandidate, Bidder, BufferedSessionChange, CandidateCommitments, CandidateDescriptor, CandidateEvent, CandidateHash, CandidateInfo, CandidatePendingAvailability, CandidateReceipt, CollatorId, CollatorSignature, CommittedCandidateReceipt, CoreAssignment, CoreIndex, CoreOccupied, CoreState, DisputeLocation, DisputeResult, DisputeState, DisputeStatement, DisputeStatementSet, DoubleVoteReport, DownwardMessage, ExplicitDisputeStatement, GlobalValidationData, GlobalValidationSchedule, GroupIndex, GroupRotationInfo, HeadData, HostConfiguration, HrmpChannel, HrmpChannelId, HrmpOpenChannelRequest, InboundDownwardMessage, InboundHrmpMessage, InboundHrmpMessages, IncomingParachain, IncomingParachainDeploy, IncomingParachainFixed, InvalidDisputeStatementKind, LeasePeriod, LeasePeriodOf, LocalValidationData, MessageIngestionType, MessageQueueChain, MessagingStateSnapshot, MessagingStateSnapshotEgressEntry, MultiDisputeStatementSet, NewBidder, OccupiedCore, OccupiedCoreAssumption, OldV1SessionInfo, OutboundHrmpMessage, ParaGenesisArgs, ParaId, ParaInfo, ParaLifecycle, ParaPastCodeMeta, ParaScheduling, ParaValidatorIndex, ParachainDispatchOrigin, ParachainInherentData, ParachainProposal, ParachainsInherentData, ParathreadClaim, ParathreadClaimQueue, ParathreadEntry, PersistedValidationData, PvfCheckStatement, QueuedParathread, RegisteredParachainInfo, RelayBlockNumber, RelayChainBlockNumber, RelayChainHash, RelayHash, Remark, ReplacementTimes, Retriable, ScheduledCore, Scheduling, ScrapedOnChainVotes, ServiceQuality, SessionInfo, SessionInfoValidatorGroup, SignedAvailabilityBitfield, SignedAvailabilityBitfields, SigningContext, SlotRange, SlotRange10, Statement, SubId, SystemInherentData, TransientValidationData, UpgradeGoAhead, UpgradeRestriction, UpwardMessage, ValidDisputeStatementKind, ValidationCode, ValidationCodeHash, ValidationData, ValidationDataType, ValidationFunctionParams, ValidatorSignature, ValidityAttestation, VecInboundHrmpMessage, WinnersData, WinnersData10, WinnersDataTuple, WinnersDataTuple10, WinningData, WinningData10, WinningDataEntry } from '@polkadot/types/interfaces/parachains';
-import type { FeeDetails, InclusionFee, RuntimeDispatchInfo } from '@polkadot/types/interfaces/payment';
+import type { FeeDetails, InclusionFee, RuntimeDispatchInfo, RuntimeDispatchInfoV1, RuntimeDispatchInfoV2 } from '@polkadot/types/interfaces/payment';
import type { Approvals } from '@polkadot/types/interfaces/poll';
import type { ProxyAnnouncement, ProxyDefinition, ProxyType } from '@polkadot/types/interfaces/proxy';
import type { AccountStatus, AccountValidity } from '@polkadot/types/interfaces/purchase';
@@ -273,10 +273,12 @@
ContractExecResultTo255: ContractExecResultTo255;
ContractExecResultTo260: ContractExecResultTo260;
ContractExecResultTo267: ContractExecResultTo267;
+ ContractExecResultU64: ContractExecResultU64;
ContractInfo: ContractInfo;
ContractInstantiateResult: ContractInstantiateResult;
ContractInstantiateResultTo267: ContractInstantiateResultTo267;
ContractInstantiateResultTo299: ContractInstantiateResultTo299;
+ ContractInstantiateResultU64: ContractInstantiateResultU64;
ContractLayoutArray: ContractLayoutArray;
ContractLayoutCell: ContractLayoutCell;
ContractLayoutEnum: ContractLayoutEnum;
@@ -1057,6 +1059,8 @@
RpcMethods: RpcMethods;
RuntimeDbWeight: RuntimeDbWeight;
RuntimeDispatchInfo: RuntimeDispatchInfo;
+ RuntimeDispatchInfoV1: RuntimeDispatchInfoV1;
+ RuntimeDispatchInfoV2: RuntimeDispatchInfoV2;
RuntimeVersion: RuntimeVersion;
RuntimeVersionApi: RuntimeVersionApi;
RuntimeVersionPartial: RuntimeVersionPartial;
tests/src/interfaces/default/types.tsdiffbeforeafterboth--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1303,7 +1303,7 @@
export interface PalletConfigurationCall extends Enum {
readonly isSetWeightToFeeCoefficientOverride: boolean;
readonly asSetWeightToFeeCoefficientOverride: {
- readonly coeff: Option<u32>;
+ readonly coeff: Option<u64>;
} & Struct;
readonly isSetMinGasPriceOverride: boolean;
readonly asSetMinGasPriceOverride: {
@@ -2319,12 +2319,16 @@
readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
readonly approve: bool;
} & Struct;
- readonly isRepairItem: boolean;
- readonly asRepairItem: {
+ readonly isForceRepairCollection: boolean;
+ readonly asForceRepairCollection: {
+ readonly collectionId: u32;
+ } & Struct;
+ readonly isForceRepairItem: boolean;
+ readonly asForceRepairItem: {
readonly collectionId: u32;
readonly itemId: u32;
} & Struct;
- readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetAllowanceForAll' | 'RepairItem';
+ readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetAllowanceForAll' | 'ForceRepairCollection' | 'ForceRepairItem';
}
/** @name PalletUniqueError */
tests/src/interfaces/lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -2282,8 +2282,11 @@
operator: 'PalletEvmAccountBasicCrossAccountIdRepr',
approve: 'bool',
},
- repair_item: {
+ force_repair_collection: {
collectionId: 'u32',
+ },
+ force_repair_item: {
+ collectionId: 'u32',
itemId: 'u32'
}
}
@@ -2452,7 +2455,7 @@
PalletConfigurationCall: {
_enum: {
set_weight_to_fee_coefficient_override: {
- coeff: 'Option<u32>',
+ coeff: 'Option<u64>',
},
set_min_gas_price_override: {
coeff: 'Option<u64>',
tests/src/interfaces/types-lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -2517,12 +2517,16 @@
readonly operator: PalletEvmAccountBasicCrossAccountIdRepr;
readonly approve: bool;
} & Struct;
- readonly isRepairItem: boolean;
- readonly asRepairItem: {
+ readonly isForceRepairCollection: boolean;
+ readonly asForceRepairCollection: {
+ readonly collectionId: u32;
+ } & Struct;
+ readonly isForceRepairItem: boolean;
+ readonly asForceRepairItem: {
readonly collectionId: u32;
readonly itemId: u32;
} & Struct;
- readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetAllowanceForAll' | 'RepairItem';
+ readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition' | 'SetAllowanceForAll' | 'ForceRepairCollection' | 'ForceRepairItem';
}
/** @name UpDataStructsCollectionMode (237) */
@@ -2675,7 +2679,7 @@
interface PalletConfigurationCall extends Enum {
readonly isSetWeightToFeeCoefficientOverride: boolean;
readonly asSetWeightToFeeCoefficientOverride: {
- readonly coeff: Option<u32>;
+ readonly coeff: Option<u64>;
} & Struct;
readonly isSetMinGasPriceOverride: boolean;
readonly asSetMinGasPriceOverride: {
tests/src/nesting/collectionProperties.test.tsdiffbeforeafterboth--- a/tests/src/nesting/collectionProperties.test.ts
+++ b/tests/src/nesting/collectionProperties.test.ts
@@ -209,7 +209,7 @@
before(async () => {
await usingPlaygrounds(async (helper, privateKey) => {
const donor = await privateKey({filename: __filename});
- [alice, bob] = await helper.arrange.createAccounts([100n, 10n], donor);
+ [alice, bob] = await helper.arrange.createAccounts([1000n, 100n], donor);
});
});