Why managing state archival is important for applications
Managing state archival is crucial for Stellar dapps for several reasons:- Data accessibility: Archived data becomes inaccessible, potentially breaking application functionality, so it’s important to manage data lifecycle and know when to restore.
- Cost efficiency: Different storage types have varying fees and archival behaviors, allowing developers to optimize costs. Due to this, some data may be more cost-effective to store in a way that causes it to be archived after a certain period.
- Data lifecycle management: Proper management ensures that important data remains accessible while allowing temporary data to expire.
- Application continuity: Ensuring contract instances and Wasm code remain live is essential for uninterrupted dapp operation. It is essential to check for contract availability before attempting to interact with the contract after a long period of inactivity.
Methods of implementing state archival on the client side
1. Extending TTL from the smart contract
This method involves invoking theextend_ttl() method from your smart contract to extend the TTL of the contract instance and its associated data. This method is useful when you want to keep the data accessible for a longer period. To use this method, your contract must not be archived at the time of calling.
extend_ttl() has two important parameters (T,N):
- T is threshold, the current ledger height at which the extension should happen.
- N is the new ledger height at which the data will expire.
- Current TTL must be less than T for the extension to happen.
- If N is less than the current ledger height, the TTL will not be extended and the call will be regarded as a no-op.
- If N is greater than the current ledger height, the TTL will be extended to N.
The above contract shows how to extend the TTL of a
Persistent, Instance, and Temporary data entry. The extend_ttl() method is used to extend the TTL of the data entry to a new ledger height.Using the Extend TTL method in your Contract
When we create DApps, we do not typically create buttons to extend the TTL of data entries. Instead, we can create a function that extends the TTL of the data entries when the DApp is used. For example, we can increase the TTL of a temporary data entry calledhighestBid in a bidding DApp when a new bid is placed. This will ensure that the bid data remains accessible for as long as it is needed.
2. Restoring archived data
When developing a dapp on Stellar, you may encounter situations where contract data or the contract instance has been archived due to inactivity. Let’s walk through the process of restoring archived data using the JavaScript SDK and Freighter wallet.Prerequisites
- Stellar SDK:
npm install @stellar/stellar-sdk - Freighter API:
npm install @stellar/freighter-api - A Stellar RPC endpoint (e.g.,
https://soroban-testnet.stellar.org)
Step 1: Set up the SDK and Freighter
First, import the necessary components:Step 2: Create a helper function for restoration
Let’s create a helper function that attempts to submit a transaction, and if it fails due to archived data, it will restore the data and retry:HostStorageError), it creates a separate restoration transaction, signs it with Freighter, and submits it before retrying the original transaction.
Step 3: Use the helper function in your dapp
You can now use this function to make contract calls that automatically handle restoration:Step 4: Handling contract instance restoration
For restoring an entire contract instance, you might need a separate function: Here we will be using thegetLedgerEntries method to get the WASM code of the contract and also the restoreFootprint operation to restore the contract instance.
This function specifically restores a contract instance and its associated Wasm code. It retrieves the contract’s footprint and Wasm entry, creates a restoration transaction, which is then signed using Freighter and submitted to the network.
When to use these functions
performContractActionhelper can be used when trying to invoke a smart contract function. It can help to restore persistent data associated with the call.restoreContractInstancehelper can be used during app initialization after the app has not been used for a long time. Using an indexer to get this info (when last app was used) is a great approach.