From f5d9c56df1510addbcfe7cb700dd4c4f99ab2c1a Mon Sep 17 00:00:00 2001 From: ut-akuznetsov <59873862+ut-akuznetsov@users.noreply.github.com> Date: Thu, 15 Dec 2022 11:36:40 +0000 Subject: [PATCH] Merge pull request #777 from UniqueNetwork/fix/recompute_consumed_space Fix/recompute consumed space --- --- a/primitives/data-structs/src/lib.rs +++ b/primitives/data-structs/src/lib.rs @@ -1328,10 +1328,15 @@ return Err(PropertiesError::NoSpaceForProperty); } + let value_len = value_len as u32; let old_value = self.map.try_scoped_set(scope, key, value)?; - if old_value.is_none() { - self.consumed_space += value_len as u32; + let old_value_len = old_value.as_ref().map(|v| v.len() as u32).unwrap_or(0); + + if value_len > old_value_len { + self.consumed_space += value_len - old_value_len; + } else { + self.consumed_space -= old_value_len - value_len; } Ok(old_value) --- a/tests/src/nesting/collectionProperties.test.ts +++ b/tests/src/nesting/collectionProperties.test.ts @@ -25,7 +25,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([200n, 10n], donor); }); }); @@ -138,7 +138,7 @@ {mode: 'nft' as const, requiredPallets: []}, {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, ].map(testCase => - itSub.ifWithPallets(`Allows modifying a collection property multiple times (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { + itSub.ifWithPallets(`Allows modifying a collection property multiple times with the same size (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { const propKey = 'tok-prop'; const collection = await helper[testCase.mode].mintCollection(alice); @@ -191,6 +191,45 @@ consumedSpace = await collection.getPropertiesConsumedSpace(); expect(consumedSpace).to.be.equal(originalSpace); })); + + [ + // TODO enable properties for FT collection in Substrate (release 040) + // {mode: 'ft' as const, requiredPallets: []}, + {mode: 'nft' as const, requiredPallets: []}, + {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]}, + ].map(testCase => + itSub.ifWithPallets(`Modifying a collection property with different sizes correctly changes the consumed space (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { + const propKey = 'tok-prop'; + + const collection = await helper[testCase.mode].mintCollection(alice); + const originalSpace = await collection.getPropertiesConsumedSpace(); + + const initPropDataSize = 4096; + const biggerPropDataSize = 5000; + const smallerPropDataSize = 4000; + + const initPropData = 'a'.repeat(initPropDataSize); + const biggerPropData = 'b'.repeat(biggerPropDataSize); + const smallerPropData = 'c'.repeat(smallerPropDataSize); + + let consumedSpace; + let expectedConsumedSpaceDiff; + + await collection.setProperties(alice, [{key: propKey, value: initPropData}]); + consumedSpace = await collection.getPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = initPropDataSize - originalSpace; + expect(consumedSpace).to.be.equal(originalSpace + expectedConsumedSpaceDiff); + + await collection.setProperties(alice, [{key: propKey, value: biggerPropData}]); + consumedSpace = await collection.getPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = biggerPropDataSize - initPropDataSize; + expect(consumedSpace).to.be.equal(initPropDataSize + expectedConsumedSpaceDiff); + + await collection.setProperties(alice, [{key: propKey, value: smallerPropData}]); + consumedSpace = await collection.getPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = biggerPropDataSize - smallerPropDataSize; + expect(consumedSpace).to.be.equal(biggerPropDataSize - expectedConsumedSpaceDiff); + })); }); describe('Negative Integration Test: Collection Properties', () => { --- a/tests/src/nesting/tokenProperties.test.ts +++ b/tests/src/nesting/tokenProperties.test.ts @@ -325,7 +325,7 @@ {mode: 'nft' as const, storage: 'nonfungible' as const, pieces: undefined, requiredPallets: []}, {mode: 'rft' as const, storage: 'refungible' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, ].map(testCase => - itSub.ifWithPallets(`Allows modifying a token property multiple times (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { + itSub.ifWithPallets(`Allows modifying a token property multiple times with the same size (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { const propKey = 'tok-prop'; const collection = await helper[testCase.mode].mintCollection(alice, { @@ -434,6 +434,55 @@ const recomputedSpace = await token.getTokenPropertiesConsumedSpace(); expect(recomputedSpace).to.be.equal(originalSpace); })); + + [ + {mode: 'nft' as const, pieces: undefined, requiredPallets: []}, + {mode: 'rft' as const, pieces: 100n, requiredPallets: [Pallets.ReFungible]}, + ].map(testCase => + itSub.ifWithPallets(`Modifying a token property with different sizes correctly changes the consumed space (${testCase.mode})`, testCase.requiredPallets, async({helper}) => { + const propKey = 'tok-prop'; + + const collection = await helper[testCase.mode].mintCollection(alice, { + tokenPropertyPermissions: [ + { + key: propKey, + permission: {mutable: true, tokenOwner: true}, + }, + ], + }); + const token = await ( + testCase.pieces + ? collection.mintToken(alice, testCase.pieces) + : collection.mintToken(alice) + ); + const originalSpace = await token.getTokenPropertiesConsumedSpace(); + + const initPropDataSize = 4096; + const biggerPropDataSize = 5000; + const smallerPropDataSize = 4000; + + const initPropData = 'a'.repeat(initPropDataSize); + const biggerPropData = 'b'.repeat(biggerPropDataSize); + const smallerPropData = 'c'.repeat(smallerPropDataSize); + + let consumedSpace; + let expectedConsumedSpaceDiff; + + await token.setProperties(alice, [{key: propKey, value: initPropData}]); + consumedSpace = await token.getTokenPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = initPropDataSize - originalSpace; + expect(consumedSpace).to.be.equal(originalSpace + expectedConsumedSpaceDiff); + + await token.setProperties(alice, [{key: propKey, value: biggerPropData}]); + consumedSpace = await token.getTokenPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = biggerPropDataSize - initPropDataSize; + expect(consumedSpace).to.be.equal(initPropDataSize + expectedConsumedSpaceDiff); + + await token.setProperties(alice, [{key: propKey, value: smallerPropData}]); + consumedSpace = await token.getTokenPropertiesConsumedSpace(); + expectedConsumedSpaceDiff = biggerPropDataSize - smallerPropDataSize; + expect(consumedSpace).to.be.equal(biggerPropDataSize - expectedConsumedSpaceDiff); + })); }); describe('Negative Integration Test: Token Properties', () => { -- gitstuff