-
Notifications
You must be signed in to change notification settings - Fork 7
add transient storage support in polkadot test execution mode
#449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 7 commits
b98ae85
506f703
acd90c2
ee52cc5
6d56b56
ace141b
923320a
a9122b8
88f9ccf
71ae9c9
dff35e0
c15324c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| use crate::{config::*, test_helpers::TEST_DATA_REVIVE}; | ||
| use foundry_test_utils::Filter; | ||
| use revive_strategy::ReviveRuntimeMode; | ||
| use revm::primitives::hardfork::SpecId; | ||
| use rstest::rstest; | ||
|
|
||
| #[rstest] | ||
| #[case::pvm(ReviveRuntimeMode::Pvm)] | ||
| #[case::evm(ReviveRuntimeMode::Evm)] | ||
| #[tokio::test(flavor = "multi_thread")] | ||
| async fn test_transient_storage(#[case] runtime_mode: ReviveRuntimeMode) { | ||
| let runner: forge::MultiContractRunner = TEST_DATA_REVIVE.runner_revive(runtime_mode); | ||
| let filter = Filter::new("testTransientStoragePersistence", "TransientStorage", ".*/revive/.*"); | ||
|
|
||
| TestConfig::with_filter(runner, filter).spec_id(SpecId::PRAGUE).run().await; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,7 +115,7 @@ parameter_types! { | |
| pub const UnstableInterface: bool = true; | ||
| pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); | ||
| pub const NativeToEthRatio: u32 = 1_000_000; | ||
| pub const GasScale : u32 = 1_000_000; | ||
| pub const GasScale : u32 = 100_000_000; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does it fix?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OutOfGas errors with balancer v3 |
||
|
|
||
| pub const DepositPerByte: Balance = 1; | ||
| pub const DepositPerItem: Balance = 2; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -158,11 +158,13 @@ impl ExecutorStrategyExt for ReviveExecutorStrategyRunner { | |
| let ctx = get_context_ref(ctx); | ||
| let mut externalities = ctx.externalties.0.lock().unwrap(); | ||
| externalities.externalities.ext().storage_start_transaction(); | ||
| externalities.transient_storage.start_transaction(); | ||
| } | ||
|
|
||
| fn rollback_transaction(&self, ctx: &dyn ExecutorStrategyContext) { | ||
| let ctx = get_context_ref(ctx); | ||
| let mut state = ctx.externalties.0.lock().unwrap(); | ||
| let _ = state.externalities.ext().storage_rollback_transaction(); | ||
| state.transient_storage.rollback_transaction(); | ||
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.24; | ||
|
|
||
| import "ds-test/test.sol"; | ||
| import "cheats/Vm.sol"; | ||
| import "../../default/logs/console.sol"; | ||
|
|
||
| /** | ||
| * @title Minimal reproducer for foundry-polkadot transient storage bug | ||
| * @dev Demonstrates that transient storage is incorrectly cleared between external calls | ||
| */ | ||
| contract Counter { | ||
| function increment() external { | ||
| assembly { | ||
| let value := tload(0) | ||
| tstore(0, add(value, 1)) | ||
| } | ||
| } | ||
|
|
||
| function get() external view returns (uint256 value) { | ||
| assembly { | ||
| value := tload(0) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| contract TransientStorage is DSTest { | ||
| Vm constant vm = Vm(HEVM_ADDRESS); | ||
| Counter counter; | ||
|
|
||
| function setUp() public { | ||
| counter = new Counter(); | ||
| } | ||
|
|
||
| /** | ||
| * @dev This test FAILS in foundry-polkadot | ||
| * Expected: counter.get() returns 1 | ||
| * Actual: counter.get() returns 0 | ||
| * | ||
| * The bug: transient storage is cleared between the two external calls | ||
| * According to EIP-1153, transient storage should persist for the entire transaction | ||
| */ | ||
| function testTransientStoragePersistence() public { | ||
| // Store value 1 in transient storage | ||
| counter.increment(); | ||
|
|
||
| // This should return 1, but returns 0 in foundry-polkadot | ||
| uint256 value = counter.get(); | ||
|
|
||
| assertEq(value, 1, "Transient storage should persist across external calls"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you plan to use this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will use latest master as soon as the pr is merged