Skip to content
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

Subgraph Best Practices 5 and 6 #825

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion website/pages/en/cookbook/_meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ export default {
grafting: '',
'subgraph-uncrashable': '',
'substreams-powered-subgraphs': '',
'transfer-to-the-graph': '',
pruning: 'Subgraph Best Practice 1: Pruning with indexerHints',
derivedfrom: 'Subgraph Best Practice 2: Manage Arrays with @derivedFrom',
'immutable-entities-bytes-as-ids': 'Subgraph Best Practice 3: Using Immutable Entities and Bytes as IDs',
'avoid-eth-calls': 'Subgraph Best Practice 4: Avoid eth_calls',
'transfer-to-the-graph': '',
timeseries: 'Subgraph Best Practice 5: Simplify and Optimize with Timeseries and Aggregations',
'grafting-hotfix': 'Subgraph Best Practice 6: Grafting and Hotfixing',
enums: '',
}
14 changes: 14 additions & 0 deletions website/pages/en/cookbook/avoid-eth-calls.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,17 @@ Note: Declared eth_calls can only be made in subgraphs with specVersion >= 1.2.0
## Conclusion

We can significantly improve indexing performance by minimizing or eliminating `eth_calls` in our subgraphs.

## Subgraph Best Practices 1-6

1. [Improve Query Speed with Subgraph Pruning](https://thegraph.com/docs/en/cookbook/pruning/)

2. [Improve Indexing and Query Responsiveness by Using @derivedFrom](https://thegraph.com/docs/en/cookbook/derivedfrom/)

3. [Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs](https://thegraph.com/docs/en/cookbook/immutable-entities-bytes-as-ids/)

4. [Improve Indexing Speed by Avoiding `eth_calls`](https://thegraph.com/docs/en/cookbook/avoid-eth-calls/)

5. [Simplify and Optimize with Timeseries and Aggregations](https://thegraph.com/docs/en/cookbook/timeseries/)

6. [Use Grafting for Quick Hotfix Deployment](https://thegraph.com/docs/en/cookbook/grafting-hotfix/)
14 changes: 14 additions & 0 deletions website/pages/en/cookbook/derivedfrom.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,17 @@ This will not only make our subgraph more efficient, but it will also unlock thr
Adopting the `@derivedFrom` directive in subgraphs effectively handles dynamically growing arrays, enhancing indexing efficiency and data retrieval.

To learn more detailed strategies to avoid large arrays, read this blog from Kevin Jones: [Best Practices in Subgraph Development: Avoiding Large Arrays](https://thegraph.com/blog/improve-subgraph-performance-avoiding-large-arrays/).

## Subgraph Best Practices 1-6

1. [Improve Query Speed with Subgraph Pruning](https://thegraph.com/docs/en/cookbook/pruning/)

2. [Improve Indexing and Query Responsiveness by Using @derivedFrom](https://thegraph.com/docs/en/cookbook/derivedfrom/)

3. [Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs](https://thegraph.com/docs/en/cookbook/immutable-entities-bytes-as-ids/)

4. [Improve Indexing Speed by Avoiding `eth_calls`](https://thegraph.com/docs/en/cookbook/avoid-eth-calls/)

5. [Simplify and Optimize with Timeseries and Aggregations](https://thegraph.com/docs/en/cookbook/timeseries/)

6. [Use Grafting for Quick Hotfix Deployment](https://thegraph.com/docs/en/cookbook/grafting-hotfix/)
184 changes: 184 additions & 0 deletions website/pages/en/cookbook/grafting-hotfix.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
---
Subgraph Best Practice 6 - Use Grafting for Quick Hotfix Deployment
---

## TLDR

Grafting is a powerful feature in subgraph development that allows you to build and deploy new subgraphs while reusing the indexed data from existing ones. This technique is particularly useful for quickly deploying hotfixes to address critical issues without the need to re-index the entire subgraph from scratch. By preserving historical data, grafting ensures minimal downtime and maintains continuity in data services.

## Why Grafting Is a Best Practice for Hotfixes

1. **Rapid Deployment**

- **Minimize Downtime**: When a subgraph encounters a critical error and stops indexing, grafting enables you to deploy a fix immediately without waiting for re-indexing.
- **Immediate Recovery**: The new subgraph continues from the last indexed block, ensuring that data services remain uninterrupted.

2. **Data Preservation**

- **Reuse Historical Data**: Grafting copies the existing data from the base subgraph, so you don’t lose valuable historical records.
- **Consistency**: Maintains data continuity, which is crucial for applications relying on consistent historical data.

3. **Efficiency**
- **Save Time and Resources**: Avoids the computational overhead of re-indexing large datasets.
- **Focus on Fixes**: Allows developers to concentrate on resolving issues rather than managing data recovery.

## Best Practices When Using Grafting for Hotfixes

1. **Initial Deployment Without Grafting**

- **Start Clean**: Always deploy your initial subgraph without grafting to ensure that it’s stable and functions as expected.
- **Test Thoroughly**: Validate the subgraph’s performance to minimize the need for future hotfixes.

2. **Implementing the Hotfix with Grafting**

- **Identify the Issue**: When a critical error occurs, determine the block number of the last successfully indexed event.
- **Create a New Subgraph**: Develop a new subgraph that includes the hotfix.
- **Configure Grafting**: Use grafting to copy data up to the identified block number from the failed subgraph.
- **Deploy Quickly**: Publish the grafted subgraph to restore service as soon as possible.

3. **Post-Hotfix Actions**

- **Monitor Performance**: Ensure the grafted subgraph is indexing correctly and the hotfix resolves the issue.
- **Republish Without Grafting**: Once stable, deploy a new version of the subgraph without grafting for long-term maintenance.
- **Reason**: Relying on grafting indefinitely is not recommended as it can complicate future updates and maintenance.
- **Update References**: Redirect any services or applications to use the new, non-grafted subgraph.

4. **Important Considerations**
- **Careful Block Selection**: Choose the graft block number carefully to prevent data loss.
- **Tip**: Use the block number of the last correctly processed event.
- **Use Deployment ID**: Ensure you reference the Deployment ID of the base subgraph, not the Subgraph ID.
- **Note**: The Deployment ID is the unique identifier for a specific subgraph deployment.
- **Feature Declaration**: Remember to declare grafting in the subgraph manifest under features.

## Example: Deploying a Hotfix with Grafting

Suppose you have a subgraph tracking a smart contract that has stopped indexing due to a critical error. Here’s how you can use grafting to deploy a hotfix.

1. **Failed Subgraph Manifest (subgraph.yaml)**

```yaml
specVersion: 1.0.0
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: OldSmartContract
network: sepolia
source:
address: '0xOldContractAddress'
abi: Lock
startBlock: 5000000
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Withdrawal
abis:
- name: Lock
file: ./abis/OldLock.json
eventHandlers:
- event: Withdrawal(uint256,uint256)
handler: handleOldWithdrawal
file: ./src/old-lock.ts
```

2. **New Grafted Subgraph Manifest (subgraph.yaml)**
```yaml
specVersion: 1.0.0
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: NewSmartContract
network: sepolia
source:
address: '0xNewContractAddress'
abi: Lock
startBlock: 6000001 # Block after the last indexed block
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Withdrawal
abis:
- name: Lock
file: ./abis/Lock.json
eventHandlers:
- event: Withdrawal(uint256,uint256)
handler: handleWithdrawal
file: ./src/lock.ts
features:
- grafting
graft:
base: QmBaseDeploymentID # Deployment ID of the failed subgraph
block: 6000000 # Last successfully indexed block
```

**Explanation:**

- **Data Source Update**: The new subgraph points to 0xNewContractAddress, which may be a fixed version of the smart contract.
- **Start Block**: Set to one block after the last successfully indexed block to avoid reprocessing the error.
- **Grafting Configuration**:
- **base**: Deployment ID of the failed subgraph.
- **block**: Block number where grafting should begin.

3. **Deployment Steps**

- **Update the Code**: Implement the hotfix in your mapping scripts (e.g., handleWithdrawal).
- **Adjust the Manifest**: As shown above, update the subgraph.yaml with grafting configurations.
- **Deploy the Subgraph**:
- Authenticate with the Graph CLI.
- Deploy the new subgraph using `graph deploy`.

4. **Post-Deployment**
- **Verify Indexing**: Check that the subgraph is indexing correctly from the graft point.
- **Monitor Data**: Ensure that new data is being captured and the hotfix is effective.
- **Plan for Republish**: Schedule the deployment of a non-grafted version for long-term stability.

## Key Considerations

### When Not to Use Grafting

While grafting is a powerful tool for deploying hotfixes quickly, there are specific scenarios where it should be avoided to maintain data integrity and ensure optimal performance.

- **Incompatible Schema Changes**: If your hotfix requires altering the type of existing fields or removing fields from your schema, grafting is not suitable. Grafting expects the new subgraph’s schema to be compatible with the base subgraph’s schema. Incompatible changes can lead to data inconsistencies and errors because the existing data won’t align with the new schema.
- **Significant Mapping Logic Overhauls**: When the hotfix involves substantial modifications to your mapping logic—such as changing how events are processed or altering handler functions—grafting may not function correctly. The new logic might not be compatible with the data processed under the old logic, leading to incorrect data or failed indexing.
- **Deployments to The Graph Network**: Grafting is not recommended for subgraphs intended for The Graph’s decentralized network (mainnet). It can complicate indexing and may not be fully supported by all indexers, potentially causing unexpected behavior or increased costs. For mainnet deployments, it’s safer to re-index the subgraph from scratch to ensure full compatibility and reliability.

### Risk Management

- **Data Integrity**: Incorrect block numbers can lead to data loss or duplication.
- **Testing**: Always test grafting in a development environment before deploying to production.

## Conclusion

Grafting is an effective strategy for deploying hotfixes in subgraph development, enabling you to:

- **Quickly Recover** from critical errors without re-indexing.
- **Preserve Historical Data**, maintaining continuity for applications and users.
- **Ensure Service Availability** by minimizing downtime during critical fixes.

However, it’s important to use grafting judiciously and follow best practices to mitigate risks. After stabilizing your subgraph with the hotfix, plan to deploy a non-grafted version to ensure long-term maintainability.

## Additional Resources

- **[Grafting Documentation](/cookbook/grafting/)**: Replace a Contract and Keep its History With Grafting
- **[Understanding Deployment IDs](/querying/querying-by-subgraph-id-vs-deployment-id/)**: Learn the difference between Deployment ID and Subgraph ID in The Graph’s documentation.

By incorporating grafting into your subgraph development workflow, you can enhance your ability to respond to issues swiftly, ensuring that your data services remain robust and reliable.

## Subgraph Best Practices 1-6

1. [Improve Query Speed with Subgraph Pruning](https://thegraph.com/docs/en/cookbook/pruning/)

2. [Improve Indexing and Query Responsiveness by Using @derivedFrom](https://thegraph.com/docs/en/cookbook/derivedfrom/)

3. [Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs](https://thegraph.com/docs/en/cookbook/immutable-entities-bytes-as-ids/)

4. [Improve Indexing Speed by Avoiding `eth_calls`](https://thegraph.com/docs/en/cookbook/avoid-eth-calls/)

5. [Simplify and Optimize with Timeseries and Aggregations](https://thegraph.com/docs/en/cookbook/timeseries/)

6. [Use Grafting for Quick Hotfix Deployment](https://thegraph.com/docs/en/cookbook/grafting-hotfix/)
14 changes: 14 additions & 0 deletions website/pages/en/cookbook/immutable-entities-bytes-as-ids.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,17 @@ Query Response:
Using both Immutable Entities and Bytes as IDs has been shown to markedly improve subgraph efficiency. Specifically, tests have highlighted up to a 28% increase in query performance and up to a 48% acceleration in indexing speeds.

Read more about using Immutable Entities and Bytes as IDs in this blog post by David Lutterkort, a Software Engineer at Edge & Node: [Two Simple Subgraph Performance Improvements](https://thegraph.com/blog/two-simple-subgraph-performance-improvements/).

## Subgraph Best Practices 1-6

1. [Improve Query Speed with Subgraph Pruning](https://thegraph.com/docs/en/cookbook/pruning/)

2. [Improve Indexing and Query Responsiveness by Using @derivedFrom](https://thegraph.com/docs/en/cookbook/derivedfrom/)

3. [Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs](https://thegraph.com/docs/en/cookbook/immutable-entities-bytes-as-ids/)

4. [Improve Indexing Speed by Avoiding `eth_calls`](https://thegraph.com/docs/en/cookbook/avoid-eth-calls/)

5. [Simplify and Optimize with Timeseries and Aggregations](https://thegraph.com/docs/en/cookbook/timeseries/)

6. [Use Grafting for Quick Hotfix Deployment](https://thegraph.com/docs/en/cookbook/grafting-hotfix/)
14 changes: 14 additions & 0 deletions website/pages/en/cookbook/pruning.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ dataSources:
## Conclusion

Pruning using `indexerHints` is a best practice for subgraph development, offering significant query performance improvements.

## Subgraph Best Practices 1-6

1. [Improve Query Speed with Subgraph Pruning](https://thegraph.com/docs/en/cookbook/pruning/)

2. [Improve Indexing and Query Responsiveness by Using @derivedFrom](https://thegraph.com/docs/en/cookbook/derivedfrom/)

3. [Improve Indexing and Query Performance by Using Immutable Entities and Bytes as IDs](https://thegraph.com/docs/en/cookbook/immutable-entities-bytes-as-ids/)

4. [Improve Indexing Speed by Avoiding `eth_calls`](https://thegraph.com/docs/en/cookbook/avoid-eth-calls/)

5. [Simplify and Optimize with Timeseries and Aggregations](https://thegraph.com/docs/en/cookbook/timeseries/)

6. [Use Grafting for Quick Hotfix Deployment](https://thegraph.com/docs/en/cookbook/grafting-hotfix/)
Loading
Loading