fip | title | author | discussions-to | status | type | category | created |
---|---|---|---|---|---|---|---|
0097 |
Add Support for EIP-1153 (Transient Storage) in the FEVM |
Michael Seiler (@snissn), Steven Allen (@stebalien) |
Accepted |
Technical |
Core |
2024-11-19 |
This proposal introduces support for EIP-1153: Transient Storage in the Filecoin Ethereum Virtual Machine (FEVM). Transient storage provides data storage during transaction execution, scoped strictly to the transaction and the contract utilizing it. To maintain compatibility with Ethereum contracts utilizing this feature, the FEVM will implement transient storage with lifecycle validation and isolation.
EIP-1153 defines transient storage as temporary data accessible only during the originating transaction, cleared automatically at the end of the transaction. This FIP adapts transient storage to the FEVM using TLOAD
and TSTORE
opcodes, ensuring compatibility with Ethereum contracts and libraries that rely on this feature. Transient storage is scoped to the specific contract and transaction, ensuring that each contract’s transient storage is isolated. Nested contract calls cannot access the transient storage of other contracts, but reentrant calls to the same contract within a transaction will access the same transient storage space. Lifecycle validation mechanisms enforce this behavior, achieving functional equivalence with Ethereum’s implementation while maintaining seamless integration with Filecoin’s architecture.
Transient storage offers developers temporary, transaction-scoped storage for managing intermediate states. One key benefit of this feature is its ability to improve the implementation of reentrancy locks, enhancing security by mitigating risks associated with multiple calls to a function within sub-transactions. This feature was introduced on Ethereum mainnet in March 2024 as part of the Cancun (Dencun) upgrade, making adopting this FIP important to align the FEVM with Ethereum’s evolving tooling and Solidity’s modern features. By implementing transient storage, the FEVM ensures a seamless developer experience while supporting advanced contract use cases and secure computing.
While the FEVM implementation utilizes permanent storage for practical reasons, its lifecycle validation ensures it functionally replicates Ethereum’s transient storage. This enables compatibility with contracts and libraries that rely on TLOAD
and TSTORE
while supporting transaction-scoped data handling.
- Opcode Hex:
0x5C
- Stack Input:
key
: Location of the transient storage value to load
- Stack Output:
value
: Stored value or zero if no value exists
- Description:
- Retrieves the value associated with
key
in transient storage. - If the transaction has ended, transient storage is cleared, and
TLOAD
returns zero.
- Retrieves the value associated with
- Opcode Hex:
0x5D
- Stack Input:
key
: Location to store the valuevalue
: Value to store
- Output: None
- Description:
- Stores
value
at the specifiedkey
in transient storage. - Data is cleared at the end of the transaction.
- Stores
Transient storage is valid only within a single transaction. The system enforces this behavior by:
- Tracking
origin
andnonce
: Each transient storage slot is associated with the transaction’s origin actor and nonce. - Resetting Storage on New Transactions: If a new transaction begins, previous transient storage data is discarded.
- Allowing Reentrancy: If a contract calls itself within a transaction, it retains access to the same transient storage.
At the implementation level, transient storage is managed via StateKamt<U256, U256>
, ensuring transaction-scoped isolation.
The FEVM implements transient storage (TLOAD
and TSTORE
) using an internal lifecycle validation mechanism. This ensures that transient storage remains scoped to the transaction and is automatically cleared once execution ends.
The implementation introduces the following Rust data structures:
TransientData
: Stores the transient storage state for a contract within a transaction.TransientDataLifespan
: Tracks the lifespan of transient storage using theorigin
actor ID andnonce
of the transaction.
pub struct TransientData {
pub transient_data_state: Cid, // CID of the transient storage map
pub transient_data_lifespan: TransientDataLifespan, // Lifecycle validation
}
pub struct TransientDataLifespan {
pub origin: ActorID, // Origin actor ID
pub nonce: u64, // Unique transaction identifier
}
The FEVM utilizes persistent storage to back transient data but enforces strict lifecycle rules to ensure it behaves like Ethereum's transient storage. The system:
-
Checks Transaction Context:
- Before every
TLOAD
orTSTORE
operation, the contract verifies the transaction’sorigin
andnonce
to ensure validity.
- Before every
-
Clears Storage at Transaction End:
- If a new transaction begins, the system resets the
TransientData
state, ensuring no data persists across transactions.
- If a new transaction begins, the system resets the
-
Handles Reentrant Calls:
- If a contract invokes itself within the same transaction, transient storage remains available.
The design adheres to the intent of EIP-1153 while adapting to Filecoin's architecture. The use of lifecycle validation ensures transient storage behaves as expected within the scope of a single transaction. This approach balances compatibility with Ethereum contracts and simplifies implementation within the existing FEVM architecture.
Alternative designs, such as purely in-memory storage, were considered but deemed impractical due to technical implementation difficulties.
The addition of transient storage is fully backward-compatible. Existing contracts remain unaffected unless they utilize TLOAD
and TSTORE
. Contracts compiled with older Solidity versions will continue to execute without changes.
At the time of writing, support for TLOAD
and TSTORE
in current versions of Solidity is only available using inline-assembly. Thus, it is an explicitly opt-in feature, rather than a feature that contract authors may unknowngly be enabling when bumping compiler version and EVM target.
- Verify
TLOAD
retrieves the correct value. - Verify
TSTORE
writes data to transient storage. - Verify
TLOAD
from an uninitialized location returns zero.
- Verify transient storage is cleared at the end of a transaction.
- Verify reentrant calls access the same transient storage space.
- Verify nested contract calls have independent transient storage.
- Deploy two contracts,
A
andB
. - Have contract
A
write to transient storage. - Have contract
B
attempt to accessA
's transient storage. - Verify that
B
cannot readA
's transient storage.
- Store a value in transient storage.
- Revert the transaction before it completes.
- Verify that no transient storage data persists.
Transient storage introduces security considerations, primarily around ensuring that data does not persist beyond the transaction. To mitigate risks:
-
Automatic Clearing at Transaction End
- Transient storage is reset when a new transaction starts.
- Even if the contract does not explicitly clear storage, the FEVM enforces reset.
-
Preventing Cross-Contract Leakage
- Contracts cannot access transient storage from other contracts.
- Each contract’s transient storage is isolated by its execution context.
-
Reentrancy Safety
- Contracts can safely store temporary data within a transaction.
By adding support for transient storage, this FIP improves the FEVM's compatibility with Ethereum and provides developers with useful functionality for transaction-scoped data handling. This feature enables capabilities outlined in EIP-1153, such as reentrancy locks, temporary approvals, on-chain address computation, and enhanced proxy call metadata handling. These improvements align with Filecoin's goal of enabling scalable and reliable decentralized applications. However, transient storage does not introduce or impact economic incentives within the network.
Adding transient storage ensures compatibility with modern Ethereum tooling, attracting developers to Filecoin’s ecosystem. This feature supports the development of advanced smart contracts and storage-related services. This addition further solidifies Filecoin’s position as a robust EVM-compatible chain, enhancing its attractiveness to Ethereum developers and expanding its ecosystem of decentralized applications.
The reference implementation, including TLOAD
and TSTORE
, is available in the following pull request: filecoin-project/builtin-actors#1588. The implementation includes lifecycle validation and persistent backing for ease of use.
Copyright and related rights waived via CC0.