git.delta.rocks / unique-network / refs/commits / 386b66a0b7e2

difftreelog

test fix for new ouroboros behavior

Yaroslav Bolyukin2022-05-11parent: #2934957.patch.diff
in: master

4 files changed

modifiedcrates/struct-versioning/src/lib.rsdiffbeforeafterboth
--- a/crates/struct-versioning/src/lib.rs
+++ b/crates/struct-versioning/src/lib.rs
@@ -199,7 +199,7 @@
 	let mut out = Vec::new();
 	for version in attr.first_version..=attr.current_version {
 		let name = if version == attr.current_version {
-			input.ident.clone()	
+			input.ident.clone()
 		} else {
 			format_ident!("{}Version{}", &input.ident, version)
 		};
modifiedtests/src/nesting/unnest.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/unnest.test.ts
+++ b/tests/src/nesting/unnest.test.ts
@@ -4,14 +4,13 @@
 import usingApi, {executeTransaction} from '../substrate/substrate-api';
 import {
   createCollectionExpectSuccess,
-  createItemExpectFailure, 
+  createItemExpectFailure,
   createItemExpectSuccess,
-  getTokenOwner, 
-  getTopmostTokenOwner, 
-  normalizeAccountId, 
-  setCollectionLimitsExpectSuccess, 
-  transferExpectFailure, 
-  transferExpectSuccess, 
+  getTokenOwner,
+  getTopmostTokenOwner,
+  normalizeAccountId,
+  setCollectionLimitsExpectSuccess,
+  transferExpectSuccess,
 } from '../util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
 
@@ -36,8 +35,8 @@
 
       // Unnest
       await expect(executeTransaction(
-        api, 
-        alice, 
+        api,
+        alice,
         api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(alice), collection, nestedToken, 1),
       )).to.not.be.rejected;
       expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});
@@ -45,8 +44,8 @@
       // Nest and burn
       await transferExpectSuccess(collection, nestedToken, alice, targetAddress);
       await expect(executeTransaction(
-        api, 
-        alice, 
+        api,
+        alice,
         api.tx.unique.burnFrom(collection, normalizeAccountId(alice.address), nestedToken, 1),
       )).to.not.be.rejected;
       await expect(getTokenOwner(api, collection, nestedToken)).to.be.rejected; // 'owner == null'
@@ -61,7 +60,7 @@
     alice = privateKey('//Alice');
     bob = privateKey('//Bob');
   });
-  
+
   it('Disallows a non-owner to unnest/burn a token', async () => {
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
@@ -74,8 +73,8 @@
 
       // Try to unnest
       await expect(executeTransaction(
-        api, 
-        bob, 
+        api,
+        bob,
         api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(bob), collection, nestedToken, 1),
       )).to.be.rejectedWith(/^common\.ApprovedValueTooLow$/);
       //await transferFromExpectSuccess(collection, nestedToken, bob, targetAddress, {Substrate: bob.address});
@@ -83,14 +82,14 @@
 
       // Try to burn
       await expect(executeTransaction(
-        api, 
-        bob, 
+        api,
+        bob,
         api.tx.unique.burnFrom(collection, normalizeAccountId(bob.address), nestedToken, 1),
       )).to.not.be.rejectedWith(/^common\.ApprovedValueTooLow$/);
       expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});
     });
   });
-  
+
   it('Disallows excessive token nesting', async () => {
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
@@ -108,23 +107,15 @@
   });
 
   // todo another test for creating excessive depth matryoshka with Ethereum, move this one to nest ^
-  
-  // Recursive nesting
-  it('Prevents Ouroboros-nested operations', async () => { 
-    await usingApi(async api => {
-      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});
-      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');
 
-      // Create a nested token ouroboros
-      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});
-      await transferExpectSuccess(collection, targetToken, alice, {Ethereum: tokenIdToAddress(collection, nestedToken)});
-
-      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});
+  // Recursive nesting
+  it('Prevents ouroboros creation', async () => {
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});
+    const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');
 
-      // Make sure the ouroboros is detected
-      await expect(getTopmostTokenOwner(api, collection, nestedToken)).to.be.rejected; // With(/^common\.DepthLimit$/);
-      // todo transferFrom, must exit with Ouroboros error
-    });
+    // Create a nested token ouroboros
+    const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});
+    expect(transferExpectSuccess(collection, targetToken, alice, {Ethereum: tokenIdToAddress(collection, nestedToken)})).to.be.rejectedWith(/^structure\.OuroborosDetected$/);
   });
-});
\ No newline at end of file
+});
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -30,6 +30,7 @@
   'timestamp',
   'transactionpayment',
   'treasury',
