From 13eae578c6189bd9d131456187787e9242a17084 Mon Sep 17 00:00:00 2001 From: Ermal Kaleci Date: Wed, 18 Oct 2023 01:59:33 +0200 Subject: [PATCH] fix child trie (#449) * fix child trie * update snapshot * add test --- .gitmodules | 2 +- executor/src/task.rs | 108 ++++++++---------- .../dry-run-extrinsic.test.ts.snap | 80 ++++++------- packages/e2e/src/crowdloan.redeem.test.ts | 34 +++++- vendor/smoldot | 2 +- 5 files changed, 123 insertions(+), 103 deletions(-) diff --git a/.gitmodules b/.gitmodules index de6b6f05..e6f8e3a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vendor/smoldot"] path = vendor/smoldot - url = https://github.com/smol-dot/smoldot.git + url = https://github.com/ermalkaleci/smoldot.git diff --git a/executor/src/task.rs b/executor/src/task.rs index 871aca55..c44ba332 100644 --- a/executor/src/task.rs +++ b/executor/src/task.rs @@ -4,7 +4,7 @@ use serde_wasm_bindgen::{from_value, to_value}; use smoldot::{ executor::{ host::{Config, HeapPages, HostVmPrototype}, - runtime_host::{self, OffchainContext, RuntimeHostVm, TrieChange, TrieChangeStorageValue}, + runtime_host::{self, OffchainContext, RuntimeHostVm}, storage_diff::TrieDiff, CoreVersionRef, }, @@ -90,10 +90,10 @@ fn is_magic_signature(signature: &[u8]) -> bool { const DEFAULT_CHILD_STORAGE_PREFIX: &[u8] = b":child_storage:default:"; -fn prefixed_child_key(child: impl AsRef<[u8]>, key: impl Iterator) -> Vec { +fn prefixed_child_key(child: impl Iterator, key: impl Iterator) -> Vec { [ DEFAULT_CHILD_STORAGE_PREFIX, - child.as_ref(), + &child.collect::>(), &key.collect::>(), ] .concat() @@ -112,7 +112,7 @@ fn handle_value(value: wasm_bindgen::JsValue) -> Result>, String> pub async fn run_task(task: TaskCall, js: crate::JsCallback) -> Result { let mut storage_main_trie_changes = TrieDiff::default(); - let mut child_storage_changes: BTreeMap, Option>> = Default::default(); + let mut storage_changes: BTreeMap, Option>> = Default::default(); let mut offchain_storage_changes: BTreeMap, Option>> = Default::default(); let vm_proto = HostVmPrototype::new(Config { @@ -132,7 +132,7 @@ pub async fn run_task(task: TaskCall, js: crate::JsCallback) -> Result Result { let key = if let Some(child) = req.child_trie() { HexString(prefixed_child_key( - child, + child.as_ref().iter().copied(), req.key().as_ref().iter().copied(), )) } else { HexString(req.key().as_ref().to_vec()) }; - let key = to_value(&key).map_err(|e| e.to_string())?; - - let value = js.get_storage(key).await; - let value = if value.is_string() { - let encoded = from_value::(value) - .map(|x| x.0) - .map_err(|e| e.to_string())?; - Some(encoded) + // check storage_changes first + if let Some(value) = storage_changes.get(&key.0) { + req.inject_value( + value + .to_owned() + .map(|x| (iter::once(x), TrieEntryVersion::V1)), + ) } else { - None - }; - req.inject_value(value.map(|x| (iter::once(x), TrieEntryVersion::V1))) + // otherwise, ask chopsticks + let key = to_value(&key).map_err(|e| e.to_string())?; + + let value = js.get_storage(key).await; + let value = if value.is_string() { + let encoded = from_value::(value) + .map(|x| x.0) + .map_err(|e| e.to_string())?; + Some(encoded) + } else { + None + }; + req.inject_value(value.map(|x| (iter::once(x), TrieEntryVersion::V1))) + } } RuntimeHostVm::ClosestDescendantMerkleValue(req) => { @@ -183,7 +193,7 @@ pub async fn run_task(task: TaskCall, js: crate::JsCallback) -> Result Result Result { ret = Ok(success.virtual_machine.value().as_ref().to_vec()); - // collect child storage changes - if let Some(changes) = success.storage_changes.trie_changes_iter_ordered() { - for (child, key, change) in changes { - if child.is_none() { - continue; - } - - let prefixed_key = prefixed_child_key( - child.unwrap(), - nibbles_to_bytes_suffix_extend(key.iter().copied()), - ); - - match change { - TrieChange::InsertUpdate { - new_storage_value, .. - } => match new_storage_value { - TrieChangeStorageValue::Modified { new_value } => { - child_storage_changes - .insert(prefixed_key, new_value.map(|x| x.to_vec())); - } - TrieChangeStorageValue::Unmodified => {} - }, - TrieChange::Remove => { - child_storage_changes.insert(prefixed_key, None); - } - } - } - } + success + .storage_changes + .trie_diffs() + .iter() + .for_each(|(child, diff)| { + diff.diff_iter_unordered().for_each(|(key, value, _)| { + let prefixed_key = if let Some(child) = child { + prefixed_child_key(child.iter().copied(), key.iter().copied()) + } else { + key.to_vec() + }; + storage_changes.insert(prefixed_key, value.map(|x| x.to_vec())); + }); + }); storage_main_trie_changes = success.storage_changes.into_main_trie_diff(); @@ -323,32 +319,26 @@ pub async fn run_task(task: TaskCall, js: crate::JsCallback) -> Result { ret = Err(err.to_string()); - storage_main_trie_changes = TrieDiff::empty(); - child_storage_changes = Default::default(); break; } } } Ok(ret.map_or_else(TaskResponse::Error, move |ret| { - let mut diff: Vec<(HexString, Option)> = storage_main_trie_changes - .diff_into_iter_unordered() - .map(|(k, v, _)| (HexString(k), v.map(HexString))) + let storage_diff = storage_changes + .into_iter() + .map(|(k, v)| (HexString(k), v.map(HexString))) .collect(); - for (k, v) in child_storage_changes { - diff.push((HexString(k), v.map(HexString))); - } - - let offchain_diff = offchain_storage_changes + let offchain_storage_diff = offchain_storage_changes .into_iter() .map(|(k, v)| (HexString(k), v.map(HexString))) .collect(); TaskResponse::Call(CallResponse { result: HexString(ret), - storage_diff: diff, - offchain_storage_diff: offchain_diff, + storage_diff, + offchain_storage_diff, runtime_logs, }) })) diff --git a/packages/e2e/src/__snapshots__/dry-run-extrinsic.test.ts.snap b/packages/e2e/src/__snapshots__/dry-run-extrinsic.test.ts.snap index 96d202c0..013a30e0 100644 --- a/packages/e2e/src/__snapshots__/dry-run-extrinsic.test.ts.snap +++ b/packages/e2e/src/__snapshots__/dry-run-extrinsic.test.ts.snap @@ -10,37 +10,33 @@ exports[`dry-run-extrinsic > dry run extrinsic 1`] = ` exports[`dry-run-extrinsic > dry run extrinsic 2`] = ` [ + [ + "0x1da53b775b270400e7e61ed5cbc5a146c726478796bad0b9cabd7481dbe64983", + undefined, + ], [ "0x26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850", "0x0e000000", ], [ - "0x3a7472616e73616374696f6e5f6c6576656c3a", - undefined, + "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96", + "0xa279094100000007493c6ebb0100", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98a437914f3dd43c1f1f4289c5f1baa47d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69", - "0x000000000000000001000000000000000010a5d4e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7", + "0x38020b0a00016d6f646c6163612f63647074000000000000000000000000000000000000000011971a0007000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000cf75186100000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000b987cd2800000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000d16694700100000000000000000000000000000000000000c2321f3e0002000000010000000000c2e498170002010000020000000a0888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eedca5a0920000000000000000000000000000020000000003d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690000020000000a00d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690010a5d4e800000000000000000000000000020000000a0288dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690010a5d4e800000000000000000000000000020000000a076d6f646c6163612f747273790000000000000000000000000000000000000000dca5a0920000000000000000000000000000020000001406dca5a0920000000000000000000000000000020000000e0388dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eedca5a09200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000a279094100000000", ], [ - "0x3a65787472696e7369635f696e646578", - "0x03000000", + "0x26aa394eea5630e07c48ae0c9558cef7a86da5a932684f199539836fcb8c886f", + "0x6a140000", ], [ "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9280b197190fc1a763257f65171ea366e88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee", "0x0100000000000000010000000000000024ca803d958c03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a", - "0x0003000000", - ], - [ - "0x1da53b775b270400e7e61ed5cbc5a146c726478796bad0b9cabd7481dbe64983", - undefined, - ], - [ - "0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7", - "0x38020b0a00016d6f646c6163612f63647074000000000000000000000000000000000000000011971a0007000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000cf75186100000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000b987cd2800000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000d16694700100000000000000000000000000000000000000c2321f3e0002000000010000000000c2e498170002010000020000000a0888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eedca5a0920000000000000000000000000000020000000003d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690000020000000a00d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690010a5d4e800000000000000000000000000020000000a0288dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eed17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae690010a5d4e800000000000000000000000000020000000a076d6f646c6163612f747273790000000000000000000000000000000000000000dca5a0920000000000000000000000000000020000001406dca5a0920000000000000000000000000000020000000e0388dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0eedca5a09200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000a279094100000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da98a437914f3dd43c1f1f4289c5f1baa47d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69", + "0x000000000000000001000000000000000010a5d4e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", ], [ "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ae10bf9cd0e372c142b2ca90219666906d6f646c6163612f747273790000000000000000000000000000000000000000", @@ -51,12 +47,16 @@ exports[`dry-run-extrinsic > dry run extrinsic 2`] = ` "0x49024102840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee00d90258d0bb17c04ae889cea745c25f2210139fce8ba58b93f32cbb263264fdbd6350aa06556466ec13ad5c54ed3ae6821741baef385a4c0bfb879dc4c3651607040000000a0000d17c2d7823ebf260fd138f2d7e27d114c0145d968b5ff5006125f2414fadae69070010a5d4e8", ], [ - "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96", - "0xa279094100000007493c6ebb0100", + "0x26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a", + "0x0003000000", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7a86da5a932684f199539836fcb8c886f", - "0x6a140000", + "0x3a65787472696e7369635f696e646578", + "0x03000000", + ], + [ + "0x3a7472616e73616374696f6e5f6c6576656c3a", + undefined, ], ] `; @@ -71,49 +71,49 @@ exports[`dry-run-extrinsic > dry run extrinsic with fake signature 1`] = ` exports[`dry-run-extrinsic > dry run extrinsic with fake signature 2`] = ` [ + [ + "0x1da53b775b270400e7e61ed5cbc5a146c726478796bad0b9cabd7481dbe64983", + undefined, + ], [ "0x26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850", "0x0b000000", ], [ - "0x3a7472616e73616374696f6e5f6c6576656c3a", - undefined, + "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96", + "0x07302bec2f0136330300000007493c6ebb0100", ], [ - "0x3a65787472696e7369635f696e646578", - "0x03000000", + "0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7", + "0x2c020b0a00016d6f646c6163612f63647074000000000000000000000000000000000000000011971a0007000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000cf75186100000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000b987cd2800000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000d16694700100000000000000000000000000000000000000c2321f3e0002000000010000000000c2e498170002010000020000000a0888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee56675d7e000000000000000000000000000002000000ff00000000020000000a0788dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee56675d7e0000000000000000000000000000020000000e0388dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000007302bec2f0136330300000100", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9280b197190fc1a763257f65171ea366e88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee", - "0x010000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7a86da5a932684f199539836fcb8c886f", + "0x48140000", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a", - "0x0003000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9280b197190fc1a763257f65171ea366e88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee", + "0x010000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", ], [ - "0x1da53b775b270400e7e61ed5cbc5a146c726478796bad0b9cabd7481dbe64983", - undefined, + "0x26aa394eea5630e07c48ae0c9558cef7df1daeb8986837f21cc5d17596bb78d19eb2dcce60f37a2702000000", + "0xc101b901840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee01deadbeefcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd000000ff00000080969800", ], [ - "0x26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7", - "0x2c020b0a00016d6f646c6163612f63647074000000000000000000000000000000000000000011971a0007000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000cf75186100000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000b987cd2800000000000000000000000000020b0a00016d6f646c6163612f636470740000000000000000000000000000000000000000d16694700100000000000000000000000000000000000000c2321f3e0002000000010000000000c2e498170002010000020000000a0888dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee56675d7e000000000000000000000000000002000000ff00000000020000000a0788dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee56675d7e0000000000000000000000000000020000000e0388dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000007302bec2f0136330300000100", + "0x26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a", + "0x0003000000", ], [ - "0x26aa394eea5630e07c48ae0c9558cef7df1daeb8986837f21cc5d17596bb78d19eb2dcce60f37a2702000000", - "0xc101b901840088dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee01deadbeefcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd000000ff00000080969800", + "0x3a65787472696e7369635f696e646578", + "0x03000000", ], [ - "0x26aa394eea5630e07c48ae0c9558cef734abf5cb34d6244378cddbf18e849d96", - "0x07302bec2f0136330300000007493c6ebb0100", + "0x3a7472616e73616374696f6e5f6c6576656c3a", + undefined, ], [ "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80", "0x001faafaf5abc9353600000000000000", ], - [ - "0x26aa394eea5630e07c48ae0c9558cef7a86da5a932684f199539836fcb8c886f", - "0x48140000", - ], ] `; diff --git a/packages/e2e/src/crowdloan.redeem.test.ts b/packages/e2e/src/crowdloan.redeem.test.ts index a11384ff..b059f9a5 100644 --- a/packages/e2e/src/crowdloan.redeem.test.ts +++ b/packages/e2e/src/crowdloan.redeem.test.ts @@ -3,7 +3,7 @@ import { testingPairs } from '@acala-network/chopsticks-testing' import networks from './networks' -describe.runIf(process.env.CI)('Polkadot Crowdloan Refund', async () => { +describe('Polkadot Crowdloan Refund', async () => { const { alice } = testingPairs() const { api, dev, teardown } = await networks.polkadot({ blockNumber: 17700000, timeout: 400_000 }) @@ -19,7 +19,7 @@ describe.runIf(process.env.CI)('Polkadot Crowdloan Refund', async () => { }) }, 200_000) - it( + it.runIf(process.env.CI)( "should refund Acala's contributers", async () => { // trigger refund @@ -46,5 +46,35 @@ describe.runIf(process.env.CI)('Polkadot Crowdloan Refund', async () => { { timeout: 400_000 }, ) + it('withdraw funds from crowdloan', async () => { + const expectedEvent = expect.arrayContaining([ + expect.objectContaining({ + event: expect.objectContaining({ + method: 'Transfer', + section: 'balances', + data: expect.objectContaining({ + from: '13UVJyLnbVp77Z2t6qZV4fNpRjDHppL6c87bHcZKG48tKJad', + to: '1E8EcginNpZRZezwa1A5eQT6crLQQj5R4T3pLKFbyJX3VU8', + amount: '500,000,000,000', + }), + }), + }), + ]) + + // trigger refund + await expect( + api.tx.crowdloan.withdraw('1E8EcginNpZRZezwa1A5eQT6crLQQj5R4T3pLKFbyJX3VU8', 3336).signAndSend(alice), + ).resolves.toBeTruthy() + await dev.newBlock() + expect((await api.query.system.events()).toHuman()).toEqual(expectedEvent) + + // doing the same thing again should fail because the funds are already withdrawn + await expect( + api.tx.crowdloan.withdraw('1E8EcginNpZRZezwa1A5eQT6crLQQj5R4T3pLKFbyJX3VU8', 3336).signAndSend(alice), + ).resolves.toBeTruthy() + await dev.newBlock() + expect((await api.query.system.events()).toHuman()).not.toEqual(expectedEvent) + }) + afterAll(async () => await teardown()) }) diff --git a/vendor/smoldot b/vendor/smoldot index 52e77e74..a9710409 160000 --- a/vendor/smoldot +++ b/vendor/smoldot @@ -1 +1 @@ -Subproject commit 52e77e74a3aed644682d102122e5645abd19f93e +Subproject commit a97104092cd36a205d65359e7b9f208d07818d8b