-
Notifications
You must be signed in to change notification settings - Fork 79
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
Implementation of EIP-1153: Transient Storage using Disk Persistence and Lifecycle Management #1588
base: master
Are you sure you want to change the base?
Conversation
…around comparing the liveliness of the transient data and validating that functionality in a test
…bine transient_slots with transient_data_lifespan anyway.
…DO reinitialize does not properly clear state KAMT due to clone/reference issues that are being debugged
actors/evm/src/interpreter/system.rs
Outdated
// Reinitialize the transient_slots with a fresh KAMT | ||
//let transient_store = self.rt.store().clone(); | ||
//self.transient_slots = StateKamt::new_with_config(transient_store, KAMT_CONFIG.clone()); | ||
// TODO XXX reinitialize does not currently work due to blockstore reference issues |
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.
I'd be interested to know what these errors are and how you end up diagnosing the problem, for my own educational purposes because your commented code looks like it should work.
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.
It's because self.rt.store()
doesn't implement clone, while &...
does, so rust is helpfully creating a reference for you.
Note: the new
function explicitly requires that the store be clonable.
Options are:
- Lift that requirement up to the
impl
level. - Use
self.transient_slots.into_store()
to "take" the existing store.
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.
@Stebalien I've tried a few different variations of the "taking" option that you are suggesting. I didn't quite get anything to compile however.
Could you share a deeper explanation on the two options to either lift the requirement to the impl
level (I'm not sure what you mean by this; which requirement? which impl
?) and also if you can help me with the second option about taking the ownership of the datastore in order to satisfy the requirements of new_with_config. I'm still learning the ins and outs of this in rust, and would be very grateful. I would definitely not mind a code commit either if it's a simple lift for you. Thanks in advanced!
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.
Ah, so, this is going to be a bit of a pain. The issue is that you can't leave transient_slots
uninitialized so you need something to put there while you construct the new Kamt
. E.g., you can have Option<StateKamt<...>>
and put none there while you replace it.
But... doing that will also help facilitate lazy loading (you can leave it as None
until the user first tries to load a transient slot). So it's not the end of the world.
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.
If you're stuck, I'd address the rest of the feedback first. Then I'll see what I can do to fix this part.
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.
Thanks! I'm now returning from the thanksgiving break and will look into everything this week.
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.
I have learned many things since starting this :) I see that my previous attempt was very much against the RAII ideas that rust enforces. I didn't realize that was the issue. We don't need to destroy and create a new KAMT object but simply need to clear the one we have.
As a placeholder I have implemented a loop over keys and delete implementation of clear
for now until an efficient clear()
can be used. I opened a PR filecoin-project/ref-fvm#2092 for an efficient implementation of clear
in KAMT that I hope can be approved and it will be easy for me from there to upgrade kamt in builtin-actors to the future version that supports clear.
…ent_data_state and transient_data_lifespan
…date kamt lirbary to support a clear method
Remaining issues:
|
2024-12-04 conversation between FilB and FilOz:
|
I did a quick look for a "simple" state migration that might be similar to this; I haven't found a great example yet but part of the v9 migration did introduce a couple of fields for FIP-0029 to the miner actor, |
following up from a sync with @rvagg @BigLep and @Stebalien with my own copy of notes:
Instead the determination of transient data validity should happen when the actor state is loaded State - should contain the (lifespan and kamt root) or be null System - only needs a valid KAMT root or null
|
…ut still issues with reload
…builtin-actors into feat/transient_storage
actors/evm/src/interpreter/system.rs
Outdated
if crate::is_dead(rt, &state) { | ||
// If we're "dead", return an empty read-only contract. The code will be empty, so | ||
// nothing can happen anyways. | ||
return Ok(Self::new(rt, true)); | ||
return Self::new(rt, true); | ||
} | ||
|
||
let read_only = rt.read_only(); | ||
let current_transient_data_lifespan = get_current_transient_data_lifespan(rt)?; |
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.
nit: crate::is_dead
has similar logic to get the current lifetime. It would be nice to unify this and to have a single concept of "current transaction". On the other hand, I'm happy to do this in a followup PR.
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.
I would feel very good about landing this and then collaborating with you or allowing you to do this in a followup PR.
…ap because we have already validated the existance of an id
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.
LGTM from a code perspective!
Co-authored-by: Steven Allen <steven@stebalien.com>
https://github.com/filecoin-project/go-state-types/compare/mikers/evm-transient-data-nv17?expand=1#diff-61808733785f19d73d06ebbd0b984828297ac80b9443c2a9071d88f1fd521b89R31-R32 |
require(retrievedValue == value, "TLOAD did not retrieve stored value within transaction"); | ||
} | ||
|
||
function testLifecycleValidationSubsequentTransaction() public { |
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.
wouldn't this one be // Test 2.2
?
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.
well done, particularly on the epic test to actual-changes ratio; my suggestions are simply suggestions, up to you whether you bother
Co-authored-by: Rod Vagg <rod@vagg.org>
Thank you!! That could have been so frustrating to catch later on! |
Co-authored-by: Rod Vagg <rod@vagg.org>
Co-authored-by: Rod Vagg <rod@vagg.org>
Co-authored-by: Rod Vagg <rod@vagg.org>
…efactored into TransientStorageTest
…builtin-actors into feat/transient_storage
@rvagg thanks for the feedback on the solidity tests! I ran |
Description
This WIP PR introduces transient storage support in the Filecoin EVM, conceptually aligning with Ethereum's EIP-1153. Transient storage functionality is implemented with a tombstone mechanism for lifecycle tracking keyed by transaction identifiers (
origin
andnonce
). While the core implementation is in place, work remains on validating the transient data's lifecycle and completing associated tests.Current Progress
State Modifications:
Persistent Transient Data:
Cid
variable has been added to represent transient storage.Lifecycle Tracking:
TransientDataLifespan
to track lifecycle with originActorID
andnonce
.New Operations:
TLOAD
: Retrieves transient data while ensuring lifecycle validity.TSTORE
: Updates transient data and lifecycle.TODO
): Compare transaction metadata with stored tombstone.Remaining TODOs
Liveliness Check for Transient Data:
Code Location:
get_transient_storage
andset_transient_storage
inactors/evm/src/interpreter/system.rs
.// TODO check tombstone for liveliness of data
Test Coverage:
TLOAD
,TSTORE
) are partially tested.Code Location:
actors/evm/src/interpreter/instructions/storage.rs
(Test module)// TODO test transient storage lifecycle
Edge Case Handling:
Testing
Implemented Tests:
test_tload
: ValidatesTLOAD
operation when data exists.test_tload_oob
: Ensures out-of-boundsTLOAD
returns zero.test_tstore
: ConfirmsTSTORE
updates transient data correctly.Pending Tests:
TODO
in the test module).Tradeoffs and Considerations
Increased Storage Overhead:
transient_state
andtransient_data_lifespan
toState
.Gas Inefficiency:
Checklist
TLOAD
andTSTORE
.State
andSystem
.TLOAD
andTSTORE
.Next Steps
References
Review Feedback
Incorporates feedback from @Stebalien:
State
clean unless other updates occur.