+  'structure',
   'system',
   'vesting',
   'parachainsystem',
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
17import '../interfaces/augment-api-rpc';17import '../interfaces/augment-api-rpc';
18import '../interfaces/augment-api-query';18import '../interfaces/augment-api-query';
19import {ApiPromise, Keyring} from '@polkadot/api';19import {ApiPromise, Keyring} from '@polkadot/api';
20import type {AccountId, EventRecord} from '@polkadot/types/interfaces';20import type {AccountId, EventRecord, Event} from '@polkadot/types/interfaces';
21import {IKeyringPair} from '@polkadot/types/types';21import {AnyTuple, IEvent, IKeyringPair} from '@polkadot/types/types';
22import {evmToAddress} from '@polkadot/util-crypto';22import {evmToAddress} from '@polkadot/util-crypto';
23import BN from 'bn.js';23import BN from 'bn.js';
24import chai from 'chai';24import chai from 'chai';
25import chaiAsPromised from 'chai-as-promised';25import chaiAsPromised from 'chai-as-promised';
26import {alicesPublicKey} from '../accounts';26import {alicesPublicKey} from '../accounts';
27import privateKey from '../substrate/privateKey';27import privateKey from '../substrate/privateKey';
28import {default as usingApi, submitTransactionAsync, submitTransactionExpectFailAsync} from '../substrate/substrate-api';28import {default as usingApi, executeTransaction, submitTransactionAsync, submitTransactionExpectFailAsync} from '../substrate/substrate-api';
29import {hexToStr, strToUTF16, utf16ToStr} from './util';29import {hexToStr, strToUTF16, utf16ToStr} from './util';
30import {UpDataStructsRpcCollection} from '@polkadot/types/lookup';30import {UpDataStructsRpcCollection} from '@polkadot/types/lookup';
3131
105}105}
106106
107interface TransferResult {107interface TransferResult {
108 success: boolean;
109 collectionId: number;108 collectionId: number;
110 itemId: number;109 itemId: number;
111 sender?: CrossAccountId;110 sender?: CrossAccountId;
168 return result;167 return result;
169}168}
169
170export function getEvent<T extends Event>(events: EventRecord[], check: (event: IEvent<AnyTuple>) => event is T): T | undefined {
171 const event = events.find(r => check(r.event));
172 if (!event) return;
173 return event.event as T;
174}
170175
171export function getGenericResult(events: EventRecord[]): GenericResult {176export function getGenericResult(events: EventRecord[]): GenericResult {
172 const result: GenericResult = {177 const result: GenericResult = {
225 return result;230 return result;
226}231}
227232
228export function getTransferResult(events: EventRecord[]): TransferResult {233export function getTransferResult(api: ApiPromise, events: EventRecord[]): TransferResult {
229 const result: TransferResult = {234 for (const {event} of events) {
230 success: false,
231 collectionId: 0,
232 itemId: 0,
233 value: 0n,
234 };
235
236 events.forEach(({event: {data, method, section}}) => {
237 if (method === 'ExtrinsicSuccess') {235 if (api.events.common.Transfer.is(event)) {
238 result.success = true;236 const [collection, token, sender, recipient, value] = event.data;
239 } else if (section === 'common' && method === 'Transfer') {237 return {
240 result.collectionId = +data[0].toString();238 collectionId: collection.toNumber(),
241 result.itemId = +data[1].toString();239 itemId: token.toNumber(),
242 result.sender = normalizeAccountId(data[2].toJSON() as any);240 sender: normalizeAccountId(sender.toJSON() as any),
243 result.recipient = normalizeAccountId(data[3].toJSON() as any);241 recipient: normalizeAccountId(recipient.toJSON() as any),
244 result.value = BigInt(data[4].toString());242 value: value.toBigInt(),
245 }243 };
244 }
246 });245 }
247
248 return result;246 throw new Error('no transfer event');
249}247}
250248
251interface Nft {249interface Nft {
912 balanceBefore = await getBalance(api, collectionId, to, tokenId);910 balanceBefore = await getBalance(api, collectionId, to, tokenId);
913 }911 }
914 const transferTx = api.tx.unique.transfer(to, collectionId, tokenId, value);912 const transferTx = api.tx.unique.transfer(to, collectionId, tokenId, value);
915 const events = await submitTransactionAsync(sender, transferTx);913 const events = await executeTransaction(api, sender, transferTx);
914
916 const result = getTransferResult(events);915 const result = getTransferResult(api, events);
917 // tslint:disable-next-line:no-unused-expression
918 expect(result.success).to.be.true;
919 expect(result.collectionId).to.be.equal(collectionId);916 expect(result.collectionId).to.be.equal(collectionId);
920 expect(result.itemId).to.be.equal(tokenId);917 expect(result.itemId).to.be.equal(tokenId);
921 expect(result.sender).to.be.deep.equal(normalizeAccountId(sender.address));918 expect(result.sender).to.be.deep.equal(normalizeAccountId(sender.address));