From e4147843f1235010d13ee04968b040b7933fd99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Fri, 21 Nov 2025 02:55:15 +0000 Subject: [PATCH 1/7] Fix oversized preimage test --- packages/shared/src/preimage.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/preimage.ts b/packages/shared/src/preimage.ts index b52afc63b..2eaae4070 100644 --- a/packages/shared/src/preimage.ts +++ b/packages/shared/src/preimage.ts @@ -709,7 +709,8 @@ async function preimageOversizedTest< // 1. Alice registers an oversized preimage (more than 4 MB). const maxPreimageSize = 4 * 1024 * 1024 - const oversizedBytes = new Uint8Array(maxPreimageSize + 1).fill(1) + const oversizedBytesArray = Array(maxPreimageSize + 1).fill(1) + const oversizedBytes = client.api.createType('Bytes', oversizedBytesArray) console.info(`Image of size ${oversizedBytes.length} has hash: ${blake2AsHex(oversizedBytes, 256)}`) @@ -719,12 +720,10 @@ async function preimageOversizedTest< await checkEvents(notePreimageEvents, 'preimage').toMatchSnapshot('note oversized preimage events') - // TODO: Verify that no preimage events were emitted, and that an "ExtrinsicFailed" event was emitted! - // We expect the "ExtrinsicFailed" preimage event because the preimage exceeds the maximum allowed size, - - // expect((await getEventsWithType(client, 'preimage')).length).toBe(0) - // expect((await getEventsWithType(client, 'system')).length).toBeGreaterThan(0) - // expectFailedExtrinsicWithType(client, client.api.errors.preimage.PreimageTooLarge) + // We expect an "ExtrinsicFailed" preimage event because the preimage exceeds the maximum allowed size. + expect((await getEventsWithType(client, 'preimage')).length).toBe(0) + expect((await getEventsWithType(client, 'system')).length).toBeGreaterThan(0) + await expectFailedExtrinsicWithType(client, client.api.errors.preimage.TooBig) } /** From a26b54c79e301d74b6a239cbef7052f23554d8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Fri, 21 Nov 2025 16:20:13 +0000 Subject: [PATCH 2/7] Fix `ensure_updated` preimage test --- .../assetHubKusama.preimage.e2e.test.ts.snap | 12 +-- ...assetHubPolkadot.preimage.e2e.test.ts.snap | 12 +-- packages/shared/src/preimage.ts | 95 ++++++++++--------- 3 files changed, 53 insertions(+), 66 deletions(-) diff --git a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap index 0b413c667..80b15580f 100644 --- a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap +++ b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap @@ -52,17 +52,7 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; -exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = ` -[ - { - "data": { - "hash_": "(hash)", - }, - "method": "Noted", - "section": "preimage", - }, -] -`; +exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` [ diff --git a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap index 713c900e2..caac5451c 100644 --- a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap +++ b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap @@ -52,17 +52,7 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = ` -[ - { - "data": { - "hash_": "(hash)", - }, - "method": "Noted", - "section": "preimage", - }, -] -`; +exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` [ diff --git a/packages/shared/src/preimage.ts b/packages/shared/src/preimage.ts index 2eaae4070..b05bc7405 100644 --- a/packages/shared/src/preimage.ts +++ b/packages/shared/src/preimage.ts @@ -727,14 +727,14 @@ async function preimageOversizedTest< } /** - * Test the "ensure_updated" preimage functionality. + * Test `preimage::ensure_updated`, including the fee waiving. * - * 1. Simulate a number of pre-deprecation preimages with bogus hashes. - * 2. Alice registers a number of post-deprecation (valid) preimages. - * 3. Ensure that all valid preimages have been registered. - * 4. Alice calls "ensure_updated" for all hashes (valid and bogus). - * 5. Verify that Alice's reserved funds remain the same after the update. - * 6. If the ratio of new to total preimages is less than 90%, check that fees have been paid. + * 1. Manually inject a number of preimages into the deprecated `StatusFor` storage. + * 2. Bob registers a number of unrequested preimages - these will go into the `RequestStatusFor` storage. + * 3. Ensure that all preimages are in storage. + * 4. Alice calls "ensure_updated" for all the above preimages. + * 5. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid + * fees. */ async function preimageEnsureUpdatedTest< TCustom extends Record | undefined, @@ -743,23 +743,43 @@ async function preimageEnsureUpdatedTest< const [client] = await setupNetworks(chain) const alice = testAccounts.alice - setupBalances(client, [{ address: alice.address, amount: 1000e10 }]) + setupBalances(client, [ + { address: alice.address, amount: 1000e10 }, + { address: testAccounts.bob.address, amount: 1000e10 }, + ]) - const expectFees = newPreimagesCount / (newPreimagesCount + oldPreimagesCount) < 0.9 + const expectFees = oldPreimagesCount / (newPreimagesCount + oldPreimagesCount) < 0.9 let aliceNonce = (await client.api.rpc.system.accountNextIndex(alice.address)).toNumber() - // 1. Simulate a number of pre-deprecation preimages with bogus hashes. + // 1. Simulate a number of pre-deprecation preimages const bogusPreimageLength = 3 const preimageHashes: [string, number][] = Array.from({ length: oldPreimagesCount }, (_, i) => [ blake2AsHex(new Uint8Array(bogusPreimageLength).fill(i + 1), 256), bogusPreimageLength, ]) - // 2. Alice registers a number of post-deprecation (valid) preimages. - for (let i = 0; i < newPreimagesCount; i++) { + // Manually insert the obsolete preimages into `StatusFor` storage + const statusForEntries = preimageHashes.slice(0, oldPreimagesCount).map(([hash, len]) => [ + [hash], + { + unrequested: { + deposit: [testAccounts.bob.address, 1000000], + len, + }, + }, + ]) + + await client.dev.setStorage({ + Preimage: { + statusFor: statusForEntries, + }, + }) + + // 2. Bob registers a number of unrequested preimages + for (let i = 1; i <= newPreimagesCount; i++) { const encodedProposal = client.api.tx.treasury.spendLocal(SPEND_AMOUNT + i, testAccounts.bob.address).method const notePreimageTx = client.api.tx.preimage.notePreimage(encodedProposal.toHex()) - await sendTransaction(notePreimageTx.signAsync(alice, { nonce: aliceNonce++ })) + await sendTransaction(notePreimageTx.signAsync(testAccounts.bob, { nonce: aliceNonce++ })) preimageHashes.push([encodedProposal.hash.toHex(), encodedProposal.encodedLength]) } @@ -768,31 +788,26 @@ async function preimageEnsureUpdatedTest< await client.dev.newBlock() } - // 3. Ensure that all valid preimages have been registered. + // 3. Ensure that all preimages are in storage. for (let i = 0; i < oldPreimagesCount + newPreimagesCount; i++) { - const preimage = await client.api.query.preimage.preimageFor(preimageHashes[i]) - - // The first hashes are bogus and we expect them to not actually be stored. - expect(preimage.isNone).toBe(i < oldPreimagesCount) + if (i < oldPreimagesCount) { + const statusFor = await client.api.query.preimage.statusFor(preimageHashes[i][0]) + expect(statusFor.isSome).toBe(true) + } else { + const requestStatusFor = await client.api.query.preimage.requestStatusFor(preimageHashes[i][0]) + expect(requestStatusFor.isSome).toBe(true) + } } - // Check Alice's reserved funds. - const aliceReservedFundsAfterNote = await getReservedFunds(client, alice.address) - const aliceFreeFundsAfterNote = await getFreeFunds(client, alice.address) - - // 4. Alice calls "ensure_updated" for all hashes (valid and bogus). + // 4. Alice calls "ensure_updated" for all preimages. const ensureUpdatedTx = client.api.tx.preimage.ensureUpdated(preimageHashes.map(([hash]) => hash)) const ensureUpdatedEvents = await sendTransaction(ensureUpdatedTx.signAsync(alice)) await client.dev.newBlock() await checkEvents(ensureUpdatedEvents, 'preimage').toMatchSnapshot('ensure updated preimage events') - // Check Alice's reserved funds again. - const aliceReservedFundsAfterUpdate = await getReservedFunds(client, alice.address) - const aliceFreeFundsAfterUpdate = await getFreeFunds(client, alice.address) - - // 5. Verify that Alice's reserved funds remain the same after the update. - expect(aliceReservedFundsAfterUpdate).toBe(aliceReservedFundsAfterNote) + // 5. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid + // fees. // Get the transaction fee from the payment event. const events = await client.api.query.system.events() @@ -801,23 +816,15 @@ async function preimageEnsureUpdatedTest< return event.section === 'transactionPayment' && event.method === 'TransactionFeePaid' }) - // In all scenarios we expect an additional flat fee to also be paid. assert(client.api.events.transactionPayment.TransactionFeePaid.is(txPaymentEvent!.event)) const txPaymentEventData = txPaymentEvent!.event.data - const txPaymentFee = txPaymentEventData.actualFee.toNumber() - - assert(txPaymentEventData.tip.toBigInt() === 0n, 'Unexpected extrinsic tip') - expect(txPaymentFee).toBeGreaterThan(0) - - const ensureUpdatedFee = aliceFreeFundsAfterNote - txPaymentFee - aliceFreeFundsAfterUpdate - - // 6. If the ratio of new to total preimages is less than 90%, check that fees have been paid. + const txPaymentFee = txPaymentEventData.actualFee.toBigInt() + expect(txPaymentEventData.tip.toBigInt(), 'Unexpected extrinsic tip').toBe(0n) + // If the ratio of old to total preimages is more than 90%, fees were paid. if (expectFees) { - // TODO: The "ensure_updated" fee should be strictly positive in this case, because less than - // 90 % of the preimages were updated (since the others were bogus)! - // expect(ensureUpdatedFee).toBeGreaterThan(0) + expect(txPaymentFee).toBeGreaterThan(0n) } else { - expect(ensureUpdatedFee).toBe(0) + expect(txPaymentFee).toBe(0n) } } @@ -871,12 +878,12 @@ export function successPreimageE2ETests< { kind: 'test', label: 'preimage ensure updated test (no fees due)', - testFn: async () => await preimageEnsureUpdatedTest(chain, 1, 10), + testFn: async () => await preimageEnsureUpdatedTest(chain, 10, 1), }, { kind: 'test', label: 'preimage ensure updated test (fees due)', - testFn: async () => await preimageEnsureUpdatedTest(chain, 2, 7), + testFn: async () => await preimageEnsureUpdatedTest(chain, 5, 5), }, ], }, From 41459b03857a3e6315324b03c10155eec07de18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Fri, 21 Nov 2025 17:03:43 +0000 Subject: [PATCH 3/7] Further extened test to `ensure_updated` --- packages/shared/src/preimage.ts | 120 +++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 18 deletions(-) diff --git a/packages/shared/src/preimage.ts b/packages/shared/src/preimage.ts index b05bc7405..511da23b0 100644 --- a/packages/shared/src/preimage.ts +++ b/packages/shared/src/preimage.ts @@ -4,13 +4,13 @@ import { type Chain, testAccounts } from '@e2e-test/networks' import { type Client, type RootTestTree, setupBalances, setupNetworks } from '@e2e-test/shared' import type { IsError } from '@polkadot/types/metadata/decorate/types' -import { blake2AsHex } from '@polkadot/util-crypto' +import { blake2AsHex, encodeAddress } from '@polkadot/util-crypto' import { assert, expect } from 'vitest' import { + check, checkEvents, - getFreeFunds, getReservedFunds, scheduleInlineCallListWithSameOrigin, scheduleInlineCallWithOrigin, @@ -733,16 +733,19 @@ async function preimageOversizedTest< * 2. Bob registers a number of unrequested preimages - these will go into the `RequestStatusFor` storage. * 3. Ensure that all preimages are in storage. * 4. Alice calls "ensure_updated" for all the above preimages. - * 5. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid + * 5. Check that the old preimages moved from `StatusFor` storage to `RequestStatusFor` storage. + * 6. Check that the new preimages are still in `RequestStatusFor` storage. + * 7. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid * fees. */ async function preimageEnsureUpdatedTest< TCustom extends Record | undefined, TInitStorages extends Record> | undefined, ->(chain: Chain, oldPreimagesCount: number, newPreimagesCount: number) { +>(chain: Chain, testConfig: TestConfig, oldPreimagesCount: number, newPreimagesCount: number) { const [client] = await setupNetworks(chain) const alice = testAccounts.alice + const addressEncoding = testConfig.addressEncoding setupBalances(client, [ { address: alice.address, amount: 1000e10 }, { address: testAccounts.bob.address, amount: 1000e10 }, @@ -759,15 +762,34 @@ async function preimageEnsureUpdatedTest< ]) // Manually insert the obsolete preimages into `StatusFor` storage - const statusForEntries = preimageHashes.slice(0, oldPreimagesCount).map(([hash, len]) => [ - [hash], - { - unrequested: { - deposit: [testAccounts.bob.address, 1000000], - len, - }, - }, - ]) + // Half are unrequested, half are requested + const statusForEntries = preimageHashes.slice(0, oldPreimagesCount).map(([hash, len], i) => { + const halfwayPoint = Math.floor(oldPreimagesCount / 2) + if (i < halfwayPoint) { + // Unrequested variant + return [ + [hash], + { + unrequested: { + deposit: [alice.address, 1000000], + len, + }, + }, + ] + } else { + // Requested variant + return [ + [hash], + { + requested: { + deposit: [alice.address, 1000000], + count: 1, + len, + }, + }, + ] + } + }) await client.dev.setStorage({ Preimage: { @@ -789,13 +811,38 @@ async function preimageEnsureUpdatedTest< } // 3. Ensure that all preimages are in storage. + const halfwayPoint = Math.floor(oldPreimagesCount / 2) for (let i = 0; i < oldPreimagesCount + newPreimagesCount; i++) { if (i < oldPreimagesCount) { const statusFor = await client.api.query.preimage.statusFor(preimageHashes[i][0]) - expect(statusFor.isSome).toBe(true) + assert(statusFor.isSome) + + if (i < halfwayPoint) { + // Check unrequested variant + await check(statusFor.unwrap()).toMatchObject({ + unrequested: { + deposit: [encodeAddress(alice.address, addressEncoding), 1000000], + len: preimageHashes[i][1], + }, + }) + } else { + // Check requested variant + await check(statusFor.unwrap()).toMatchObject({ + requested: { + deposit: [encodeAddress(alice.address, addressEncoding), 1000000], + count: 1, + len: preimageHashes[i][1], + }, + }) + } } else { const requestStatusFor = await client.api.query.preimage.requestStatusFor(preimageHashes[i][0]) - expect(requestStatusFor.isSome).toBe(true) + assert(requestStatusFor.isSome) + const unwrapped = requestStatusFor.unwrap() + expect(unwrapped.isUnrequested).toBe(true) + const unrequested = unwrapped.asUnrequested + expect(unrequested.ticket[0].toString()).toBe(encodeAddress(testAccounts.bob.address, addressEncoding)) + expect(unrequested.len.toNumber()).toBe(preimageHashes[i][1]) } } @@ -806,7 +853,44 @@ async function preimageEnsureUpdatedTest< await checkEvents(ensureUpdatedEvents, 'preimage').toMatchSnapshot('ensure updated preimage events') - // 5. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid + // 5. Check that the old preimages moved from `StatusFor` storage to `RequestStatusFor` storage. + for (let i = 0; i < oldPreimagesCount; i++) { + const statusFor = await client.api.query.preimage.statusFor(preimageHashes[i][0]) + expect(statusFor.isNone).toBe(true) + + const requestStatusFor = await client.api.query.preimage.requestStatusFor(preimageHashes[i][0]) + assert(requestStatusFor.isSome) + + const unwrapped = requestStatusFor.unwrap() + + if (i < halfwayPoint) { + // Was unrequested, now unrequested in new storage + expect(unwrapped.isUnrequested).toBe(true) + const unrequested = unwrapped.asUnrequested + expect(unrequested.ticket[0].toString()).toBe(encodeAddress(alice.address, addressEncoding)) + expect(unrequested.len.toNumber()).toBe(preimageHashes[i][1]) + } else { + // Was requested, now requested in new storage + expect(unwrapped.isRequested).toBe(true) + const requested = unwrapped.asRequested + expect(requested.maybeTicket.unwrap()[0].toString()).toBe(encodeAddress(alice.address, addressEncoding)) + expect(requested.count.toNumber()).toBe(1) + expect(requested.maybeLen.unwrap().toNumber()).toBe(preimageHashes[i][1]) + } + } + + // 6. Check that the new preimages are still in `RequestStatusFor` storage. + for (let i = oldPreimagesCount; i < oldPreimagesCount + newPreimagesCount; i++) { + const requestStatusFor = await client.api.query.preimage.requestStatusFor(preimageHashes[i][0]) + assert(requestStatusFor.isSome) + const unwrapped = requestStatusFor.unwrap() + expect(unwrapped.isUnrequested).toBe(true) + const unrequested = unwrapped.asUnrequested + expect(unrequested.ticket[0].toString()).toBe(encodeAddress(testAccounts.bob.address, addressEncoding)) + expect(unrequested.len.toNumber()).toBe(preimageHashes[i][1]) + } + + // 7. If more than 90% of the preimages were updated from `StatusFor` to `RequestStatusFor`, check that Alice paid // fees. // Get the transaction fee from the payment event. @@ -878,12 +962,12 @@ export function successPreimageE2ETests< { kind: 'test', label: 'preimage ensure updated test (no fees due)', - testFn: async () => await preimageEnsureUpdatedTest(chain, 10, 1), + testFn: async () => await preimageEnsureUpdatedTest(chain, testConfig, 10, 1), }, { kind: 'test', label: 'preimage ensure updated test (fees due)', - testFn: async () => await preimageEnsureUpdatedTest(chain, 5, 5), + testFn: async () => await preimageEnsureUpdatedTest(chain, testConfig, 5, 5), }, ], }, From 90da8ae3653b51a2f005ab11ac2b824350638221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Fri, 21 Nov 2025 22:39:31 +0000 Subject: [PATCH 4/7] Address review comments --- packages/shared/src/preimage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/preimage.ts b/packages/shared/src/preimage.ts index 511da23b0..3dd2e9e5a 100644 --- a/packages/shared/src/preimage.ts +++ b/packages/shared/src/preimage.ts @@ -752,7 +752,7 @@ async function preimageEnsureUpdatedTest< ]) const expectFees = oldPreimagesCount / (newPreimagesCount + oldPreimagesCount) < 0.9 - let aliceNonce = (await client.api.rpc.system.accountNextIndex(alice.address)).toNumber() + let bobNonce = (await client.api.rpc.system.accountNextIndex(alice.address)).toNumber() // 1. Simulate a number of pre-deprecation preimages const bogusPreimageLength = 3 @@ -801,7 +801,7 @@ async function preimageEnsureUpdatedTest< for (let i = 1; i <= newPreimagesCount; i++) { const encodedProposal = client.api.tx.treasury.spendLocal(SPEND_AMOUNT + i, testAccounts.bob.address).method const notePreimageTx = client.api.tx.preimage.notePreimage(encodedProposal.toHex()) - await sendTransaction(notePreimageTx.signAsync(testAccounts.bob, { nonce: aliceNonce++ })) + await sendTransaction(notePreimageTx.signAsync(testAccounts.bob, { nonce: bobNonce++ })) preimageHashes.push([encodedProposal.hash.toHex(), encodedProposal.encodedLength]) } @@ -904,7 +904,7 @@ async function preimageEnsureUpdatedTest< const txPaymentEventData = txPaymentEvent!.event.data const txPaymentFee = txPaymentEventData.actualFee.toBigInt() expect(txPaymentEventData.tip.toBigInt(), 'Unexpected extrinsic tip').toBe(0n) - // If the ratio of old to total preimages is more than 90%, fees were paid. + // If the ratio of old to total preimages is more than 90%, fees are not paid. if (expectFees) { expect(txPaymentFee).toBeGreaterThan(0n) } else { From 1f998a84fa8e898d747074b66d3e65996a640fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Fri, 21 Nov 2025 22:53:08 +0000 Subject: [PATCH 5/7] Extend oversized preimage test --- packages/shared/src/preimage.ts | 41 +++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/packages/shared/src/preimage.ts b/packages/shared/src/preimage.ts index 3dd2e9e5a..5a39dc7ca 100644 --- a/packages/shared/src/preimage.ts +++ b/packages/shared/src/preimage.ts @@ -693,10 +693,12 @@ async function preimageEmptyTest< } /** - * Test the registering (noting) and unregistering (unnoting) of an oversized preimage. + * Test the maximum preimage size limit. * - * 1. Alice registers an oversized preimage. - * 2. The registration fails and no preimage is stored. + * 1. Alice successfully registers a preimage at exactly the maximum size (4 MB). + * 2. Verify the max-sized preimage is stored correctly. + * 3. Alice attempts to register an oversized preimage (4 MB + 1 byte). + * 4. The oversized registration fails with `TooBig` error and no preimage is stored. */ async function preimageOversizedTest< TCustom extends Record | undefined, @@ -707,23 +709,42 @@ async function preimageOversizedTest< const alice = testAccounts.alice setupBalances(client, [{ address: alice.address, amount: 1000e10 }]) - // 1. Alice registers an oversized preimage (more than 4 MB). const maxPreimageSize = 4 * 1024 * 1024 + + // 1. Alice successfully registers a preimage at exactly the maximum size. + const maxSizeBytesArray = Array(maxPreimageSize).fill(2) + const maxSizeBytes = client.api.createType('Bytes', maxSizeBytesArray) + const maxSizeHash = blake2AsHex(maxSizeBytes, 256) + + const noteMaxSizeTx = client.api.tx.preimage.notePreimage(maxSizeBytes) + const noteMaxSizeEvents = await sendTransaction(noteMaxSizeTx.signAsync(alice)) + await client.dev.newBlock() + + await checkEvents(noteMaxSizeEvents, 'preimage').toMatchSnapshot('note max size preimage events') + + // 2. Verify the max-sized preimage is stored correctly. + const storedMaxSizePreimage = await client.api.query.preimage.preimageFor([maxSizeHash, maxPreimageSize]) + assert(storedMaxSizePreimage.isSome, 'Max size preimage should be stored') + expect(storedMaxSizePreimage.unwrap().length).toBe(maxPreimageSize) + + // 3. Alice attempts to register an oversized preimage (more than 4 MB). const oversizedBytesArray = Array(maxPreimageSize + 1).fill(1) const oversizedBytes = client.api.createType('Bytes', oversizedBytesArray) + const oversizedHash = blake2AsHex(oversizedBytes, 256) - console.info(`Image of size ${oversizedBytes.length} has hash: ${blake2AsHex(oversizedBytes, 256)}`) - - const notePreimageTx = client.api.tx.preimage.notePreimage(oversizedBytes) - const notePreimageEvents = await sendTransaction(notePreimageTx.signAsync(alice)) + const noteOversizedTx = client.api.tx.preimage.notePreimage(oversizedBytes) + const noteOversizedEvents = await sendTransaction(noteOversizedTx.signAsync(alice)) await client.dev.newBlock() - await checkEvents(notePreimageEvents, 'preimage').toMatchSnapshot('note oversized preimage events') + await checkEvents(noteOversizedEvents, 'preimage').toMatchSnapshot('note oversized preimage events') - // We expect an "ExtrinsicFailed" preimage event because the preimage exceeds the maximum allowed size. + // 4. Verify the oversized registration failed with `TooBig` error and no preimage is stored. expect((await getEventsWithType(client, 'preimage')).length).toBe(0) expect((await getEventsWithType(client, 'system')).length).toBeGreaterThan(0) await expectFailedExtrinsicWithType(client, client.api.errors.preimage.TooBig) + + const storedOversizedPreimage = await client.api.query.preimage.preimageFor([oversizedHash, maxPreimageSize + 1]) + expect(storedOversizedPreimage.isNone, 'Oversized preimage should not be stored').toBe(true) } /** From c3fa281003203449e6a62225825652d3f0ff7066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Sat, 22 Nov 2025 01:54:57 +0000 Subject: [PATCH 6/7] Update preimage snapshots --- .../assetHubKusama.preimage.e2e.test.ts.snap | 12 ++++++++++++ .../assetHubPolkadot.preimage.e2e.test.ts.snap | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap index 80b15580f..585df671b 100644 --- a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap +++ b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap @@ -52,6 +52,18 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; +exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note max size preimage events 1`] = ` +[ + { + "data": { + "hash_": "(hash)", + }, + "method": "Noted", + "section": "preimage", + }, +] +`; + exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` diff --git a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap index caac5451c..bceade266 100644 --- a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap +++ b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap @@ -52,6 +52,18 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; +exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note max size preimage events 1`] = ` +[ + { + "data": { + "hash_": "(hash)", + }, + "method": "Noted", + "section": "preimage", + }, +] +`; + exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` From c4c163d5a965b0276bae51e6f91fe622deaa785c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20Bald=C3=A9?= Date: Sat, 22 Nov 2025 02:08:20 +0000 Subject: [PATCH 7/7] Update snapshot names, `PreImage` -> `Preimage` --- .../assetHubKusama.preimage.e2e.test.ts.snap | 28 +++++++++---------- .../src/assetHubKusama.preimage.e2e.test.ts | 2 +- ...assetHubPolkadot.preimage.e2e.test.ts.snap | 28 +++++++++---------- .../src/assetHubPolkadot.preimage.e2e.test.ts | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap index 585df671b..24d2e2c91 100644 --- a/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap +++ b/packages/kusama/src/__snapshots__/assetHubKusama.preimage.e2e.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage empty test > note empty preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage empty test > note empty preimage events 1`] = ` [ { "data": { @@ -12,7 +12,7 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage empty test > unnote empty preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage empty test > unnote empty preimage events 1`] = ` [ { "data": { @@ -24,11 +24,11 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage ensure updated test (fees due) > ensure updated preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage ensure updated test (fees due) > ensure updated preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage ensure updated test (no fees due) > ensure updated preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage ensure updated test (no fees due) > ensure updated preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage single note and unnote test > note preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage single note and unnote test > note preimage events 1`] = ` [ { "data": { @@ -40,7 +40,7 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; -exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests > preimage single note and unnote test > unnote preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > Kusama Asset Hub Preimage > preimage tests > preimage single note and unnote test > unnote preimage events 1`] = ` [ { "data": { @@ -52,7 +52,7 @@ exports[`Kusama Asset Hub PreImage > Kusama Asset Hub PreImage > preimage tests ] `; -exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note max size preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > failure tests > preimage oversized test > note max size preimage events 1`] = ` [ { "data": { @@ -64,9 +64,9 @@ exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > n ] `; -exports[`Kusama Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` [ { "data": { @@ -78,11 +78,11 @@ exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and ] `; -exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > repeat note preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > failure tests > preimage repeated note and unnote test > repeat note preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > repeat unnote preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > failure tests > preimage repeated note and unnote test > repeat unnote preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and unnote test > unnote preimage events 1`] = ` +exports[`Kusama Asset Hub Preimage > failure tests > preimage repeated note and unnote test > unnote preimage events 1`] = ` [ { "data": { @@ -94,6 +94,6 @@ exports[`Kusama Asset Hub PreImage > failure tests > preimage repeated note and ] `; -exports[`Kusama Asset Hub PreImage > failure tests > preimage single request and unrequest test as non-root > request preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > failure tests > preimage single request and unrequest test as non-root > request preimage events 1`] = `[]`; -exports[`Kusama Asset Hub PreImage > failure tests > preimage single request and unrequest test as non-root > unrequest preimage events 1`] = `[]`; +exports[`Kusama Asset Hub Preimage > failure tests > preimage single request and unrequest test as non-root > unrequest preimage events 1`] = `[]`; diff --git a/packages/kusama/src/assetHubKusama.preimage.e2e.test.ts b/packages/kusama/src/assetHubKusama.preimage.e2e.test.ts index 9b56e5313..7c8eadd33 100644 --- a/packages/kusama/src/assetHubKusama.preimage.e2e.test.ts +++ b/packages/kusama/src/assetHubKusama.preimage.e2e.test.ts @@ -2,7 +2,7 @@ import { assetHubKusama } from '@e2e-test/networks/chains' import { basePreimageE2ETests, registerTestTree, type TestConfig } from '@e2e-test/shared' const testConfig: TestConfig = { - testSuiteName: 'Kusama Asset Hub PreImage', + testSuiteName: 'Kusama Asset Hub Preimage', addressEncoding: 2, blockProvider: 'NonLocal', asyncBacking: 'Enabled', diff --git a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap index bceade266..bea07839e 100644 --- a/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap +++ b/packages/polkadot/src/__snapshots__/assetHubPolkadot.preimage.e2e.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage empty test > note empty preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage empty test > note empty preimage events 1`] = ` [ { "data": { @@ -12,7 +12,7 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage empty test > unnote empty preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage empty test > unnote empty preimage events 1`] = ` [ { "data": { @@ -24,11 +24,11 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage ensure updated test (fees due) > ensure updated preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage ensure updated test (fees due) > ensure updated preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage ensure updated test (no fees due) > ensure updated preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage ensure updated test (no fees due) > ensure updated preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage single note and unnote test > note preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage single note and unnote test > note preimage events 1`] = ` [ { "data": { @@ -40,7 +40,7 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; -exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage tests > preimage single note and unnote test > unnote preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > Polkadot Asset Hub Preimage > preimage tests > preimage single note and unnote test > unnote preimage events 1`] = ` [ { "data": { @@ -52,7 +52,7 @@ exports[`Polkadot Asset Hub PreImage > Polkadot Asset Hub PreImage > preimage te ] `; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note max size preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > failure tests > preimage oversized test > note max size preimage events 1`] = ` [ { "data": { @@ -64,9 +64,9 @@ exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > ] `; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > failure tests > preimage oversized test > note oversized preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > failure tests > preimage repeated note and unnote test > note preimage events 1`] = ` [ { "data": { @@ -78,11 +78,11 @@ exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note an ] `; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > repeat note preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > failure tests > preimage repeated note and unnote test > repeat note preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > repeat unnote preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > failure tests > preimage repeated note and unnote test > repeat unnote preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note and unnote test > unnote preimage events 1`] = ` +exports[`Polkadot Asset Hub Preimage > failure tests > preimage repeated note and unnote test > unnote preimage events 1`] = ` [ { "data": { @@ -94,6 +94,6 @@ exports[`Polkadot Asset Hub PreImage > failure tests > preimage repeated note an ] `; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage single request and unrequest test as non-root > request preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > failure tests > preimage single request and unrequest test as non-root > request preimage events 1`] = `[]`; -exports[`Polkadot Asset Hub PreImage > failure tests > preimage single request and unrequest test as non-root > unrequest preimage events 1`] = `[]`; +exports[`Polkadot Asset Hub Preimage > failure tests > preimage single request and unrequest test as non-root > unrequest preimage events 1`] = `[]`; diff --git a/packages/polkadot/src/assetHubPolkadot.preimage.e2e.test.ts b/packages/polkadot/src/assetHubPolkadot.preimage.e2e.test.ts index c9a9d829d..7d8decb01 100644 --- a/packages/polkadot/src/assetHubPolkadot.preimage.e2e.test.ts +++ b/packages/polkadot/src/assetHubPolkadot.preimage.e2e.test.ts @@ -2,7 +2,7 @@ import { assetHubPolkadot } from '@e2e-test/networks/chains' import { basePreimageE2ETests, registerTestTree, type TestConfig } from '@e2e-test/shared' const testConfig: TestConfig = { - testSuiteName: 'Polkadot Asset Hub PreImage', + testSuiteName: 'Polkadot Asset Hub Preimage', addressEncoding: 0, blockProvider: 'NonLocal', asyncBacking: 'Enabled',