Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bdf9f7d
Allow to mint with the pre-signed signatures
Jan 12, 2023
320582d
Another try
Jan 12, 2023
a92dc15
WIP: test encoder
Jan 13, 2023
124d872
Fix the deposits
Jan 17, 2023
bb91166
Refactoring + tests + benchmarks
Jan 17, 2023
9f7e563
Add sp-core/runtime-benchmarks
Jan 17, 2023
a4c7e79
Remove sp-core from dev deps
Jan 17, 2023
09f86aa
Enable full_crypto for benchmarks
Jan 17, 2023
dc9ff18
Typo
Jan 20, 2023
55eeb12
Fix
Jan 21, 2023
e8ea9ec
Update frame/nfts/src/mock.rs
jsidorenko Jan 21, 2023
5f27ced
Merge branch 'master' of https://github.com/paritytech/substrate into…
Jan 21, 2023
62edf5f
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_nfts
Jan 21, 2023
b119156
Add docs
Jan 22, 2023
781f834
Add attributes into the pre-signed object & track the deposit owner f…
Jan 31, 2023
839c37c
Update docs
Jan 31, 2023
4980270
Merge branch 'master' into js/offchain-mint
Jan 31, 2023
c2d7c99
Merge branch 'master' of https://github.com/paritytech/substrate into…
Jan 31, 2023
7120dd0
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_nfts
Jan 31, 2023
088dddd
Add the number of attributes provided to weights
Jan 31, 2023
ad7b0e1
Merge branch 'master' into js/offchain-mint
Feb 1, 2023
603a194
Support pre-signed attributes
Feb 1, 2023
30b26a7
Update docs
Feb 2, 2023
22c176d
Merge branch 'master' into js/offchain-attributes
Feb 14, 2023
2c43623
Fix merge artifacts
Feb 14, 2023
1a9fdee
Update docs
Feb 15, 2023
2056b91
Add more tests
Feb 15, 2023
d519049
Merge branch 'master' of https://github.com/paritytech/substrate into…
Feb 15, 2023
0032b2e
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_nfts
Feb 15, 2023
5e81316
Update frame/nfts/src/types.rs
jsidorenko Feb 22, 2023
72bcea2
Update types.rs
jsidorenko Feb 22, 2023
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
Prev Previous commit
Next Next commit
Fix merge artifacts
  • Loading branch information
Jegor Sidorenko committed Feb 14, 2023
commit 2c43623307d7e8bf903b4ebfd60ad3091ce6c05e
16 changes: 7 additions & 9 deletions frame/nfts/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,15 +775,13 @@ benchmarks_instance_pallet! {

set_attributes_pre_signed {
let n in 0 .. T::MaxAttributesPerCall::get() as u32;
let (collection, caller, _) = create_collection::<T, I>();
let (collection, _, _) = create_collection::<T, I>();

let item_owner: T::AccountId = account("item_owner", 0, SEED);
let item_owner_lookup = T::Lookup::unlookup(item_owner.clone());

let account_public = sr25519_generate(0.into(), None);
let account_signer = MultiSigner::Sr25519(account_public);
let account = Nfts::<T, I>::signer_to_account(account_signer.clone()).unwrap();
let account_lookup = T::Lookup::unlookup(account.clone());
let signer_public = sr25519_generate(0.into(), None);
let signer: T::AccountId = MultiSigner::Sr25519(signer_public).into_account().into();

T::Currency::make_free_balance_be(&item_owner, DepositBalanceOf::<T, I>::max_value());

Expand All @@ -806,20 +804,20 @@ benchmarks_instance_pallet! {
collection,
item,
attributes,
namespace: AttributeNamespace::Account(account.clone()),
namespace: AttributeNamespace::Account(signer.clone()),
deadline: One::one(),
};
let message = Encode::encode(&pre_signed_data);
let signature = MultiSignature::Sr25519(sr25519_sign(0.into(), &account_public, &message).unwrap());
let signature = MultiSignature::Sr25519(sr25519_sign(0.into(), &signer_public, &message).unwrap());

frame_system::Pallet::<T>::set_block_number(One::one());
}: _(SystemOrigin::Signed(item_owner.clone()), pre_signed_data, signature, account_signer)
}: _(SystemOrigin::Signed(item_owner.clone()), pre_signed_data, signature.into(), signer.clone())
verify {
assert_last_event::<T, I>(
Event::PreSignedAttributesSet {
collection,
item,
namespace: AttributeNamespace::Account(account.clone()),
namespace: AttributeNamespace::Account(signer.clone()),
}
.into(),
);
Expand Down
12 changes: 4 additions & 8 deletions frame/nfts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1850,17 +1850,13 @@ pub mod pallet {
pub fn set_attributes_pre_signed(
origin: OriginFor<T>,
data: PreSignedAttributesOf<T, I>,
signature: MultiSignature,
signer: MultiSigner,
signature: T::OffchainSignature,
signer: T::AccountId,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let msg = Encode::encode(&data);
ensure!(
signature.verify(&*msg, &signer.clone().into_account()),
Error::<T, I>::WrongSignature
);
let signer_account = Self::signer_to_account(signer)?;
Self::do_set_attributes_pre_signed(origin, data, signer_account)
ensure!(signature.verify(&*msg, &signer), Error::<T, I>::WrongSignature);
Self::do_set_attributes_pre_signed(origin, data, signer)
}
}
}
Expand Down
72 changes: 39 additions & 33 deletions frame/nfts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3182,23 +3182,29 @@ fn pre_signed_attributes_should_work() {
new_test_ext().execute_with(|| {
let user_1_pair = sp_core::sr25519::Pair::from_string("//Alice", None).unwrap();
let user_1_signer = MultiSigner::Sr25519(user_1_pair.public());
let user_1 = Nfts::signer_to_account(user_1_signer.clone()).unwrap();
let user_2 = 2;
let user_1 = user_1_signer.clone().into_account();
let user_2 = account(2);
let user_3_pair = sp_core::sr25519::Pair::from_string("//Bob", None).unwrap();
let user_3_signer = MultiSigner::Sr25519(user_3_pair.public());
let user_3 = Nfts::signer_to_account(user_3_signer.clone()).unwrap();
let user_3 = user_3_signer.clone().into_account();
let collection_id = 0;
let item_id = 0;

Balances::make_free_balance_be(&user_1, 100);
Balances::make_free_balance_be(&user_2, 100);
Balances::make_free_balance_be(&user_3, 100);
assert_ok!(Nfts::create(
RuntimeOrigin::signed(user_1),
user_1,
RuntimeOrigin::signed(user_1.clone()),
user_1.clone(),
collection_config_with_all_settings_enabled(),
));
assert_ok!(Nfts::mint(RuntimeOrigin::signed(user_1), collection_id, item_id, user_2, None));
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(user_1.clone()),
collection_id,
item_id,
user_2.clone(),
None,
));

// validate the CollectionOwner namespace
let pre_signed_data = PreSignedAttributes {
Expand All @@ -3212,10 +3218,10 @@ fn pre_signed_attributes_should_work() {
let signature = MultiSignature::Sr25519(user_1_pair.sign(&message));

assert_ok!(Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_1_signer.clone(),
user_1.clone(),
));

assert_eq!(
Expand All @@ -3233,15 +3239,15 @@ fn pre_signed_attributes_should_work() {
&attribute_key,
))
.unwrap();
assert_eq!(deposit.account, Some(user_2));
assert_eq!(deposit.account, Some(user_2.clone()));
assert_eq!(deposit.amount, 3);

assert_eq!(Balances::free_balance(&user_1), 100 - 2 - 1); // 2 - collection deposit, 1 - item deposit
assert_eq!(Balances::free_balance(&user_2), 100 - 6); // 6 - attributes

// validate the deposit gets returned on attribute update from collection's owner
assert_ok!(Nfts::set_attribute(
RuntimeOrigin::signed(user_1),
RuntimeOrigin::signed(user_1.clone()),
collection_id,
Some(item_id),
AttributeNamespace::CollectionOwner,
Expand All @@ -3263,60 +3269,60 @@ fn pre_signed_attributes_should_work() {
collection: 0,
item: 0,
attributes: vec![(vec![0], vec![1]), (vec![2], vec![3])],
namespace: AttributeNamespace::Account(user_3),
namespace: AttributeNamespace::Account(user_3.clone()),
deadline: 10000000,
};
let message = Encode::encode(&pre_signed_data);
let signature = MultiSignature::Sr25519(user_3_pair.sign(&message));

assert_ok!(Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_3_signer.clone(),
user_3.clone(),
));

assert_eq!(
attributes(0),
vec![
(Some(0), AttributeNamespace::CollectionOwner, bvec![0], bvec![1]),
(Some(0), AttributeNamespace::Account(user_3), bvec![0], bvec![1]),
(Some(0), AttributeNamespace::Account(user_3.clone()), bvec![0], bvec![1]),
(Some(0), AttributeNamespace::CollectionOwner, bvec![2], bvec![3]),
(Some(0), AttributeNamespace::Account(user_3), bvec![2], bvec![3]),
(Some(0), AttributeNamespace::Account(user_3.clone()), bvec![2], bvec![3]),
]
);

let attribute_key: BoundedVec<_, _> = bvec![0];
let (_, deposit) = Attribute::<Test>::get((
0,
Some(0),
AttributeNamespace::Account(user_3),
AttributeNamespace::Account(user_3.clone()),
&attribute_key,
))
.unwrap();
assert_eq!(deposit.account, Some(user_2));
assert_eq!(deposit.account, Some(user_2.clone()));
assert_eq!(deposit.amount, 3);

assert_eq!(Balances::free_balance(&user_2), 100 - 9);
assert_eq!(Balances::free_balance(&user_3), 100);

// validate the deposit gets returned on attribute update from user_3
assert_ok!(Nfts::set_attribute(
RuntimeOrigin::signed(user_3),
RuntimeOrigin::signed(user_3.clone()),
collection_id,
Some(item_id),
AttributeNamespace::Account(user_3),
AttributeNamespace::Account(user_3.clone()),
bvec![0],
bvec![1],
));
let (_, deposit) = Attribute::<Test>::get((
0,
Some(0),
AttributeNamespace::Account(user_3),
AttributeNamespace::Account(user_3.clone()),
&attribute_key,
))
.unwrap();
assert_eq!(deposit.account, Some(user_3));
assert_eq!(deposit.account, Some(user_3.clone()));
assert_eq!(deposit.amount, 3);

assert_eq!(Balances::free_balance(&user_2), 100 - 6);
Expand All @@ -3325,21 +3331,21 @@ fn pre_signed_attributes_should_work() {
// can't update with the wrong signature
assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_1_signer.clone(),
user_1.clone(),
),
Error::<Test>::WrongSignature
);

// can't update if I don't own that item
assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_3),
RuntimeOrigin::signed(user_3.clone()),
pre_signed_data.clone(),
signature.clone(),
user_3_signer.clone(),
user_3.clone(),
),
Error::<Test>::NoPermission
);
Expand All @@ -3358,10 +3364,10 @@ fn pre_signed_attributes_should_work() {

assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_3_signer.clone(),
user_3.clone(),
),
Error::<Test>::NoPermission
);
Expand All @@ -3370,10 +3376,10 @@ fn pre_signed_attributes_should_work() {
System::set_block_number(10000001);
assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_3_signer.clone(),
user_3.clone(),
),
Error::<Test>::DeadlineExpired
);
Expand All @@ -3392,10 +3398,10 @@ fn pre_signed_attributes_should_work() {

assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_1_signer.clone(),
user_1.clone(),
),
Error::<Test>::UnknownItem
);
Expand All @@ -3413,10 +3419,10 @@ fn pre_signed_attributes_should_work() {

assert_noop!(
Nfts::set_attributes_pre_signed(
RuntimeOrigin::signed(user_2),
RuntimeOrigin::signed(user_2.clone()),
pre_signed_data.clone(),
signature.clone(),
user_1_signer.clone(),
user_1.clone(),
),
Error::<Test>::MaxAttributesLimitReached
);
Expand Down