# Introduction

Gravity is a high-performance Layer 1 blockchain with a native protocol-level oracle — built to be the world computer and the foundational harness for humans and their AI agents.

<figure><img src="/files/ClMoTQaNfFel4EQZ0qZE" alt=""><figcaption></figcaption></figure>

Introducing [Gravity](https://gravity.xyz/?utm_source=medium\&utm_medium=blog\&utm_campaign=gravitylaunch) — among the fastest EVM Layer 1 blockchains, with a native, protocol-level oracle. Gravity combines a parallel EVM execution layer with fast-finality BFT consensus and verified on-chain access to real-world data, giving developers a chain fast enough and connected enough to run the next generation of applications, like AI agents acting on behalf of users.

Gravity is built to be a **world computer**: a single, credibly neutral execution environment where applications run transparently, settle instantly, and read trustworthy external data without depending on off-chain middleware. As autonomous AI agents become first-class economic actors, Gravity serves as the **foundational harness that connects agents with one another and with the world** — a shared substrate where agents can transact, coordinate, and act on verified information with code-is-law guarantees.

## Gravity <a href="#id-18c8" id="id-18c8"></a>

At its core, Gravity pairs the fastest EVM execution available — [Gravity Reth](/research-and-development/greth) running the [Grevm](/research-and-development/grevm2) parallel execution engine — with a state-of-the-art, AptosBFT-derived consensus protocol that delivers high throughput and near-instant finality. This is the same foundation you can run yourself with the [Gravity SDK](/research-and-development/gravity-sdk-tutorial).

This work doesn't stay in our own fork. We are one of the most active external contributors to [Reth](https://github.com/paradigmxyz/reth), the upstream execution client maintained by Paradigm, and a number of our mempool and execution optimizations have already been merged back into the main repository — benefiting the entire Reth ecosystem, not just Gravity. See the [full list of upstreamed pull requests](/research-and-development/greth#high-throughput-mempool) for details.

What sets Gravity apart is its **native oracle**, built into the protocol rather than bolted on as a set of smart contracts. The chain itself can fetch and verify external data — state from other blockchains, JWK providers for keyless authentication, DNS, and on-demand requests — and make it available on-chain with the same security guarantees as the rest of consensus. For AI agents and high-stakes applications, this turns the chain into a trustworthy bridge between on-chain logic and real-world inputs.

Gravity is fully EVM-compatible, so existing Ethereum tooling, contracts, and wallets work without modification.

## Key Features of Gravity <a href="#id-637a" id="id-637a"></a>

* **High-Performance Execution:** Gravity integrates the fastest EVM execution layer, Gravity Reth, with the Grevm parallel execution engine and an AptosBFT-derived consensus protocol — together delivering high throughput and near-instant finality. On a live 3-validator cluster (8 vCPU / 16 GB nodes), Gravity sustains **\~9.5k–11k TPS** of ERC20 transfers with **\~200 ms** block times. See the [3-validator cluster benchmark results](/research-and-development/benchmark-results) for the full setup and methodology.
* **Native Oracle:** A protocol-level oracle brings verified external data on-chain — other blockchains, JWK providers, DNS, and on-demand requests — without relying on off-chain middleware.
* **A Harness for AI Agents:** Fast finality, low fees, and trustworthy data access make Gravity a natural execution and coordination layer for autonomous agents acting on behalf of users.
* **EVM Compatibility:** Gravity is fully EVM-compatible, allowing developers to deploy and interact with smart contracts seamlessly.

## Use Cases <a href="#d11f" id="d11f"></a>

* **Autonomous AI Agents:** Agents need a place to hold assets, transact, and coordinate with other agents while reading verified real-world data. Gravity's fast finality and native oracle make it a credible execution and settlement layer for agent-to-agent and agent-to-world interactions.
* **On-Chain Applications with Real-World Data:** Because the oracle is part of consensus, applications can depend on external data — prices, cross-chain state, identity attestations — without trusting a separate middleware operator. This unlocks fully on-chain markets such as perpetual DEXs and prediction markets, where fast, verifiable price and outcome data is the core of the product rather than an afterthought.
* **High-Throughput dApps:** Parallel execution and near-instant finality support consumer-scale applications that would be infeasible on slower chains, shifting mission-critical logic from private, unauditable backends onto an open, code-is-law database.
* **Keyless & Passkey Accounts:** Native JWK verification and secp256r1 precompiles let developers build wallets and account-abstraction flows that authenticate with passkeys and familiar identity providers.

## Network <a href="#id-51ef" id="id-51ef"></a>

Gravity Mainnet (L1) is live as the production chain (chain ID `127001`) — see [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) to connect. A public [Gravity Longevity Testnet (L1)](/gravity-networks/l1-longevity-testnet) is available for development.

Gravity originally launched in 2024 as the Gravity Alpha Mainnet, an Ethereum rollup on the Arbitrum Nitro stack (chain ID `1625`). That network is still operational and its documentation is preserved under [Legacy: Alpha Mainnet (L2)](/legacy-alpha-mainnet-l2/legacy-l2), but new development should target L1.

{% hint style="danger" %}
**Holding assets on Gravity Alpha Mainnet (L2)? Bridge them out before November 1, 2026.**

The Alpha Mainnet (L2) is being deprecated in favor of L1 and will be unsettled in **December 2026**. Move **all** assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).

Note that different assets use different exit routes: **USDC, USDT and ETH/WETH can only leave via** [**Stargate**](https://stargate.finance/bridge) — the canonical bridge cannot withdraw them. Native withdrawals of G, DAI and WBTC go through the [Gravity Bridge](https://bridge.gravity.xyz/) and take \~7 days, so start early.
{% endhint %}

## Join Us <a href="#id-0f90" id="id-0f90"></a>

The universe cannot exist without gravity; it's the cosmic glue that holds everything together. Similarly, Gravity is the foundational layer that will empower the next era of the Internet — and the agents that increasingly run on it — to grow and thrive. Join us as we venture into this exciting new phase to transform the future of the Internet.

For more information, visit [gravity.xyz](https://gravity.xyz/?utm_source=medium\&utm_medium=blog\&utm_campaign=gravitylaunch), and follow Gravity on X for the latest updates: [@GravityChain](https://x.com/GravityChain).


# Ecosystem VC Alliance

Eligibility and Application Guide for the Gravity Ecosystem VC Alliance

<figure><img src="/files/E8V8NS1xaGCXrlHrsyN2" alt=""><figcaption></figcaption></figure>

The Gravity Ecosystem VC Alliance is a $50 million initiative designed to support projects building on the Gravity blockchain. Backed by leading VCs and blockchain investors, it provides developers with the resources and capital needed to leverage Gravity's advanced features, such as high throughput, sub-second finality, and a native protocol-level oracle, to create scalable and high-performance decentralized solutions.

## Eligibility Criteria

To qualify for the Gravity Ecosystem VC Alliance, projects must meet the following requirements (subject to change):

* Native Integration: Projects must build directly on the Gravity blockchain, leveraging its core features like sub-second finality and omnichain functionality.
* Ecosystem Alignment: Applicants should utilize native Gravity assets and collaborate meaningfully with existing ecosystem partners.
* Priority Focus Areas: DeFi (lending, derivatives, yield aggregators, DEXs, or bridges), payments (financial tools or payment systems), Telegram Mini Apps/Games, loyalty solutions (projects using Gravity’s Loyalty Point-as-a-Service), and onchain quests (fully decentralized gamified systems).

Approved applicants to the Ecosystem VC Alliance will gain direct access to Gravity's network of investors. Each project will receive personalized attention, with investors offering tailored support based on the project's needs and growth potential.

## Application Procedure

To apply for the Gravity Ecosystem VC Alliance, follow these steps:

1. Submit the Application: Applicants submit the [form](https://contact.gravity.xyz/GravityEcosystemVCAlliance).
2. Project Screening: Gravity will source and screen projects, sharing the selected opportunities with the Alliance members.
3. Review Process: The Gravity team reviews on a rolling basis and the deadline is on the 15th (GMT+8) of every month. Applications submitted after the most recent deadline will be reviewed for the following one.
4. Sharing with the VC Alliance: The selected projects’ information is shared with the Alliance members within two weeks after the cutoff.
5. Alliance Review: Alliance members will review the projects and respond within 10-15 working days to indicate their interest.
6. Direct Communication: Projects will then engage directly with interested Alliance members to structure the deal.


# Developer Grant Program

Explore Gravity's $5 million grant program funding developers building on Gravity with up to $200K plus ecosystem support for qualified projects.

On December 2, 2024, G DAO approved [Proposal GP35](https://dao.galxe.com/#/proposal/0x4b3def5d4f11e32de95e6e31a8eb0ff5853dd5cd6ff0d4ce037f71153b352ec2), securing a $5 million budget to fund strategic initiatives within the Gravity ecosystem.

The Gravity Developer Grant Program is a funding initiative designed to support developers and innovators in building applications within the Gravity ecosystem. By empowering builders, Gravity aims to enable the development of tools like decentralized applications, developer infrastructure, and community-driven projects that address user needs, encourage collaboration, and contribute to the ecosystem’s continuous growth.

## Build with Gravity

Gravity invites developers and teams to join our ecosystem, utilizing our high-performance infrastructure to build scalable dApps that can drive real-world adoption. To be eligible for the Developer Grant Program, projects must meet one or more of the following criteria:

* Built for [Gravity](https://gravity.xyz/): Projects should either run exclusively on the Gravity Chain or designate Gravity as a primary network in their architecture.
* Mainnet Availability: Projects must have a fully functional Mainnet version that is live and accessible to users.
* Clear Development Roadmap: For projects that are not yet live, a detailed go-to-market (GTM) plan is required. The plan should include development timelines, strategies for acquiring users, and clear launch goals.

## Pioneering the Next Phase of Web3

The Developer Grant Program is dedicated to accelerating the development of technologies and tools that drive significant impact within the ecosystem. This includes, but is not limited to, the following key areas:

* Ecosystem dApps: Projects that build directly on Gravity.
* Infrastructure Growth: Solutions that reinforce the network, such as:
  * Wallet systems
  * Centralized exchange support for Gravity Alpha Mainnet
  * Data analytics tools and ranking platforms
  * RPC, API, and Indexer services
  * Stablecoins
  * Security and Bounty Programs: Initiatives aimed at securing the network through bug bounty programs and advanced security infrastructure.

## Applying for the Developer Grant Program

To apply for the Gravity Developer Grant Program, submit your application using the form [here](https://contact.gravity.xyz/GravityGrantApplication). In your application, be sure to include the following:

* Project Background: Explain the context behind your project, including how it was built or your plan for growing your user base.
* Problem and Solution: Describe the problem your project is addressing and the solution you are proposing.
* Impact on the Gravity Ecosystem: Highlight how your project will contribute to and benefit the Gravity ecosystem.

Applications are reviewed on a rolling basis by the Gravity team. If your project aligns with our objectives, our technical team may reach out for a more in-depth discussion or to conduct due diligence. All applicants will receive application results via email. Successful applicants will work with the Gravity legal team to finalize the funding agreement.

## Grant Allocation

The Developer Grant Program offers a wide range of funding opportunities, with a maximum amount of $200K (equivalent in G tokens). The allocation of grants will be governed through the [G DAO](https://forum.gravity.xyz/)’s governance process.

Beyond funding, we provide extensive ecosystem support to ensure the success of your project. This includes:

* Marketing & Strategy: Access to co-marketing opportunities to boost visibility, premium client strategies, and enhanced services for Galxe quests. We also offer expert guidance for go-to-market planning and advisory.
* Exclusive Network Access: Your project will gain entry to over 6,000 partners within the Galxe ecosystem, opening doors for valuable collaborations and significant growth opportunities.

Our aim is to offer both the resources and connections needed to help your project thrive and make a lasting impact on the Gravity ecosystem. Submit your application through our form [here](https://tally.so/r/wzQ97Z) to get started.


# Community Program: Galactic G

Discover Galactic G - the badge for Gravity's passionate supporters. Learn how to become a community leader through engagement, creativity, and advocacy to gain exclusive privileges.

The Galactic G isn’t just a role—it’s a badge of honor, earned by the most passionate, dedicated, and unstoppable supporters of Gravity. It symbolizes true community, reserved for those real Gs who consistently show up, stand out, and push Gravity forward. Galactic G holders are the core genius of Gravity—early adopters, update trackers, and ultimate believers.

They don’t just keep the G staked; they keep it alive in their hearts.

Scarce and exclusive, this role brings prestige, perks, and the power to lead the charge as the voice of the community.

If you’ve got the G, you’re not just a supporter—you’re a trailblazer. Stay bold. Stay Galactic.

***

## Communication & Engagement

To become a Galactic G and maintain your status, participation is key. Members aspiring to join this elite group must actively engage in meaningful, organic conversations within the server that inspire and motivate others.

* Discussions can range from humorous to technical but must align with community guidelines.
* Avoid repetitive or generic messages like "gm" or "hello."
* Participate in community events such as Gravity Quizzes, community calls, and more.

Galactic Gs set the standard for vibrant, engaging dialogue that fosters community growth.

***

## Creativity & Art

Unleash your creativity and showcase your talents!

* Share original memes, art, and fun content on the server and social media platforms.
* Design stickers, emojis, GIFs, and other artwork inspired by the Gravity theme.
* Exceptional contributions may be rewarded with special recognition, perks, or roles.

Creativity is boundless—let your imagination lead the way!

***

## Social Media Presence

Galactic G members are Gravity's ambassadors, spreading the word across social media platforms.

* Post about Gravity on platforms like X (Twitter), Medium, or Warp Cast at least twice weekly.
* High-quality posts may be highlighted or reshared by Gravity’s official accounts.

Be the voice that amplifies Gravity’s vision across the galaxy!

***

## Community Missions

Contribute to the collective mission and shine as a Galactic G!

* Participate in general missions, which may include creating memes, artwork, or posts about collaborations.
* Engage in special weekly missions designed to challenge and inspire.

Your involvement directly shapes the community’s energy and momentum.

***

## Pulsar Collaborative Events

Elevate your engagement and join forces with Pulsars!

* Host and organize exclusive events with Pulsar collaborators.
* Access a dedicated channel for Galactic Gs, featuring exclusive chats and missions.

This is your chance to lead, collaborate, and make an impact.

Become a Galactic G and join the ranks of those shaping Gravity’s future. Together, we’ll build something extraordinary.

Feeling the pull of Gravity? Join our [Discord community ](https://discord.gg/Gravity-Chain)and start your journey toward becoming a Galactic G today.


# G Token

Powering the future of Web3. G is the native token on Gravity, and the utility token of both Gravity and the Galxe ecosystem.

<figure><img src="/files/MzAVDPAdkY3YaFZeLP80" alt=""><figcaption></figcaption></figure>

## **GAL -> G Migration**

With the approval of proposals [GP-25](https://dao.galxe.com/#/proposal/0x8d3f386c3b0cb9fa170d4231c65f18bd45ea1402b90a70116e1101c22e62ed01) and [GP-30](https://dao.galxe.com/#/proposal/0xa6af134cd0522ea34d2d6485a557fafdb01cc7f32726f409bd8f399cc2af2514) by the Galxe DAO community, we’re migrating the Galxe (GAL) token to Gravity (G), unifying and streamlining the experience across both ecosystems. This upgrade focuses on enhancing the user journey, integrating the token seamlessly across our Layer 1 and the Galxe ecosystem, and simplifying the ticker for easier recognition. G will serve as the universal token, providing utility in governance, transactions, and incentives across the entire ecosystem. Read this article to learn more about [the token migration](https://gravity.xyz/blog/gal-g).

[The migration portal is available](https://app.galxe.com/gal-token-migration) for all GAL holders to migrate their existing GAL to G.

## **What is G Token?**

G is the native token on Gravity and the utility token for both Gravity and the Galxe ecosystem. G powers transactions as the gas token and secures the network through staking. As the primary utility token across both ecosystems, G drives governance decisions, incentivizes growth, and facilitates payments.

## G Token

### As the Native Token

* G is the native coin of **Gravity Mainnet (L1)** (chain ID `127001`, now live) and of the legacy **Gravity Alpha Mainnet (L2)**.

### Genesis Allocation on Gravity Mainnet (L1)

At Gravity Mainnet (L1) genesis, **7,000,000 G** was allocated as initial validator stake across the seven launch validators:

| Validator   |   Genesis stake |
| ----------- | --------------: |
| Validator-1 |     1,000,000 G |
| Validator-2 |     1,000,000 G |
| Validator-3 |     1,000,000 G |
| Validator-4 |     1,000,000 G |
| Validator-5 |     1,000,000 G |
| Validator-6 |     1,300,000 G |
| Validator-7 |       700,000 G |
| **Total**   | **7,000,000 G** |

To back this allocation, a matching **7,000,000 G** was locked on Ethereum mainnet in the canonical bridge's `GBridgeSender` contract ([`0xE82c61Ac9Ec2041b493118051afa4F18a55dC876`](https://etherscan.io/address/0xE82c61Ac9Ec2041b493118051afa4F18a55dC876)). G held by the GBridgeSender is permanently locked to back native G on L1 and **should be considered burned** from the circulating ERC-20 supply. This is a one-time genesis bootstrap and will not recur.

**Transaction:** [`0xa1c2e4ec30a116a8c7f752c674a3a07c635d92cbdc7edca6055c8ed2b21fcff2`](https://etherscan.io/tx/0xa1c2e4ec30a116a8c7f752c674a3a07c635d92cbdc7edca6055c8ed2b21fcff2) — 7,000,000 G transferred to the GBridgeSender on 2026-05-28.

### As ERC-20 Token

* Token Name: **Gravity**
* Token Symbol: **G**
* Initial Total Supply: 12,000,000,000 G
* Decimal: 18
* ERC-20 Contract Address: `0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649`
* Token Icon: <https://assets.gravity.xyz/token_logo.png>, or [visit this link](https://gal.xyz/brand) for different versions
* **Currently Available Networks:**
  * [**Ethereum**](https://etherscan.io/token/0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649#code)
    * Contract owner: [Safe multi-sig on Ethereum](https://etherscan.io/address/0xbD6e434dB90FD8AD4E28d85C133AD34cA6fbfB6D)
    * Initial supply: 10,000,000,000 G
    * Current supply: 11,526,557,260 G, including G tokens already bridged to the Gravity Alpha Mainnet. So the actual supply is `11,526,557,260 G - num_bridged G`
      * Rebalance Event 1: Receiving 1,515,000,000 G From BNB Chain. <https://etherscan.io/tx/0xfeacc21c6ff2863bd1f54c945b48395dd120c51699ac84c459362999cebdb4ef>
      * Rebalance Event 2: Sending 10,000,000 G To Base.\
        <https://etherscan.io/tx/0x343d58b7e6b9a83a5d512e2d1f33dd0d19cf465c0409f15f5c446adf04204528>
      * Rebalance Event 4 (Ethereum Token Upgrader): Receiving 21,557,260 G From BNB Chain Token Upgrader <https://etherscan.io/tx/0xb138a6e3edb88623dfe0c9ac9da4f15b48ce56c8fb42f168650e8eeadb6bc399>
    * Gravity Alpha Mainnet (L2), i.e. `num_bridged G`
      * As a rollup on the Ethereum mainnet, G tokens bridged to the Gravity Alpha Mainnet are locked in [this contract](https://etherscan.io/address/0x7983403dda368aa7d67145a9b81c5c517f364c42): `0x7983403dda368aa7d67145a9b81c5c517f364c42`, utilizing the Arbitrum standard ERC-20 gateway.
      * The number of G tokens is dynamic, fluctuating as users bridge tokens in and out of the L2. You can view the real-time number by checking the G token balance of the [contract address](https://etherscan.io/address/0x7983403dda368aa7d67145a9b81c5c517f364c42) above.
    * Gravity Mainnet (L1), i.e. G locked in the canonical L1 bridge
      * G bridged to Gravity Mainnet (L1) is locked in the `GBridgeSender` contract [`0xE82c61Ac9Ec2041b493118051afa4F18a55dC876`](https://etherscan.io/address/0xE82c61Ac9Ec2041b493118051afa4F18a55dC876) and **should be considered burned** from the circulating ERC-20 supply — it is permanently locked to back native G on L1. This includes the one-time 7,000,000 G genesis backing (see [Genesis Allocation on Gravity Mainnet (L1)](#genesis-allocation-on-gravity-mainnet-l1)).
  * [**BNB Chain**](https://bscscan.com/token/0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649#code)
    * Contract owner: [Safe multi-sig on BNB Chain](https://bscscan.com/address/0xBB86C74ecCA362D007293EE8A2E24E9De0B9E558)
    * Initial supply: 2,000,000,000 G
    * Current supply: 458,442,740 G
      * Rebalance Event 1: Sending 1,515,000,000 G To Ethereum <https://bscscan.com/tx/0xc144061a9a04099b2e004c7c2f713f8267b32332bc72c0c944c483cbf8776fb9>
      * Rebalance Event 3: Sending 5,000,000 G to Base <https://bscscan.com/tx/0x2238d2181ef36cdc8cb9cfca70e5ad13ae1de9a6fa96a90860e8fe22e68c1c39>
      * Rebalance Event 4 (BNB Chain Token Upgrader): Sending 21,557,260 G to Ethereum Token Upgrader <https://bscscan.com/tx/0x9f9f6777593fb1e78776fab4e364ba1569ced2026e467964da9374a4dd357707>
  * [**Base**](https://basescan.org/token/0x9c7beba8f6ef6643abd725e45a4e8387ef260649#code)
    * Contract owner: [Safe multi-sig on Base](https://basescan.org/address/0x08bDCC846D80d81eF6e058bB64228Ec58CA6726a)
    * Initial supply: 0 G
    * Current supply: 15,000,000 G
      * Rebalance Event 2: Receiving 10,000,000 G From Ethereum <https://basescan.org/tx/0x3e3341ce3a9e2f9e7098dea8ae7935e74c5711630af56fcb010b681da92d5de3>
      * Rebalance Event 3: Receiving 5,000,000 G From BNB Chain <https://basescan.org/tx/0x9abe5c88c3e4bc36214d5141b3b13cddefb658e0c5cbba14ce5ef8002b360d45>
* Audit report

{% file src="/files/PcnWrGpAkK9N2RF2SQy9" %}

### As LayerZero OFT

{% hint style="warning" %}
**Legacy:** The LayerZero OFT deployment described below is legacy and is no longer actively used.
{% endhint %}

For chains that do not have G token contract deployed natively, we use LayerZero's OFT standard to bring G tokens to those chains.

* Token Name: `GravityTokenG (OFT)`
* Token Symbol: `G.oft`

Deployed networks:

* [**Polygon**](https://polygonscan.com/address/0x7653235DA659c8e573B365B16EE95b847A1777ba)
  * Owner: [Safe multi-sig on Polygon](https://polygonscan.com/address/0x897a91caf592c42fcc953da16890c50372e63c61)
  * Initial supply: 0 G (minted on-demand by bridging from Ethereum mainnet)

Security configurations:

* [OFT Adapter](https://etherscan.io/address/0x71c066fd4949C44B2cB2f509E2CD2421FbD36bca) on Ethereum mainnet: `0x71c066fd4949C44B2cB2f509E2CD2421FbD36bca`
  * Owner: [Safe multi-sig on Ethereum](https://etherscan.io/address/0xbD6e434dB90FD8AD4E28d85C133AD34cA6fbfB6D)
* Ethereum -> Polygon
  * Confirmation required: 15
  * [LayerZero Labs](https://docs.layerzero.network/v2/developers/evm/technical-reference/dvn-addresses#layerzero-labs): `0x589dEDbD617e0CBcB916A9223F4d1300c294236b`
  * [Google Cloud](https://docs.layerzero.network/v2/developers/evm/technical-reference/dvn-addresses#google-cloud): `0xD56e4eAb23cb81f43168F9F45211Eb027b9aC7cc`
* Polygon -> Ethereum
  * Confirmation required: 512
  * [LayerZero Labs](https://docs.layerzero.network/v2/developers/evm/technical-reference/dvn-addresses#layerzero-labs): `0x23DE2FE932d9043291f870324B74F820e11dc81A`
  * [Google Cloud](https://docs.layerzero.network/v2/developers/evm/technical-reference/dvn-addresses#google-cloud): `0xD56e4eAb23cb81f43168F9F45211Eb027b9aC7cc`

### **Bridging G Between Networks**

**To Gravity Mainnet (L1, `127001`):** only the official [Gravity Native Bridge](https://bridge.gravity.xyz/) (Mainnet tab) supports L1 today — Ethereum → Gravity L1. The third-party routes below are being migrated to L1; until then they reach the legacy L2 only. Full guide: [How to Get G](/the-g-token/how-to-get-g).

**To Gravity Alpha Mainnet (L2, `1625`):**

* [Gravity Alpha Mainnet official canonical bridge](https://bridge.gravity.xyz/) (Legacy L2 tab) for Ethereum <> Gravity Alpha Mainnet
* [Symbiosis](https://app.symbiosis.finance/swap?amountIn\&chainIn=BNB\&chainOut=Gravity\&tokenIn=0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649\&tokenOut=G) for other networks

{% hint style="info" %}
**There is no canonical bridge between the Ethereum, BNB Chain and Base deployments of G.** Those three ERC-20s are independent deployments that happen to share the same address; each has its own owner multisig, and none of them is an omnichain (OFT) token. The **Rebalance Events** listed above are manual treasury transfers between deployments, not a user-accessible route.

To move G between those chains, use a third-party liquidity route (for example [Symbiosis](https://app.symbiosis.finance/swap)) or a centralized exchange. These are swaps against pooled liquidity, not canonical bridging.
{% endhint %}

### **Token Release Schedule**

Please [refer to this table](https://docs.google.com/spreadsheets/d/e/2PACX-1vQKC7RmjjYkPbgPWbY9XPTiZFBgLHDQnQJaKszhiu80AAKIoS4gf6E1C20I55a3JFNm7V5HDF9giCmW/pubhtml) for the completed **token release schedule of G**.

To find the previous token release schedule of GAL, [visit this table](https://gal.org/token-table).

### How to get G

> For getting native **G on Gravity Mainnet (L1)**, follow [How to Get G](/the-g-token/how-to-get-g) — the canonical L1 guide. Some on-chain links below currently route to the legacy **Alpha Mainnet (L2)** and are being migrated to L1.

* Buy G with credit card
  * [Alchemy Pay](https://ramp.alchemypay.org/?appId=Ds23NPiP1aeapVES#/index)
  * [Onramp Money](https://onramp.money/main/buy/?appId=1\&coinCode=g\&network=erc20)
* Get G on supported exchanges
  * Find the list of supported exchanges on [CoinMarketCap](https://coinmarketcap.com/currencies/gravity-token/) or [CoinGecko](https://www.coingecko.com/en/coins/gravity)
* Get G onchain
  * [Jumper Exchange](https://jumper.exchange/?fromChain=1\&toChain=1625\&toToken=0x0000000000000000000000000000000000000000)
  * [Uniswap](https://app.uniswap.org/explore/tokens/ethereum/0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649)
  * [Symbiosis](https://app.symbiosis.finance/swap?amountIn\&chainIn=Ethereum\&chainOut=Gravity\&tokenIn=ETH\&tokenOut=G)
  * [Gas.zip](https://www.gas.zip/)
  * [Comet](https://cometbridge.app/instantGas)
  * If you have a balance in any vault in [Smart Saving](https://app.galxe.com/SmartSavings), click the corresponding vault and choose to receive the withdrawal token as G

### API

To get G supplies:

* **Total Supply:** <https://api.galxe.com/services/g-supply/total>
* **Circulating Supply:** <https://api.galxe.com/services/g-supply/circulating>

## **G Utilities**

Beyond migrating the existing utilities from GAL, G will expand its range of applications to serve all users within our ecosystems. Here are the key functionalities of G:

* **Staking:** Stake G to actively participate in governance, secure the network, and contribute to the long-term sustainability of both the Gravity and Galxe ecosystems. Additionally, G stakers gain convenient access to exclusive rewards from applications built by Galxe.
* **Governance:** G DAO is governed by G holders. Acting as a transparent, secure, and decentralized framework, G DAO fosters unity and progress among its members.
* **Transacting:** As the native gas token of Gravity Chain, G is used for executing and paying for all onchain transactions.
* **Payments:** As the utility token in the Galxe ecosystem, G is used to pay fees for applications built by Galxe, including Galxe Quest, Galxe Passport, Galxe Score, Alva, and more.

### Additional Examples of G Utilities in the Galxe Ecosystem

* **Galxe Shop**

  Shop from thousands of online merchants and earn cash back in G. Galxe Shop offers a seamless and rewarding shopping experience, exclusive to the Galxe community.
* **Galxe Earn**

  G stakers may be eligible for exclusive airdrops from partners within the Galxe ecosystem. Powered by Galxe Quest, Galxe Earn facilitates direct engagement and smarter distribution of rewards.


# How to Get G

How to bridge G to Gravity L1, buy G on exchanges, or migrate from Alpha Mainnet (L2).

You need native G on Gravity L1 to pay gas, stake, or participate in governance. This page covers the three realistic routes: the **canonical bridge from Ethereum**, **direct withdrawals from centralized exchanges**, and **migration from Alpha Mainnet (L2)**.

{% hint style="info" %}
This page is the L1 view. The Alpha Mainnet (L2) bridging guide is preserved at [How to Get G (Gravity Alpha, L2)](/legacy-alpha-mainnet-l2/bridge-to-gravity) and remains valid for anyone still using L2.
{% endhint %}

## Option 1: Canonical bridge from Ethereum

{% hint style="warning" %}
**The canonical bridge is one-way today.** It moves G from Ethereum to Gravity L1 only — there is currently no route to bridge native G from Gravity L1 back to Ethereum. The return leg is on the roadmap. Only bridge what you intend to keep on L1.
{% endhint %}

The canonical bridge locks ERC-20 G on Ethereum and issues native G on Gravity L1 at a 1:1 ratio. End-to-end takes a few minutes once the Ethereum transaction is confirmed. The bridge consists of two contracts on Ethereum — `GravityPortal` (the generic message outbox) and `GBridgeSender` (which locks the user's G ERC-20 and forwards the bridge message to the Portal) — paired with the `GBridgeReceiver` contract on Gravity L1 (deployed at genesis) that mints native G once the consensus engine relays the verified message through the native oracle. Contract addresses are listed in [Gravity Mainnet (L1) Contracts](/developer-resources/mainnet#cross-chain-bridge).

{% hint style="info" %}
**Bridge UI:** The unified [Get G portal](https://bridge.gravity.xyz/) at `bridge.gravity.xyz` is the single entry point for bridging G to Gravity. See the [Get G One Portal](https://gravity.xyz/blog/get-g-one-portal-every-option-to-acquire-g-tokens) announcement for all options.
{% endhint %}

### Step-by-step

1. Hold G as ERC-20 on Ethereum at [`0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649`](https://etherscan.io/token/0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649) (buy on a CEX, on Uniswap, etc.).
2. Open the canonical bridge UI (see the box above) and connect your wallet.
3. Approve the bridge contract to spend your G.
4. Send the bridge transaction, paying the ETH bridge fee on Ethereum.
5. Wait for the bridge to relay your message to L1; native G arrives at your recipient address shortly after Ethereum finality.

## Option 2: Centralized exchanges

G is currently listed on Binance, OKX, Bitget, KuCoin, MEXC, and BitMart, with deposits and withdrawals available on Ethereum (and on Mantle L2 on some). Once an exchange adds direct Gravity L1 support, you can withdraw native G to your L1 address in a single step. Until then, withdraw G as ERC-20 to Ethereum and follow **Option 1** to bridge in. Confirm the network the exchange uses — L1 vs Ethereum vs Alpha Mainnet (L2) — before withdrawing.

For the up-to-date exchange list, see [CoinMarketCap](https://coinmarketcap.com/currencies/gravity-token/), [CoinGecko](https://www.coingecko.com/en/coins/gravity), or the [Get G portal announcement (April 2025)](https://gravity.xyz/blog/get-g-one-portal-every-option-to-acquire-g-tokens).

## Option 3: Migrate from Alpha Mainnet (L2) to L1

If you hold native G on Alpha Mainnet (L2, Chain ID `1625`):

1. Use the [L2 canonical bridge](https://bridge.gravity.xyz/) to withdraw your G back to Ethereum. The L2 rollup's optimistic-challenge period means this leg takes \~7 days.
2. Once the G ERC-20 is back on Ethereum, follow **Option 1** above to bridge into L1.

Direct L2-to-L1 routing may be added through third-party aggregators; check current options at [Jumper](https://jumper.exchange/) or [Symbiosis](https://app.symbiosis.finance/) when L1 is listed.

## Other ways to acquire G

* **Fiat onramps** — Buy G with credit card, bank transfer, or local payment methods through [Onramp.money](https://onramp.money/) or [Alchemy Pay](https://ramp.alchemypay.org/). These currently deliver G ERC-20; bridge to L1 using **Option 1**.
* **Cross-chain aggregators** — [LI.FI](https://li.fi/) supports moving G across 37+ networks; once L1 is a routing destination, you can bridge from any supported source chain in a single transaction.

## After you have G on L1

* Add the network to your wallet — see [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet).
* Stake or delegate — see [G Token](/the-g-token/g-token#g-utilities).
* Explore the ecosystem — see [Wallets & Exchanges](/ecosystem-infrastructures/supported-wallets) and [Cross-chain Interoperability](/ecosystem-infrastructures/cross-chain-interoperability).

## See also

* [G Token](/the-g-token/g-token) — token overview and utilities.
* [Token Contracts on Gravity](/the-g-token/token-contracts) — L1 ERC-20 list (wG, USDT, USDC, …).
* [How to Get Test Tokens](/the-g-token/how-to-get-test-tokens) — for the Longevity Testnet (L1).


# How to Get Test Tokens

## Claiming Test Tokens

The Gravity Faucet provides test tokens for both Testnet (L2) and Testnet (L1).

### Request Limits

* 1 G token per address every 24 hours
* Separate limits for Testnet (L2) and Testnet (L1)

### Testnet (L2) vs Testnet (L1)

| Environment      | Layer   | Purpose              | ChainID |
| ---------------- | ------- | -------------------- | ------- |
| **Testnet (L2)** | Layer 2 | Testing applications | 13505   |
| **Testnet (L1)** | Layer 1 | Development          | 7771625 |

### How to Claim

1. Visit <https://faucet.gravity.xyz/>
2. Connect your wallet
3. Select network (Testnet (L2) or Testnet (L1))
4. Request tokens


# Token Contracts on Gravity

Canonical ERC-20 token contracts on Gravity L1.

This page is the authoritative list of canonical ERC-20 token contracts on Gravity L1. The list is populated as tokens are bridged in and deployed.

{% hint style="info" %}
For the Alpha Mainnet (L2, Chain ID `1625`) token list — which has G / wG / WBTC / DAI / ETH(WETH) / USDT / USDC — see [Token Contracts on Gravity Alpha (L2)](/legacy-alpha-mainnet-l2/token-contracts-on-gravity). Addresses below are for **L1 only** and are different from the L2 addresses.
{% endhint %}

## Native token

| Token | L1 address                      | Notes                                                                                                                                                                                      |
| ----- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| G     | Native coin — no ERC-20 address | Used for gas, staking, and governance. Bridged from Ethereum ERC-20 `0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649` via the canonical bridge (see [How to Get G](/the-g-token/how-to-get-g)). |

## Bridged assets

These addresses are populated as the canonical bridge goes live for each asset. Each entry lists the canonical L1 address, the Ethereum source contract, and the official bridge route used.

| Token                 | L1 address                                   | Ethereum source                                              | Official bridge    |
| --------------------- | -------------------------------------------- | ------------------------------------------------------------ | ------------------ |
| wG (Wrapped G)        | `0xBB859E225ac8Fb6BE1C7e38D87b767e95Fef0EbD` | native G on L1 (wrapper, not bridged from an external chain) | —                  |
| WETH.e (Bridged WETH) | `0x9Da9C5b2CBf7dcC773071338A6480e0E5FDee177` | Native ETH                                                   | wiring in progress |
| USDT.e (Bridged USDT) | `0x06Fd3e67231baea179676c490482372F7Fb4A3f2` | `0xdac17f958d2ee523a2206206994597c13d831ec7`                 | wiring in progress |
| USDC.e (Bridged USDC) | `0x979c024b381E25a093b8B4CEb06e74B8140664ff` | `0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`                 | wiring in progress |
| DAI                   | TBA                                          | `0x6B175474E89094C44Da98b954EedeAC495271d0F`                 | TBA                |
| WBTC                  | TBA                                          | `0x2260fac5e5542a773aa44fbcfedf7c193bc2c599`                 | TBA                |

{% hint style="warning" %}
**These three tokens are deployed but not yet usable.** USDC.e follows [Circle's Bridged USDC Standard](https://www.circle.com/bridged-usdc) (FiatToken v2.2 behind a proxy, upgradeable to native USDC by Circle later); USDT.e and WETH.e are Chainlink `BurnMintERC20` contracts. Until the bridge partner (Chainlink) completes the white-glove wire-up, total supply is 0, nothing can be minted, and no bridge route exists — do not integrate them as live assets or provide liquidity against them. Full deployment details and the permission model: [gravity-preinstalls](https://github.com/Galxe/gravity-preinstalls) (`docs/TOKEN_SECURITY.md`).
{% endhint %}

## Submitting a new token

Canonical tokens are tracked in the public [Galxe/gravity-token-list](https://github.com/Galxe/gravity-token-list) repository (`src/tokenlist.json`). To get your token added:

1. Deploy the ERC-20 on Gravity L1.
2. Fork [Galxe/gravity-token-list](https://github.com/Galxe/gravity-token-list).
3. Add an entry to `src/tokenlist.json` with `chainId: 127001`, address, symbol, decimals, and logo URI.
4. Open a PR following the template. The Gravity team reviews for basic sanity (no impersonation, verified contract, correct metadata).

## See also

* [G Token](/the-g-token/g-token) — native token overview.
* [How to Get G](/the-g-token/how-to-get-g) — bridging flow.
* [Gravity Mainnet (L1) Contracts](/developer-resources/mainnet) — system and bridge contract addresses.
* [Legacy L2 token list](/legacy-alpha-mainnet-l2/token-contracts-on-gravity) — Alpha Mainnet (L2) canonical list.


# Gravity Mainnet (L1)

Gravity Mainnet (L1) network reference — chain ID, RPC, explorer, bridge.

Gravity Mainnet is the production deployment of Gravity L1 — an EVM-compatible Layer 1 blockchain powered by AptosBFT consensus and a parallel EVM execution layer (Grevm on Gravity Reth), with a native on-chain oracle built into the protocol. This page is the canonical source of connection parameters for wallets, dapps, and infrastructure providers.

## Network Details

[*Add Gravity Mainnet to MetaMask*](https://chainlist.org/chain/127001)

* **Chain ID:** `127001`
* **Currency Symbol / Native Token:** `G`
* **Native token decimals:** `18`
* **RPC Endpoint:** <https://mainnet-rpc.gravity.xyz>
* **Block Explorer:** [https://mainnet-explorer.gravity.xyz](https://mainnet-explorer.gravity.xyz/) (Blockscout)
* **Chain Logo:** <https://assets.gravity.xyz/chain_logo.png>, or [visit this link](https://gal.xyz/brand) for different versions

## Add Gravity to your wallet

Gravity Mainnet can be added as a custom network to any EVM-compatible wallet (MetaMask, OKX Wallet, Trust Wallet, Rainbow, etc.). Use the one-click [ChainList entry](https://chainlist.org/chain/127001), or add manually using the values above.

## Getting G

You need G to pay gas on Gravity L1. See [How to Get G](/the-g-token/how-to-get-g) for bridging from Ethereum, CEX withdrawals, and migration from Alpha Mainnet (L2).

## RPC namespaces

The public endpoint exposes the standard Ethereum JSON-RPC surface (`eth`, `net`, `web3`). If your workload needs higher throughput than the public endpoint offers, consider running your own node or using one of the [Node Providers](/ecosystem-infrastructures/node-providers).

## See also

* [Gravity Mainnet Hardforks](/gravity-networks/mainnet-hardforks) — required node version and activation schedule.
* [Gravity Longevity Testnet (L1)](/gravity-networks/l1-longevity-testnet) — stable public testnet, Chain ID `7771625`.
* [G Token](/the-g-token/g-token) — native token overview.
* [Token Contracts on Gravity](/the-g-token/token-contracts) — L1 ERC-20 list.
* [Gravity Mainnet (L1) Contracts](/developer-resources/mainnet) — system and bridge contract addresses.
* [Legacy: Alpha Mainnet (L2)](/legacy-alpha-mainnet-l2/using-gravity-alpha-mainnet-l2) — for readers looking for the 2024 Arbitrum Nitro rollup (Chain ID `1625`).


# Gravity Mainnet Hardforks

Gravity Mainnet (L1) hardfork schedule, required node version, and what happens if a node misses an activation.

Mainnet (chain ID `127001`) activation times are compiled into the `gravity_node` release. Editing `genesis.json` does not change them. If genesis disagrees with the binary, the node keeps the binary value.

Validators, VFNs, and public full nodes must all run the required release before the next activation.

## Current required version

Upgrade to [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) before **2026-08-18 02:00:00 UTC**.

```bash
docker pull ghcr.io/galxe/gravity_node:v1.9.1
```

Source builds must `git checkout v1.9.1` before compiling. See the PFN, VFN, and validator run guides.

## Schedule

Newest first. Only the top row still requires action.

| Hardfork     | Activation (UTC)    | Unix         | First release                                                      |
| ------------ | ------------------- | ------------ | ------------------------------------------------------------------ |
| Beta + Osaka | 2026-08-18 02:00:00 | `1787018400` | [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) |
| Alpha        | 2026-07-27 05:00:00 | `1785128400` | [v1.8.0](https://github.com/Galxe/gravity-sdk/releases/tag/v1.8.0) |
| Prague       | 2026-06-29 05:00:00 | `1782709200` | [v1.7.3](https://github.com/Galxe/gravity-sdk/releases/tag/v1.7.3) |

## If you miss a hardfork

A node still on the previous rules executes the new schedule differently. The first block whose local execution hash does not match the committed hash stops the process. That block may be the activation block, or a later block.

This is fail-stop: the node does not keep serving a private fork. RPC height stops increasing.

Search logs for:

```
commit_info mismatch
Block hash mismatch
assertion `left == right` failed
```

There is no dedicated "hardfork missed" message. The failure is the same hash mismatch used for any execution-spec divergence.

## See also

* [Run a Gravity Mainnet Public Full Node](/gravity-networks/run-a-mainnet-pfn)
* [Run a Gravity Mainnet Public Full Node With Docker](/gravity-networks/run-a-mainnet-pfn-with-docker)
* [Run a Gravity Mainnet VFN](/gravity-networks/run-a-mainnet-vfn)
* [Run a Gravity Mainnet Validator (Invite Only)](/gravity-networks/run-a-mainnet-validator)


# Run a Gravity Mainnet Public Full Node

Run a Gravity Mainnet (L1) Public Full Node. Covers binaries, genesis artifacts, public/VFN seeds, deployment, database warm start, and sync verification for a PFN/RPC endpoint.

This guide walks you through running a Public Full Node (PFN) on Gravity Mainnet (L1, Chain ID `127001`). A PFN syncs from upstream public or VFN seeds and can serve EVM JSON-RPC for your applications, indexers, or internal services.

A PFN does **not** participate in consensus, does **not** hold validator stake, and does **not** require an invite. If you only need occasional reads or writes, you can use the public endpoint at <https://mainnet-rpc.gravity.xyz> instead.

{% hint style="warning" %}
**Required version.** Mainnet nodes must run [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) before **2026-08-18 02:00:00 UTC**. See [Gravity Mainnet Hardforks](/gravity-networks/mainnet-hardforks).
{% endhint %}

> **Placeholders.** Commands below use `<YOUR_...>` placeholders. Replace each value before running. Never commit private keys, generated identities, or node databases to version control.

## Network Role

Gravity L1 separates node traffic into validator, VFN, and public networks. A PFN uses the public network and syncs outward from upstream infrastructure:

```
validators --VFN net--> VFN --public net--> PFN / RPC --> app or indexer
```

Use a PFN when you want:

* a private or high-throughput JSON-RPC endpoint;
* a node close to your backend or indexer;
* independent chain data for analytics or monitoring;
* no validator-set or governance operations.

## Prerequisites

1. **A Linux x86-64 host.** Production nodes are built and run on Ubuntu 24.04 LTS. Build on the same OS family that you deploy to.
2. **`gravity_node` and `gravity_cli`.** Build from source:

   ```bash
   git clone https://github.com/Galxe/gravity-sdk.git
   cd gravity-sdk
   git checkout v1.9.1
   RUSTFLAGS="--cfg tokio_unstable" \
     cargo build --profile quick-release -p gravity_node -p gravity_cli
   ```

   The binaries land in `target/quick-release/`. You can also download the [v1.9.1 release](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1). For `gravity_cli` command usage, see the [Gravity CLI Skill](https://github.com/Galxe/gravity-sdk/blob/main/.agents/skills/gravity-cli/SKILL.md).
3. **Mainnet `genesis.json` and `waypoint.txt`.** These artifacts pin the exact chain you are joining. Download the canonical files from [`gravity-sdk/genesis/mainnet`](https://github.com/Galxe/gravity-sdk/tree/main/genesis/mainnet); do not regenerate genesis locally for mainnet.
4. **An upstream public-network seed.** For each seed you need its `peer_id`, host, public port, and `network_public_key`. The current public PFN seeds are listed below.
5. **SSD/NVMe storage.** Chain data grows with uptime. Budget well above the current chain size.

## 1. Prepare Genesis Artifacts

Place the canonical mainnet artifacts where your cluster config references them:

```bash
mkdir -p <YOUR_GRAVITY_SDK_PATH>/cluster/output
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/genesis.json \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/genesis.json
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/waypoint.txt \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/waypoint.txt
```

```
<YOUR_GRAVITY_SDK_PATH>/cluster/output/genesis.json
<YOUR_GRAVITY_SDK_PATH>/cluster/output/waypoint.txt
```

If the artifacts live elsewhere, you can point to absolute paths in `genesis_source`:

```toml
[genesis_source]
genesis_path = "<YOUR_MAINNET_ARTIFACT_DIR>/genesis.json"
waypoint_path = "<YOUR_MAINNET_ARTIFACT_DIR>/waypoint.txt"
```

The `genesis.json` and `waypoint.txt` must match each other. A wrong pair can start a node on a different chain identity and prevent it from syncing mainnet.

## 2. Gather Seed Information

### Current Mainnet PFN Connectivity

At the moment, public internet access is intended for the mainnet RPC/PFN fleet. Other validator and VFN hosts should be treated as private/internal unless the Gravity team explicitly shares invite-only seed information.

Public full-node (PFN) operators should dial **direct per-node p2p DNS** on port `6180`. Each seed entry must use that node's own `peer_id` and `network_public_key`. Do not point a noise-ik multiaddr at a load-balanced VIP: the peer identity is per-node and will not match an arbitrary backend.

| Node    | Host                            | JSON-RPC | Public-network seed port | Peer ID                                                            | Network public key                                                 |
| ------- | ------------------------------- | -------- | ------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| `rpc-1` | `mainnet-rpc-p2p-1.gravity.xyz` | `8545`   | `6180`                   | `38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077` | `234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f` |
| `rpc-3` | `mainnet-rpc-p2p-3.gravity.xyz` | `8545`   | `6180`                   | `2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4` | `0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365` |

`rpc-2` is internal-only (no public p2p address). It is not a published seed for external PFN operators.

For normal JSON-RPC traffic, prefer the aggregate endpoint:

```
https://mainnet-rpc.gravity.xyz
```

Before using a PFN host as an upstream seed, verify from your node host that the public-network port is reachable:

```bash
nc -vz mainnet-rpc-p2p-1.gravity.xyz 6180
nc -vz mainnet-rpc-p2p-3.gravity.xyz 6180
```

Validator and VFN joining is currently invite-only for Gravity-operated mainnet seeds. A PFN does not need validator access, but it still needs a reachable public-network upstream seed plus that seed's public identity values.

Use the current public PFN seeds directly in `local-pfn.toml`. Configure both entries for redundancy; either seed alone is enough to sync if the other is temporarily unreachable.

```toml
seeds = [
  { peer_id = "38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-1.gravity.xyz/tcp/6180/noise-ik/234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f/handshake/0" },
  { peer_id = "2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-3.gravity.xyz/tcp/6180/noise-ik/0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365/handshake/0" },
]
```

For an explicit PFN seed, fill these values from the upstream node's public identity:

| Value                                | Meaning                                                 |
| ------------------------------------ | ------------------------------------------------------- |
| `<YOUR_UPSTREAM_PEER_ID>`            | Upstream sidecar `account_address`.                     |
| `<YOUR_UPSTREAM_HOST>`               | DNS name or IP address of the upstream public listener. |
| `<YOUR_UPSTREAM_PUBLIC_PORT>`        | Public-network port exposed by the upstream node.       |
| `<YOUR_UPSTREAM_NETWORK_PUBLIC_KEY>` | Upstream sidecar `network_public_key`.                  |

Prefer explicit seed entries over `seeds = [{ from = "<id>" }]` for a standalone PFN config. The `{ from = ... }` form only works when the seed node is also defined in the same TOML file.

## 3. Write `local-pfn.toml`

Create a config such as:

```toml
[cluster]
name = "<YOUR_PFN_CLUSTER_NAME>"
base_dir = "<YOUR_DEPLOY_BASE_DIR>"

[genesis_source]
genesis_path = "./output/genesis.json"
waypoint_path = "./output/waypoint.txt"

[[nodes]]
id = "local-pfn"
role = "pfn"
source = { bin_path = "../target/quick-release/gravity_node" }
identity = { source = "file" }

# Deploy directory, not the database directory.
# deploy.sh renders storage to <YOUR_DEPLOY_BASE_DIR>/local-pfn/data
# and reth to <YOUR_DEPLOY_BASE_DIR>/local-pfn/data/reth.
data_dir = "<YOUR_DEPLOY_BASE_DIR>/local-pfn"

host = "127.0.0.1"
# Example local public-network port for this PFN. If other nodes should sync
# from this node, expose and publish the chosen public listener; PFN/VFN public
# listeners commonly use 6195.
public_port = 6180
rpc_port = 8545
metrics_port = 9001
inspection_port = 10001
authrpc_port = 8661
reth_p2p_port = 12024
txpool_max_account_slots = 64
prune_transactionlookup_distance = 10064

seeds = [
  { peer_id = "38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-1.gravity.xyz/tcp/6180/noise-ik/234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f/handshake/0" },
  { peer_id = "2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-3.gravity.xyz/tcp/6180/noise-ik/0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365/handshake/0" },
]
```

Port choices can be changed if you run multiple nodes on one host. Keep the RPC port private unless you intentionally expose it behind your own gateway, authentication, rate limiting, and monitoring.

`prune_transactionlookup_distance = 10064` starts reth with `--full --prune.transactionlookup.distance 10064`. This keeps recent transaction-hash lookup data while allowing older transaction lookup indexes to be pruned. Use a value **greater than or equal to `10064`** for production PFN/RPC nodes. Treat smaller values, such as short test-only distances, as invalid for mainnet PFN configs and reject them during config review.

Use transaction-lookup pruning when you want lower execution database growth and do not need arbitrary old `eth_getTransactionByHash` lookups from this node.

If you omit `prune_transactionlookup_distance`, the generated PFN reth config uses archive-style storage for transaction lookups and keeps historical lookup indexes instead of pruning them. That is simpler for indexers or debugging flows that need old transaction hashes, but it uses more disk over time.

Do not set `prune_transactionlookup_distance = 0` to disable pruning. A distance of `0` is still a pruning mode and can prune transaction lookup data aggressively. To run without transaction-lookup pruning, leave the field out.

The example above generates and stores identity files locally. In production, you can also load the node identity from a secret manager. For example:

```toml
identity = {
  source = "gcp_secret",
  secret = "projects/<YOUR_PROJECT>/secrets/<YOUR_PFN_IDENTITY_SECRET>/versions/1",
}
```

Pin a fixed secret version instead of `latest` when you want reproducible deployments and safer rollbacks.

## 4. Generate Identity and Deploy

From the SDK cluster directory:

```bash
cd <YOUR_GRAVITY_SDK_PATH>/cluster
just init local-pfn.toml
just deploy local-pfn.toml
```

Expected layout:

```
<YOUR_DEPLOY_BASE_DIR>/local-pfn/config/
<YOUR_DEPLOY_BASE_DIR>/local-pfn/data/
<YOUR_DEPLOY_BASE_DIR>/local-pfn/script/start.sh
<YOUR_DEPLOY_BASE_DIR>/local-pfn/script/stop.sh
```

If the package is generated on a build host, copy it to the runtime host while preserving the node directory layout.

## 5. Optional: Warm Start From a Snapshot or Existing Node

A new PFN can sync from genesis, but that may take a long time on an established chain.

### Option A: Download the Public Mainnet Data Snapshot

Gravity publishes daily mainnet PFN data snapshots in the public bucket. Pick the latest available date and download it to your node host. For example, use `2026-06-14` for the snapshot at `gravity-mainnet-data/2026-06-14.tar`:

```bash
SNAPSHOT_DATE=<YYYY-MM-DD>
curl -L --fail --continue-at - \
  "https://storage.googleapis.com/gravity-public-bucket/gravity-mainnet-data/${SNAPSHOT_DATE}.tar" \
  -o "/tmp/${SNAPSHOT_DATE}.tar"
```

Before the first start, replace the generated empty data directory with the snapshot data:

```bash
tar -xf "/tmp/${SNAPSHOT_DATE}.tar" \
  -C <YOUR_DEPLOY_BASE_DIR>/local-pfn/data
```

After extraction, the data directory should contain the snapshot databases while preserving the node directory layout:

```
<YOUR_DEPLOY_BASE_DIR>/local-pfn/data/consensus_db/
<YOUR_DEPLOY_BASE_DIR>/local-pfn/data/quorumstoreDB/
<YOUR_DEPLOY_BASE_DIR>/local-pfn/data/reth/
```

### Option B: Copy From an Existing Node You Control

If you already run a trusted RPC/PFN, you can copy only the chain databases from that node:

```bash
cd <YOUR_EXISTING_NODE_DATA_DIR>
tar -cf - consensus_db quorumstoreDB reth | \
  ssh <YOUR_TARGET_HOST> \
    "mkdir -p <YOUR_DEPLOY_BASE_DIR>/local-pfn/data && \
     cd <YOUR_DEPLOY_BASE_DIR>/local-pfn/data && tar -xf -"
```

Do **not** copy `rand_db` or `secure_storage.json` from another node. Those files carry node-specific randomness or safety state and should not be reused.

## 6. Start the Node

```bash
bash <YOUR_DEPLOY_BASE_DIR>/local-pfn/script/start.sh
```

Check the logs under the node directory:

```bash
tail -n 200 <YOUR_DEPLOY_BASE_DIR>/local-pfn/consensus_log/pfn.log
ls -lh <YOUR_DEPLOY_BASE_DIR>/local-pfn/execution_logs
```

## 7. Verify Sync

Query your local node:

```bash
curl -s http://127.0.0.1:8545 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

Compare it with the public chain head:

```bash
curl -s https://mainnet-rpc.gravity.xyz \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

When the two heights are close and your local height keeps advancing, the node is caught up. Gravity has BFT-final blocks: once a block is returned by your node, there is no EVM-style reorg to wait for.

## Troubleshooting

| Symptom                                                         | Cause / fix                                                                                                              |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `seeds: from=<id>: missing host or public_port in cluster.toml` | Use an explicit `peer_id` / `address` seed, or define the seed node in the same TOML.                                    |
| Node stays at a low height                                      | Re-check seed `peer_id`, host, port, network public key, `genesis.json`, and `waypoint.txt`.                             |
| `net_peerCount` returns `0`                                     | Usually expected. Gravity syncs through AptosBFT/VFN/public networks, not EVM devp2p gossip. Watch block height instead. |
| RPC unavailable                                                 | Confirm `rpc_port` is free, the process is running, and logs exist under the deploy directory.                           |
| Database paths look nested incorrectly                          | `data_dir` should be the deploy directory. Storage is rendered to `$data_dir/data`.                                      |

## See Also

* [Run a Gravity Mainnet VFN](/gravity-networks/run-a-mainnet-vfn)
* [Run a Gravity Mainnet Validator](/gravity-networks/run-a-mainnet-validator)
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet)
* [Node Providers](/ecosystem-infrastructures/node-providers)


# Run a Gravity Mainnet Public Full Node With Docker

Run a Gravity Mainnet (L1) Public Full Node with Docker. Covers image preparation, mainnet artifacts, PFN identity generation, pruning, startup, sync checks, and operational cleanup.

This guide walks you through running a Gravity Mainnet Public Full Node (PFN) with the `gravity_node` Docker image. A PFN syncs from an upstream public-network seed and can serve EVM JSON-RPC for applications, indexers, or internal services.

A PFN does **not** participate in consensus, does **not** hold validator stake, and does **not** require validator invite access.

{% hint style="warning" %}
**Required version.** Mainnet nodes must run [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) before **2026-08-18 02:00:00 UTC**. See [Gravity Mainnet Hardforks](/gravity-networks/mainnet-hardforks).
{% endhint %}

> **Placeholders.** Commands below use `<YOUR_...>` placeholders. Replace each value before running. Never commit generated identities, private keys, `.env` files, rendered node config, logs, or node databases to version control.

## Prerequisites

1. **Docker and Docker Compose v2.** Production nodes should run on Linux. Docker Desktop on macOS is useful for local validation, but it handles host networking differently from Linux.
2. **Local command-line tools.** Install `just`, `envsubst` from GNU gettext, `jq`, `curl`, `nc`, and `lsof`.
3. **The Gravity SDK repository.** The Docker image and config templates live in [`gravity-sdk`](https://github.com/Galxe/gravity-sdk).

   ```bash
   git clone https://github.com/Galxe/gravity-sdk.git
   cd gravity-sdk
   git checkout v1.9.1
   ```
4. **Mainnet `genesis.json` and `waypoint.txt`.** These artifacts pin the exact chain you are joining. Download the canonical files from [`gravity-sdk/genesis/mainnet`](https://github.com/Galxe/gravity-sdk/tree/main/genesis/mainnet).
5. **An upstream public-network seed.** The current public PFN seeds are shown below.
6. **SSD/NVMe storage.** Chain data grows with uptime. Budget well above the current chain size.

## 1. Pull the Docker Image

```bash
docker pull ghcr.io/galxe/gravity_node:v1.9.1
```

To build from source instead, check out `v1.9.1` and tag the image `ghcr.io/galxe/gravity_node:v1.9.1` so the `.env` values below still match.

## 2. Prepare the Docker Workspace

```bash
cd docker/gravity_node
cp .env.example .env
mkdir -p config
```

Edit `.env`:

```dotenv
GRAVITY_IMAGE=ghcr.io/galxe/gravity_node
IMAGE_TAG=v1.9.1
RUST_LOG=info
```

The container reads node config from `./config` and stores chain data in Docker volumes.

## 3. Prepare Mainnet Artifacts

From `docker/gravity_node`:

```bash
mkdir -p ../../cluster/output
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/genesis.json \
  -o ../../cluster/output/genesis.json
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/waypoint.txt \
  -o ../../cluster/output/waypoint.txt
```

Copy these artifacts into the Docker config directory:

```bash
cp ../../cluster/output/genesis.json config/genesis.json
cp ../../cluster/output/waypoint.txt config/waypoint.txt
```

## 4. Gather Seed Information

At the moment, public internet access is intended for the mainnet RPC/PFN fleet. Other validator and VFN hosts should be treated as private/internal unless the Gravity team explicitly shares invite-only seed information.

Public full-node (PFN) operators should dial **direct per-node p2p DNS** on port `6180`. Each seed entry must use that node's own `peer_id` and `network_public_key`. Do not point a noise-ik multiaddr at a load-balanced VIP: the peer identity is per-node and will not match an arbitrary backend.

| Node    | Host                            | Public-network seed port | Peer ID                                                            | Network public key                                                 |
| ------- | ------------------------------- | ------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| `rpc-1` | `mainnet-rpc-p2p-1.gravity.xyz` | `6180`                   | `38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077` | `234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f` |
| `rpc-3` | `mainnet-rpc-p2p-3.gravity.xyz` | `6180`                   | `2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4` | `0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365` |

`rpc-2` is internal-only (no public p2p address). It is not a published seed for external PFN operators.

Before using the seeds, verify from your node host that the public-network ports are reachable:

```bash
nc -vz mainnet-rpc-p2p-1.gravity.xyz 6180
nc -vz mainnet-rpc-p2p-3.gravity.xyz 6180
```

Use the current public PFN seeds when rendering `PFN_SEEDS_BLOCK` in the Docker config section below. Configure both entries for redundancy; either seed alone is enough to sync if the other is temporarily unreachable.

```toml
seeds = [
  { peer_id = "38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-1.gravity.xyz/tcp/6180/noise-ik/234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f/handshake/0" },
  { peer_id = "2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4", role = "PreferredUpstream", address = "/dns/mainnet-rpc-p2p-3.gravity.xyz/tcp/6180/noise-ik/0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365/handshake/0" },
]
```

## 5. Generate a PFN Identity

Create a minimal cluster config file for identity generation, for example `cluster/local-pfn-docker.toml`:

```toml
[cluster]
name = "<YOUR_PFN_CLUSTER_NAME>"

[[nodes]]
id = "local-pfn-docker"
role = "pfn"
identity = { source = "file" }
```

The Docker flow uses this TOML only to generate node identity material. It does not read ports, seeds, `base_dir`, or `data_dir` from the TOML during container startup. Docker runtime storage is controlled by the volume or bind mount in the start command, and by the container paths rendered in the next section.

Generate the PFN identity:

```bash
cd ../../cluster
just init local-pfn-docker.toml
cd ../docker/gravity_node
cp ../../cluster/output/local-pfn-docker/config/identity.yaml config/identity.yaml
```

The generated `identity.yaml` contains private node identity material. Keep it on the runtime host only.

## 6. Render Container Config

The container sees config at `/gravity/config` and data at `/gravity/data`, so the rendered files must use container paths, not host paths.

`DATA_DIR`, `STORAGE_DIR`, and `LOG_DIR` are intentionally separate:

```
/gravity/data/              # Docker data volume root
└── data/                   # STORAGE_DIR, chain databases
    ├── consensus_db/
    ├── quorumstoreDB/
    └── reth/

/gravity/logs/              # Docker logs volume root
├── consensus_log/
└── execution_logs/
```

To place data on a specific host disk, mount that host path to `/gravity/data`. To place logs on a specific host disk, mount that host path to `/gravity/logs`. Do not change the TOML `data_dir` for Docker runtime storage.

From `docker/gravity_node`:

```bash
export NODE_ID=local-pfn-docker
export HOST=127.0.0.1
export PUBLIC_PORT=26180
export RPC_PORT=28545
export METRICS_PORT=29001
export INSPECTION_PORT=30001
export AUTHRPC_PORT=28661
export P2P_PORT_RETH=32024
export TXPOOL_MAX_ACCOUNT_SLOTS=64
export PRUNE_TRANSACTIONLOOKUP_DISTANCE=10064

export CONFIG_DIR=/gravity/config
export DATA_DIR=/gravity/data
export STORAGE_DIR=/gravity/data/data
export LOG_DIR=/gravity/logs
export GENESIS_PATH=/gravity/config/genesis.json

export RPC_HTTP_CORSDOMAIN='*'
export RPC_HTTP_API='debug,eth,net,trace,txpool,web3,rpc'

export NETWORK_IDENTITY_TYPE=from_file
export NETWORK_IDENTITY_FIELD=path
export NETWORK_IDENTITY_VALUE=/gravity/config/identity.yaml
export SAFETY_RULES_IDENTITY_VARIANT=from_file
export SAFETY_RULES_IDENTITY_KEY=identity_blob_path
export SAFETY_RULES_IDENTITY_VALUE=/gravity/config/identity.yaml
export DISCOVERY_METHOD_FULLNODE_BLOCK=''
export PFN_SEEDS_BLOCK='    seeds:
      "0x38013b46c21388c3fd08ab32b86b478b3109125566d63c2da8fdc941dc474077":
        addresses:
          - "/dns/mainnet-rpc-p2p-1.gravity.xyz/tcp/6180/noise-ik/234aee14677a3d2198208ea72ca5e95ed75520df27f01f0c36220303ff78642f/handshake/0"
        role: PreferredUpstream
      "0x2d30cf69303d40e0efcdb0f3a6545d43b055e86729287f2f1328c001caeb2be4":
        addresses:
          - "/dns/mainnet-rpc-p2p-3.gravity.xyz/tcp/6180/noise-ik/0a71ef75482f617203f64b0d5e9e3a66361b5f35e9d709ef873c494cd76d2365/handshake/0"
        role: PreferredUpstream'

envsubst < ../../cluster/templates/public_full_node.yaml.tpl \
  > config/public_full_node.yaml

envsubst < ../../cluster/templates/reth_config_pfn_prune.json.tpl \
  > config/reth_config.json
```

If you do not want transaction-lookup pruning, do not set `PRUNE_TRANSACTIONLOOKUP_DISTANCE`, and render `reth_config.json` from the non-prune template instead:

```bash
envsubst < ../../cluster/templates/reth_config_pfn.json.tpl \
  > config/reth_config.json
```

Verify the rendered config:

```bash
jq . config/reth_config.json >/dev/null
grep -n 'public_full_node.yaml\|prune.transactionlookup.distance\|gravity/config\|gravity/data' \
  config/reth_config.json
grep -n 'PreferredUpstream\|mainnet-rpc-p2p-1.gravity.xyz\|mainnet-rpc-p2p-3.gravity.xyz\|/gravity/config/identity.yaml' \
  config/public_full_node.yaml
```

Expected `reth_config.json` behavior:

* `chain` points to `/gravity/config/genesis.json`;
* `gravity_node_config` points to `/gravity/config/public_full_node.yaml`;
* `datadir` points to `/gravity/data/data/reth`;
* `log.file.directory` points to `/gravity/logs/execution_logs/`;
* when pruning is enabled, `prune.transactionlookup.distance` is `10064`.

## 7. Pruning Mode

`prune_transactionlookup_distance = 10064` starts reth with transaction-lookup pruning enabled. This keeps recent transaction-hash lookup data while allowing older lookup indexes to be pruned.

Use a value **greater than or equal to `10064`** for production PFN/RPC nodes. Treat smaller values as test-only and reject them during config review.

Use this pruning mode when you want lower execution database growth and do not need arbitrary old `eth_getTransactionByHash` lookups from this node.

If you omit `prune_transactionlookup_distance`, the generated PFN reth config uses archive-style transaction lookup behavior and keeps historical lookup indexes instead of pruning them. That is simpler for indexers or debugging flows that need old transaction hashes, but it uses more disk over time.

Do not set `prune_transactionlookup_distance = 0` to disable pruning. A distance of `0` is still a pruning mode and can prune transaction lookup data aggressively. To run without transaction-lookup pruning, leave the field out.

## 8. Optional: Warm Start From a Snapshot or Existing Node

A new Docker PFN can sync from genesis, but that may take a long time on an established chain. To warm start, load the snapshot into the Docker data volume **before the first node start**.

If the Docker PFN has already started once, stop the container and remove the old data volume before importing a snapshot. Do not merge snapshot files into an already-initialized database.

The Docker container mounts its data volume at `/gravity/data`. The chain databases must live under `/gravity/data/data`, so extract snapshot contents into that `data` subdirectory.

### Option A: Download the Public Mainnet Data Snapshot

Gravity publishes daily mainnet PFN data snapshots in the public bucket. Pick the latest available date and download it to your node host:

```bash
curl -s 'https://storage.googleapis.com/storage/v1/b/gravity-public-bucket/o?prefix=gravity-mainnet-data/&fields=items(name,size,updated)' \
  | jq -r '.items[] | "\(.name) \(.size) \(.updated)"'

SNAPSHOT_DATE=<YYYY-MM-DD>
curl -L --fail --continue-at - \
  "https://storage.googleapis.com/gravity-public-bucket/gravity-mainnet-data/${SNAPSHOT_DATE}.tar" \
  -o "/tmp/${SNAPSHOT_DATE}.tar"
```

The snapshot tar contains database directories such as `consensus_db/`, `quorumstoreDB/`, and `reth/` at the archive root. It does not contain an outer `data/` directory.

For the Linux compose flow, load the snapshot into the compose data volume:

```bash
docker compose run --rm --no-deps \
  --user root \
  --entrypoint sh \
  -e SNAPSHOT_DATE \
  -v /tmp:/snapshot:ro \
  gravity_node \
  -lc 'mkdir -p /gravity/data/data && \
       tar -xf "/snapshot/${SNAPSHOT_DATE}.tar" -C /gravity/data/data && \
       chown -R 10001:10001 /gravity/data /gravity/logs'
```

For the macOS `docker run` flow, load the snapshot into the explicit named volume used by the start command below:

```bash
set -a
. ./.env
set +a

docker volume create gravity_node_local_pfn_data
docker run --rm \
  --user root \
  --entrypoint sh \
  -e SNAPSHOT_DATE \
  -v gravity_node_local_pfn_data:/gravity/data \
  -v gravity_node_local_pfn_logs:/gravity/logs \
  -v /tmp:/snapshot:ro \
  ${GRAVITY_IMAGE}:${IMAGE_TAG} \
  -lc 'mkdir -p /gravity/data/data && \
       tar -xf "/snapshot/${SNAPSHOT_DATE}.tar" -C /gravity/data/data && \
       chown -R 10001:10001 /gravity/data /gravity/logs'
```

After extraction, the Docker data volume should contain:

```
/gravity/data/data/consensus_db/
/gravity/data/data/quorumstoreDB/
/gravity/data/data/reth/
```

### Option B: Copy From an Existing Node You Control

If you already run a trusted RPC/PFN, you can copy only the chain databases from that node:

```bash
cd <YOUR_EXISTING_NODE_DATA_DIR>
tar -cf /tmp/pfn-data.tar consensus_db quorumstoreDB reth
```

Then load `/tmp/pfn-data.tar` into the Docker data volume with the same compose or `docker run` extraction pattern above. Mount `/tmp` as `/snapshot` and replace the extraction command with:

```bash
tar -xf /snapshot/pfn-data.tar -C /gravity/data/data
```

Do **not** copy `rand_db` or `secure_storage.json` from another node. Those files carry node-specific randomness or safety state and should not be reused.

## 9. Start the PFN

Make sure the selected host ports are free:

```bash
lsof -nP -iTCP:26180 -iTCP:28545 -iTCP:29001 -iTCP:30001 -iTCP:28661 -iTCP:32024
```

On Linux, use Docker Compose:

```bash
docker compose up -d
docker ps --filter name=gravity_node
```

The compose file uses `network_mode: host` because p2p ports need predictable advertised addresses.

On Docker Desktop for macOS, host networking behaves differently. For local validation from the macOS host, use explicit port publishing:

```bash
docker rm -f gravity_node 2>/dev/null || true
set -a
. ./.env
set +a

docker run -d --name gravity_node --restart unless-stopped \
  -p 26180:26180 \
  -p 28545:28545 \
  -p 29001:29001 \
  -p 30001:30001 \
  -p 28661:28661 \
  -p 32024:32024 \
  -v "$(pwd)/config:/gravity/config:ro" \
  -v gravity_node_local_pfn_data:/gravity/data \
  -v gravity_node_local_pfn_logs:/gravity/logs \
  -e RUST_BACKTRACE=1 \
  -e RUST_LOG=info \
  --ulimit nofile=1048576:1048576 \
  ${GRAVITY_IMAGE}:${IMAGE_TAG}
```

## 10. Verify Sync

Query the local Docker PFN:

```bash
curl -s --noproxy '*' http://127.0.0.1:28545 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | jq -r .result
```

Compare with the public RPC:

```bash
curl -s --noproxy '*' https://mainnet-rpc.gravity.xyz \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | jq -r .result
```

Follow logs:

```bash
docker logs gravity_node -f
docker exec gravity_node sh -lc \
  'tail -n 200 /gravity/logs/execution_logs/*/reth.log'
docker exec gravity_node sh -lc \
  'tail -n 200 /gravity/logs/consensus_log/vfn.log'
```

Confirm the prune config was accepted:

```bash
docker exec gravity_node sh -lc \
  'grep -R "Pruner initialized\\|prune_config\\|transaction_lookup" /gravity/logs/execution_logs || true'
```

## 11. Stop, Restart, or Reset

For the Linux compose flow, stop the container but keep chain data:

```bash
docker compose down
```

Restart:

```bash
docker compose up -d
```

Delete the local PFN database and start from zero again:

```bash
docker compose down -v
```

For the macOS `docker run` flow, stop the container but keep chain data:

```bash
docker rm -f gravity_node
```

Delete the local PFN database and start from zero again:

```bash
docker rm -f gravity_node
docker volume rm gravity_node_local_pfn_data gravity_node_local_pfn_logs
```

Only remove Docker volumes when you intentionally want to delete the node database.

## Files to Keep Out of Version Control

Do not commit generated runtime files:

* `docker/gravity_node/.env`;
* `docker/gravity_node/config/*`;
* `cluster/output/<YOUR_NODE_ID>/config/identity.yaml`;
* Docker volumes such as `gravity-data`, `gravity-logs`, `gravity_node_local_pfn_data`, and `gravity_node_local_pfn_logs`;
* node databases and logs.

The reusable materials are the public guide and SDK templates. Each operator should generate their own identity and runtime config.


# Run a Gravity Mainnet VFN

Run a Gravity Mainnet (L1) Validator Full Node. Covers validator VFN-network seeds, deployment, optional public listener, database warm start, and sync verification.

This guide walks you through running a Validator Full Node (VFN) on Gravity Mainnet (L1, Chain ID `127001`). A VFN dials one or more validators on the VFN network and can expose a public listener for downstream PFNs.

A VFN is **not** part of the validator set and does not need validator stake. Access depends on which validator seed you connect to:

* Connecting to Gravity mainnet genesis validator seeds is currently **invite-only**. You need approved validator VFN-network seed information.
* Connecting to validators that you deploy and operate yourself does not require a Gravity mainnet invite.

{% hint style="warning" %}
**Required version.** Mainnet nodes must run [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) before **2026-08-18 02:00:00 UTC**. See [Gravity Mainnet Hardforks](/gravity-networks/mainnet-hardforks).
{% endhint %}

> **Placeholders.** Commands below use `<YOUR_...>` placeholders. Replace each value before running. Never reuse another node's private identity or safety storage.

## Network Role

Gravity traffic flows outward from validators to VFNs, then to PFNs:

```
validators --VFN net--> VFN --public net--> PFN / RPC
```

Use a VFN when you want:

* a full node close to a validator or validator operator;
* a relay point for one or more PFNs;
* a node that follows validator-network data without joining consensus.

## Prerequisites

1. **A Linux x86-64 host**, preferably Ubuntu 24.04 LTS.
2. **`gravity_node` and `gravity_cli`.**

   ```bash
   git clone https://github.com/Galxe/gravity-sdk.git
   cd gravity-sdk
   git checkout v1.9.1
   RUSTFLAGS="--cfg tokio_unstable" \
     cargo build --profile quick-release -p gravity_node -p gravity_cli
   ```
3. **Mainnet `genesis.json` and `waypoint.txt`.** Use the canonical mainnet artifacts from [`gravity-sdk/genesis/mainnet`](https://github.com/Galxe/gravity-sdk/tree/main/genesis/mainnet); do not regenerate genesis locally.
4. **Validator VFN-network seed information.** Each validator seed needs `account_address`, host, `vfn_port`, and `network_public_key`. Genesis validator seeds require approval; self-operated validator seeds do not.
5. **SSD/NVMe storage** sized for current chain data plus growth.

## 1. Gather Validator Seed Information

For each validator you will dial, collect its public identity values from `identity.public.yaml`:

```yaml
account_address: <VALIDATOR_PEER_ID>
network_public_key: <VALIDATOR_NETWORK_PUBLIC_KEY>
```

You also need the validator host and VFN-network port, commonly `6190`.

In a standalone VFN config, prefer explicit seed entries:

```toml
seeds = [
  {
    peer_id = "<YOUR_VALIDATOR_1_ACCOUNT_ADDRESS>",
    role = "Validator",
    host = "<YOUR_VALIDATOR_1_HOST>",
    port = 6190,
    network_pk = "<YOUR_VALIDATOR_1_NETWORK_PUBLIC_KEY>"
  },
  {
    peer_id = "<YOUR_VALIDATOR_2_ACCOUNT_ADDRESS>",
    role = "Validator",
    host = "<YOUR_VALIDATOR_2_HOST>",
    port = 6190,
    network_pk = "<YOUR_VALIDATOR_2_NETWORK_PUBLIC_KEY>"
  },
]
```

Avoid `seeds = [{ from = "<id>" }]` unless the seed validator is also defined in the same TOML. The deploy script needs that validator's `host` and `vfn_port` from the same config.

## 2. Write `cluster-vfn.toml`

Download the canonical mainnet artifacts where the config below expects them:

```bash
mkdir -p <YOUR_GRAVITY_SDK_PATH>/cluster/output
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/genesis.json \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/genesis.json
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/waypoint.txt \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/waypoint.txt
```

Create a config such as:

```toml
[cluster]
name = "<YOUR_VFN_CLUSTER_NAME>"
base_dir = "<YOUR_DEPLOY_BASE_DIR>"

[genesis_source]
genesis_path = "./output/genesis.json"
waypoint_path = "./output/waypoint.txt"

[relayer]
relayer_rpc_url = "<YOUR_L1_RPC_URL>"

[[nodes]]
id = "vfn-1"
role = "vfn"
source = { bin_path = "../target/quick-release/gravity_node" }
identity = { source = "file" }
host = "<YOUR_VFN_HOST>"

# Deploy directory, not the database directory.
# deploy.sh renders storage to <YOUR_DEPLOY_BASE_DIR>/vfn-1/data
# and reth to <YOUR_DEPLOY_BASE_DIR>/vfn-1/data/reth.
data_dir = "<YOUR_DEPLOY_BASE_DIR>/vfn-1"

vfn_port = 6190
public_port = 6195
rpc_port = 8545
metrics_port = 9001
inspection_port = 10001
https_port = 11001
authrpc_port = 8661
reth_p2p_port = 12024
discovery_method = "none"
txpool_max_account_slots = 64

seeds = [
  {
    peer_id = "<YOUR_VALIDATOR_1_ACCOUNT_ADDRESS>",
    role = "Validator",
    host = "<YOUR_VALIDATOR_1_HOST>",
    port = 6190,
    network_pk = "<YOUR_VALIDATOR_1_NETWORK_PUBLIC_KEY>"
  },
]
```

`public_port` is optional but useful if PFNs should sync from this VFN. Keep RPC private unless you intentionally expose it behind your own gateway and access controls.

If you load identity from a secret manager, pin a fixed version rather than `latest`:

```toml
identity = {
  source = "gcp_secret",
  secret = "projects/<YOUR_PROJECT>/secrets/<YOUR_SECRET>/versions/1",
}
```

## 3. Generate Identity and Deploy

```bash
cd <YOUR_GRAVITY_SDK_PATH>/cluster
just init cluster-vfn.toml
just deploy cluster-vfn.toml
```

Expected layout:

```
<YOUR_DEPLOY_BASE_DIR>/vfn-1/config/
<YOUR_DEPLOY_BASE_DIR>/vfn-1/data/
<YOUR_DEPLOY_BASE_DIR>/vfn-1/script/start.sh
<YOUR_DEPLOY_BASE_DIR>/vfn-1/script/stop.sh
```

The public identity generated for the VFN is written to:

```
<YOUR_GRAVITY_SDK_PATH>/cluster/output/vfn-1/config/identity.public.yaml
```

If downstream PFNs will use this VFN as a seed, share the VFN sidecar `account_address`, `network_public_key`, host, and `public_port`.

## 4. Optional: Warm Start From an Existing Node

To speed up initial sync, copy only chain databases from an existing RPC/PFN or VFN you control:

```bash
cd <YOUR_EXISTING_NODE_DATA_DIR>
tar -cf - consensus_db quorumstoreDB reth | \
  ssh <YOUR_TARGET_HOST> \
    "mkdir -p <YOUR_DEPLOY_BASE_DIR>/vfn-1/data && \
     cd <YOUR_DEPLOY_BASE_DIR>/vfn-1/data && tar -xf -"
```

Do **not** copy `rand_db` or `secure_storage.json` from another node. `secure_storage.json` contains node-specific safety state and can make the node behave as if it belongs to a different identity.

## 5. Start and Verify

```bash
bash <YOUR_DEPLOY_BASE_DIR>/vfn-1/script/start.sh
```

Check logs:

```bash
tail -n 200 <YOUR_DEPLOY_BASE_DIR>/vfn-1/consensus_log/vfn.log
ls -lh <YOUR_DEPLOY_BASE_DIR>/vfn-1/execution_logs
```

Check RPC height:

```bash
curl -s http://127.0.0.1:8545 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

Compare with the public head:

```bash
curl -s https://mainnet-rpc.gravity.xyz \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

## Troubleshooting

| Symptom                                                      | Cause / fix                                                                                                    |
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `seeds: from=<id>: missing host or vfn_port in cluster.toml` | Use explicit seed entries, or define the seed validator in the same TOML.                                      |
| VFN does not advance                                         | Verify validator seed `peer_id`, host, `vfn_port`, and `network_public_key`; also verify genesis and waypoint. |
| Downstream PFNs cannot connect                               | Confirm `public_port` is open, reachable, and advertised with the VFN `network_public_key`.                    |
| Paths render as `<node>/data/<node>`                         | `data_dir` should be the node deploy directory, not the final database directory.                              |
| Identity-related errors after copying data                   | Remove any copied `secure_storage.json`; it must not be reused across nodes.                                   |

## See Also

* [Run a Gravity Mainnet Public Full Node](/gravity-networks/run-a-mainnet-pfn)
* [Run a Gravity Mainnet Validator](/gravity-networks/run-a-mainnet-validator)
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet)


# Run a Gravity Mainnet Validator (Invite Only)

Run an invite-only Gravity Mainnet (L1) validator. Validator onboarding is currently invite-only. Covers validator node deployment, StakePool creation, governance whitelisting, validator join, status

This guide walks approved operators through adding a validator to Gravity Mainnet (L1, Chain ID `127001`). A validator participates in AptosBFT consensus and must be backed by a StakePool that has been approved through governance.

Validator onboarding is currently **invite-only**. If you only need a node for reads, writes, or indexing, run a [Public Full Node](/gravity-networks/run-a-mainnet-pfn) instead.

{% hint style="warning" %}
**Required version.** Mainnet nodes must run [v1.9.1](https://github.com/Galxe/gravity-sdk/releases/tag/v1.9.1) before **2026-08-18 02:00:00 UTC**. See [Gravity Mainnet Hardforks](/gravity-networks/mainnet-hardforks).
{% endhint %}

> **Placeholders.** Commands below use `<YOUR_...>` placeholders. Replace each value before running. Never paste private keys into shared shells or commit generated node identities.

## Network Role

Validators connect to each other on the validator network and optionally expose VFN-network endpoints for VFNs:

```
validator set --validator net--> consensus
validator --VFN net--> VFN --public net--> PFN / RPC
```

The onboarding flow is:

1. Prepare validator config and identity.
2. Deploy the node package.
3. Fund the validator account.
4. Create a StakePool.
5. Add the StakePool to the validator whitelist through governance.
6. Join the validator set with the node's public identity.
7. Start the node and verify status.

## Prerequisites

1. **Approval from current governance / operators.** The StakePool must be whitelisted before it can join the validator set.
2. **A Linux x86-64 host**, preferably Ubuntu 24.04 LTS.
3. **`gravity_node` and `gravity_cli`.**

   ```bash
   git clone https://github.com/Galxe/gravity-sdk.git
   cd gravity-sdk
   git checkout v1.9.1
   RUSTFLAGS="--cfg tokio_unstable" \
     cargo build --profile quick-release -p gravity_node -p gravity_cli
   ```
4. **Mainnet `genesis.json` and `waypoint.txt`.** Use the canonical mainnet artifacts from [`gravity-sdk/genesis/mainnet`](https://github.com/Galxe/gravity-sdk/tree/main/genesis/mainnet); do not regenerate genesis locally.
5. **A fresh validator EVM account.** This account owns and operates the StakePool. Do not reuse public test keys for a long-running validator.
6. **System contract addresses** for staking, validator management, and governance. See the mainnet contract reference for current addresses.

## 1. Write `cluster-validator.toml`

Download the canonical mainnet artifacts where the config below expects them:

```bash
mkdir -p <YOUR_GRAVITY_SDK_PATH>/cluster/output
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/genesis.json \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/genesis.json
curl -fsSL https://raw.githubusercontent.com/Galxe/gravity-sdk/main/genesis/mainnet/waypoint.txt \
  -o <YOUR_GRAVITY_SDK_PATH>/cluster/output/waypoint.txt
```

Create a config such as:

```toml
[cluster]
name = "<YOUR_VALIDATOR_CLUSTER_NAME>"
base_dir = "<YOUR_DEPLOY_BASE_DIR>"

[genesis_source]
genesis_path = "./output/genesis.json"
waypoint_path = "./output/waypoint.txt"

[relayer]
relayer_rpc_url = "<YOUR_L1_RPC_URL>"

[[nodes]]
id = "validator-1"
role = "validator"
source = { bin_path = "../target/quick-release/gravity_node" }
identity = { source = "file" }
host = "<YOUR_VALIDATOR_HOST>"

# Deploy directory, not the database directory.
# deploy.sh renders storage to <YOUR_DEPLOY_BASE_DIR>/validator-1/data
# and reth to <YOUR_DEPLOY_BASE_DIR>/validator-1/data/reth.
data_dir = "<YOUR_DEPLOY_BASE_DIR>/validator-1"

validator_port = 6180
vfn_port = 6190
rpc_port = 8545
metrics_port = 9001
inspection_port = 10001
https_port = 11001
authrpc_port = 8661
reth_p2p_port = 12024
txpool_max_account_slots = 64
```

If identity is stored in a secret manager, pin a fixed version rather than `latest`:

```toml
identity = {
  source = "gcp_secret",
  secret = "projects/<YOUR_PROJECT>/secrets/<YOUR_SECRET>/versions/1",
}
```

## 2. Generate Identity and Deploy

```bash
cd <YOUR_GRAVITY_SDK_PATH>/cluster
just init cluster-validator.toml
just deploy cluster-validator.toml
```

Expected layout:

```
<YOUR_DEPLOY_BASE_DIR>/validator-1/config/
<YOUR_DEPLOY_BASE_DIR>/validator-1/data/
<YOUR_DEPLOY_BASE_DIR>/validator-1/script/start.sh
<YOUR_DEPLOY_BASE_DIR>/validator-1/script/stop.sh
```

The public identity used during `validator join` is written to:

```
<YOUR_GRAVITY_SDK_PATH>/cluster/output/validator-1/config/identity.public.yaml
```

## 3. Optional: Warm Start the Databases

To reduce cold-sync time, copy only chain databases from an existing RPC/PFN you control:

```bash
cd <YOUR_EXISTING_NODE_DATA_DIR>
tar -cf - consensus_db quorumstoreDB reth | \
  ssh <YOUR_TARGET_HOST> \
    "mkdir -p <YOUR_DEPLOY_BASE_DIR>/validator-1/data && \
     cd <YOUR_DEPLOY_BASE_DIR>/validator-1/data && tar -xf -"
```

Do **not** copy another node's `secure_storage.json`. It contains safety-rules owner and consensus-key state. Reusing it can produce errors such as:

```
The validator is not in the validator set. Address not in set: <OLD_OWNER_ACCOUNT>
```

## 4. Fund the Validator Account

Set common variables:

```bash
export RPC_URL="https://mainnet-rpc.gravity.xyz"
export VALIDATOR_ADDRESS="<YOUR_VALIDATOR_EVM_ADDRESS>"
export STAKE_AMOUNT="<YOUR_STAKE_AMOUNT>"
export STAKING_ADDRESS="<STAKING_CONTRACT_ADDRESS>"
export VALIDATOR_MANAGER_ADDRESS="<VALIDATOR_MANAGER_CONTRACT_ADDRESS>"
export GOVERNANCE_ADDRESS="<GOVERNANCE_CONTRACT_ADDRESS>"
```

Fund the validator account with enough balance for stake and gas:

```bash
cast balance "$VALIDATOR_ADDRESS" --rpc-url "$RPC_URL"
```

The validator account must sign StakePool and validator lifecycle operations. Use your normal secure signing workflow. If `gravity_cli` prompts for a key on stdin, ensure the signer is the StakePool operator.

## 5. Create a StakePool

Use the validator account to create a StakePool:

```bash
gravity_cli stake create \
  --rpc-url "$RPC_URL" \
  --stake-amount "$STAKE_AMOUNT" \
  --lockup-duration <YOUR_LOCKUP_SECONDS> \
  --gas-limit <YOUR_GAS_LIMIT>
```

Record the created pool:

```bash
export STAKE_POOL="<YOUR_STAKE_POOL_ADDRESS>"
```

Verify:

```bash
gravity_cli stake get \
  --rpc-url "$RPC_URL" \
  --owner "$VALIDATOR_ADDRESS"

cast call "$STAKING_ADDRESS" \
  "isPool(address)(bool)" "$STAKE_POOL" \
  --rpc-url "$RPC_URL"
```

If the chain enforces a minimum lockup duration, do not set the lockup exactly at the minimum. Add a buffer so timestamp drift does not trigger `LockupDurationTooShort`.

## 6. Whitelist the StakePool

The whitelist target is the StakePool address, not the validator EOA:

```solidity
ValidatorManagement.setValidatorPoolAllowed(address stakePool, bool allowed)
```

This call must go through governance. Direct calls from an EOA are expected to revert.

Create calldata:

```bash
export ALLOW_CALL=$(cast calldata \
  "setValidatorPoolAllowed(address,bool)" \
  "$STAKE_POOL" true)
```

Create, vote, resolve, and execute the proposal according to the current governance process:

```bash
cast send "$GOVERNANCE_ADDRESS" \
  "createProposal(address,address[],bytes[],string)(uint64)" \
  "<YOUR_PROPOSER_POOL>" \
  "[$VALIDATOR_MANAGER_ADDRESS]" \
  "[$ALLOW_CALL]" \
  "add-validator-whitelist-validator-1" \
  --rpc-url "$RPC_URL" \
  --private-key <YOUR_PROPOSER_PRIVATE_KEY>

export PROPOSAL_ID="<YOUR_PROPOSAL_ID>"

cast send "$GOVERNANCE_ADDRESS" \
  "vote(address,uint64,uint128,bool)" \
  "<YOUR_PROPOSER_POOL>" "$PROPOSAL_ID" \
  340282366920938463463374607431768211455 true \
  --rpc-url "$RPC_URL" \
  --private-key <YOUR_PROPOSER_PRIVATE_KEY>

cast send "$GOVERNANCE_ADDRESS" \
  "resolve(uint64)" "$PROPOSAL_ID" \
  --rpc-url "$RPC_URL" \
  --private-key <YOUR_PROPOSER_PRIVATE_KEY>

cast send "$GOVERNANCE_ADDRESS" \
  "execute(uint64,address[],bytes[])" \
  "$PROPOSAL_ID" \
  "[$VALIDATOR_MANAGER_ADDRESS]" \
  "[$ALLOW_CALL]" \
  --rpc-url "$RPC_URL" \
  --private-key <YOUR_GOVERNANCE_EXECUTOR_PRIVATE_KEY>
```

Confirm the pool is allowed:

```bash
cast call "$VALIDATOR_MANAGER_ADDRESS" \
  "isValidatorPoolAllowed(address)(bool)" "$STAKE_POOL" \
  --rpc-url "$RPC_URL"
```

## 7. Join the Validator Set

Read the node's public identity:

```bash
export CONSENSUS_PUBLIC_KEY=$(yq -r '.consensus_public_key' \
  <YOUR_GRAVITY_SDK_PATH>/cluster/output/validator-1/config/identity.public.yaml)
export CONSENSUS_POP=$(yq -r '.consensus_pop' \
  <YOUR_GRAVITY_SDK_PATH>/cluster/output/validator-1/config/identity.public.yaml)
export NETWORK_PUBLIC_KEY=$(yq -r '.network_public_key' \
  <YOUR_GRAVITY_SDK_PATH>/cluster/output/validator-1/config/identity.public.yaml)
```

Join:

```bash
gravity_cli validator join \
  --rpc-url "$RPC_URL" \
  --stake-pool "$STAKE_POOL" \
  --consensus-public-key "$CONSENSUS_PUBLIC_KEY" \
  --consensus-pop "$CONSENSUS_POP" \
  --network-public-key "$NETWORK_PUBLIC_KEY" \
  --validator-network-address "/dns/<YOUR_VALIDATOR_HOST>/tcp/6180" \
  --fullnode-network-address "/dns/<YOUR_VALIDATOR_HOST>/tcp/6190" \
  --moniker "validator-1" \
  --gas-limit <YOUR_GAS_LIMIT>
```

The signer must be the StakePool operator.

## 8. Start and Verify

```bash
bash <YOUR_DEPLOY_BASE_DIR>/validator-1/script/start.sh
```

Check validator set and epoch status:

```bash
gravity_cli validator list --rpc-url "$RPC_URL"
gravity_cli epoch status --rpc-url "$RPC_URL"

cast call "$VALIDATOR_MANAGER_ADDRESS" \
  "getValidatorStatus(address)(uint8)" "$STAKE_POOL" \
  --rpc-url "$RPC_URL"
```

Status values:

| Value | Status             |
| ----- | ------------------ |
| `0`   | `INACTIVE`         |
| `1`   | `PENDING_ACTIVE`   |
| `2`   | `ACTIVE`           |
| `3`   | `PENDING_INACTIVE` |

After joining, a validator usually enters `PENDING_ACTIVE` and becomes `ACTIVE` after an epoch transition.

You can also check node health:

```bash
gravity_cli status --rpc-url "$RPC_URL"
curl -s http://127.0.0.1:8545 \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```

## Leave the Validator Set

To leave:

```bash
gravity_cli validator leave \
  --rpc-url "$RPC_URL" \
  --stake-pool "$STAKE_POOL" \
  --gas-limit <YOUR_GAS_LIMIT>
```

If the validator is `ACTIVE`, it becomes `PENDING_INACTIVE` and exits after the next epoch transition. If it is still `PENDING_ACTIVE`, it can become `INACTIVE` immediately.

Verify:

```bash
gravity_cli validator list --rpc-url "$RPC_URL"
```

## Troubleshooting

| Symptom                                   | Cause / fix                                                                                                   |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `isValidatorPoolAllowed` returns `false`  | The governance whitelist proposal has not executed, or it targeted the wrong StakePool.                       |
| `LockupDurationTooShort`                  | Increase the lockup duration above the minimum with a buffer.                                                 |
| Validator remains `PENDING_ACTIVE`        | Activation normally happens at the next epoch transition. Check `gravity_cli epoch status`.                   |
| `Address not in set: <OLD_OWNER_ACCOUNT>` | Another node's `secure_storage.json` was copied. Remove it and regenerate/redeploy with the correct identity. |
| Node paths do not point to `<node>/data`  | `data_dir` should be the deploy directory, not the database directory.                                        |

## See Also

* [Run a Gravity Mainnet Public Full Node](/gravity-networks/run-a-mainnet-pfn)
* [Run a Gravity Mainnet VFN](/gravity-networks/run-a-mainnet-vfn)
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet)
* [Gravity Mainnet (L1) Contracts](/developer-resources/mainnet)


# Gravity Longevity Testnet (L1)

## **Network Details**

* **Chain ID:** `7771625`
* **Status:** Long-running testnet — no planned resets.
* **Configuration:** See [genesis/testnet](https://github.com/Galxe/gravity-sdk/tree/main/genesis/testnet) for the exact version and network configuration.

## **Developer Resources**

* **Faucet:** [Gravity Testnet Faucet](https://faucet.gravity.xyz/)
* **Explorer:** [Gravity Testnet Explorer](https://explorer-testnet.gravity.xyz/)
* **RPC Endpoint:** [Gravity Testnet RPC](https://testnet-rpc.gravity.xyz)

## **Performance Benchmarking**

Benchmarking of the Gravity L1, conducted under controlled conditions, indicates the following performance metrics:

* **Block Time:** \~200ms
* **ERC20 Transfer Throughput:** \~**9,500 – 11,000 TPS** on a 3-validator cluster (8 vCPU / 16 GB RAM per node); limited by disk I/O persistence latency, not CPU or execution.

For detailed results and bottleneck analysis, see [3-Validator Cluster Benchmark Results](/research-and-development/benchmark-results).

For instructions on how to reproduce these results, refer to the [Benchmark Reproduction Guide](/research-and-development/benchmark-guide).


# Deployed Contracts

Canonical EVM ecosystem preinstall contracts on Gravity Mainnet (L1).

Gravity L1 ships the standard EVM ecosystem contracts at their **universal cross-chain addresses** — the same addresses they occupy on Ethereum, Base, Arbitrum, and most other EVM chains. Because tooling (viem, ethers, wagmi, Foundry, wallet SDKs, ERC-4337 bundlers, Safe UI, …) hardcodes these addresses, any dapp that relies on them works on Gravity with **zero per-chain configuration**.

{% hint style="info" %}
These are the standard, audited ecosystem deployments — distinct from Gravity's own **system runtime contracts** in the `0x1625Fxxxx` range. For those, see [System Contracts](/developer-resources/mainnet).
{% endhint %}

## Deployer factories (L1, chain ID `127001`)

| Contract                                | Address                                      | Role                                                |
| --------------------------------------- | -------------------------------------------- | --------------------------------------------------- |
| Arachnid Deterministic Deployment Proxy | `0x4e59b44847b379578588920cA78FbF26c0B4956C` | `CREATE2` deployer factory                          |
| CreateX                                 | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` | `CREATE2` / `CREATE3` deployer factory              |
| Safe Singleton Factory                  | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | `CREATE2` deployer factory (used by the Safe suite) |

## Core infrastructure

| Contract       | Address                                      | Role                                    |
| -------------- | -------------------------------------------- | --------------------------------------- |
| Multicall3     | `0xcA11bde05977b3631167028862bE2a173976CA11` | Batched reads/writes in a single call   |
| Permit2        | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Uniswap signature-based token approvals |
| Wrapped G (wG) | `0xBB859E225ac8Fb6BE1C7e38D87b767e95Fef0EbD` | ERC-20 wrapper for native G             |

## ERC-4337 account abstraction

| Contract           | Address                                      | Role                                          |
| ------------------ | -------------------------------------------- | --------------------------------------------- |
| EntryPoint v0.6    | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` | Account-abstraction entrypoint                |
| SenderCreator v0.6 | `0x7fc98430eAEdbb6070B35B39D798725049088348` | EntryPoint v0.6 account-deployment helper     |
| EntryPoint v0.7    | `0x0000000071727De22E5E9d8BAf0edAc6f37da032` | Account-abstraction entrypoint                |
| SenderCreator v0.7 | `0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C` | EntryPoint v0.7 account-deployment helper     |
| EntryPoint v0.8    | `0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108` | Account-abstraction entrypoint (EIP-7702 era) |

All three EntryPoint versions are live, so bundlers, paymasters, and smart-wallet SDKs work on Gravity regardless of which version they target.

## Safe{Wallet} smart-account suite (v1.4.1)

The full canonical [Safe](https://safe.global) contract suite is deployed at its universal addresses, so the Safe SDK / Transaction Service and any Safe-based tooling work on Gravity.

| Contract                     | Address                                      | Role                                                 |
| ---------------------------- | -------------------------------------------- | ---------------------------------------------------- |
| Safe (L1 singleton)          | `0x41675C099F32341bf84BFc5382aF534df5C7461a` | Safe master copy (mainnet-style)                     |
| SafeL2 (L2 singleton)        | `0x29fcB43b46531BcA003ddC8FCB67FFE91900C762` | Safe master copy emitting events for indexers        |
| SafeProxyFactory             | `0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67` | Deploys Safe proxies (`createProxyWithNonce`)        |
| CompatibilityFallbackHandler | `0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99` | Default fallback handler (EIP-1271, token receivers) |
| MultiSend                    | `0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526` | Batch multiple calls in one Safe tx                  |
| MultiSendCallOnly            | `0x9641d764fc13c8B624c04430C7356C1C7C8102e2` | Batch `CALL`-only txs (no delegatecall)              |
| CreateCall                   | `0x9b35Af71d77eaf8d7e40252370304687390A1A52` | Deploy contracts from within a Safe                  |
| SignMessageLib               | `0xd53cd0aB83D845Ac265BE939c57F53AD838012c9` | On-chain EIP-1271 message signing                    |
| SimulateTxAccessor           | `0x3d4BA2E0884aa488718476ca2FB8Efc291A46199` | `staticcall` tx simulation                           |

{% hint style="info" %}
On Gravity, point Safe proxies at the **SafeL2** singleton (`0x29fc…0C762`) rather than the L1 `Safe` — the L2 variant emits the events the Safe Transaction Service and indexers rely on (the L1 singleton is the mainnet/gas-optimised variant).
{% endhint %}

## Bridged asset tokens

Canonical bridged representations of the major assets, deployed deterministically (CREATE2 via CreateX) by the Gravity operator on 2026-08-11. USDC.e follows [Circle's Bridged USDC Standard](https://www.circle.com/bridged-usdc) (upgrade path to native USDC); USDT.e and WETH.e are Chainlink `BurnMintERC20` tokens (burn/mint RBAC, CCIP-ready).

{% hint style="warning" %}
**Deployed, but not yet usable.** The bridge wire-up with the partner team (Chainlink) is still in progress: total supply of all three tokens is 0, no mint/burn roles are configured, and there is no bridge route in or out. Until the handover completes, do **not** integrate these tokens as live assets, list them as usable in wallets or UIs, or provide liquidity against them — any pre-handover "liquidity" in them is unbacked. The addresses below are published so integrators can prepare.
{% endhint %}

| Token                           | Address                                      | Decimals | Standard                      |
| ------------------------------- | -------------------------------------------- | -------- | ----------------------------- |
| USDC.e — Bridged USDC (Gravity) | `0x979c024b381E25a093b8B4CEb06e74B8140664ff` | 6        | Circle FiatToken v2.2 (proxy) |
| USDT.e — Bridged USDT (Gravity) | `0x06Fd3e67231baea179676c490482372F7Fb4A3f2` | 6        | Chainlink BurnMintERC20       |
| WETH.e — Bridged WETH (Gravity) | `0x9Da9C5b2CBf7dcC773071338A6480e0E5FDee177` | 18       | Chainlink BurnMintERC20       |

Supporting contracts for USDC.e: implementation `0xc4092FcAFB2D2B6367b25E2e2e2d8F306402bcBE`, MasterMinter `0x71C045E9A23dFAAA11828b4582cbBDafDca21B8a`, SignatureChecker library `0xFe6f85f6111DB61D04de45bd2c9E0EA56F309e4e`.

## Verify before you hardcode

Confirm an address has code before relying on it:

```bash
cast code 0xcA11bde05977b3631167028862bE2a173976CA11 --rpc-url https://mainnet-rpc.gravity.xyz
```

A non-empty result means the contract is live; an empty `0x` means it is not deployed yet.

## See also

* [System Contracts](/developer-resources/mainnet) — Gravity's system runtime and bridge contracts (`0x1625Fxxxx`).
* [Token Contracts on Gravity](/the-g-token/token-contracts) — canonical ERC-20 list (G, wG, USDT, …).
* [Gravity Skill](/developer-resources/gravity-skill) — the agent skill that bundles these addresses for AI coding tools.
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) — network connection parameters.


# Deployed Contracts (Testnet)

Canonical EVM ecosystem preinstall contracts on the Gravity Longevity Testnet (L1).

The Gravity Longevity Testnet (L1, Chain ID `7771625`) ships the same standard EVM ecosystem contracts as mainnet, at their **universal cross-chain addresses** — the same addresses they occupy on Ethereum, Base, Arbitrum, Gravity Mainnet, and most other EVM chains. Because tooling (viem, ethers, wagmi, Foundry, wallet SDKs, ERC-4337 bundlers, Safe UI, …) hardcodes these addresses, any dapp that relies on them works on the testnet with **zero per-chain configuration**.

{% hint style="info" %}
These are the standard, audited ecosystem deployments — distinct from Gravity's own **system runtime contracts** in the `0x1625Fxxxx` range. Addresses match [Gravity Mainnet (L1)](/developer-resources/deployed-contracts). Prefer a quick `cast code` check before hardcoding (see [Verify before you hardcode](#verify-before-you-hardcode)).
{% endhint %}

## Deployer factories (L1, chain ID `7771625`)

| Contract                                | Address                                      | Role                                                |
| --------------------------------------- | -------------------------------------------- | --------------------------------------------------- |
| Arachnid Deterministic Deployment Proxy | `0x4e59b44847b379578588920cA78FbF26c0B4956C` | `CREATE2` deployer factory                          |
| CreateX                                 | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` | `CREATE2` / `CREATE3` deployer factory              |
| Safe Singleton Factory                  | `0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7` | `CREATE2` deployer factory (used by the Safe suite) |

## Core infrastructure

| Contract       | Address                                      | Role                                    |
| -------------- | -------------------------------------------- | --------------------------------------- |
| Multicall3     | `0xcA11bde05977b3631167028862bE2a173976CA11` | Batched reads/writes in a single call   |
| Permit2        | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Uniswap signature-based token approvals |
| Wrapped G (wG) | `0xBB859E225ac8Fb6BE1C7e38D87b767e95Fef0EbD` | ERC-20 wrapper for native G             |

## ERC-4337 account abstraction

| Contract           | Address                                      | Role                                          |
| ------------------ | -------------------------------------------- | --------------------------------------------- |
| EntryPoint v0.6    | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` | Account-abstraction entrypoint                |
| SenderCreator v0.6 | `0x7fc98430eAEdbb6070B35B39D798725049088348` | EntryPoint v0.6 account-deployment helper     |
| EntryPoint v0.7    | `0x0000000071727De22E5E9d8BAf0edAc6f37da032` | Account-abstraction entrypoint                |
| SenderCreator v0.7 | `0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C` | EntryPoint v0.7 account-deployment helper     |
| EntryPoint v0.8    | `0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108` | Account-abstraction entrypoint (EIP-7702 era) |

## Safe{Wallet} smart-account suite (v1.4.1)

The full canonical [Safe](https://safe.global) contract suite is deployed on the Longevity Testnet at the same universal addresses as [mainnet](/developer-resources/deployed-contracts#safe-wallet-smart-account-suite-v1-4-1). Safe SDK / Foundry / cast workflows that target these addresses work without per-chain overrides.

| Contract                     | Address                                      | Role                                                 |
| ---------------------------- | -------------------------------------------- | ---------------------------------------------------- |
| Safe (L1 singleton)          | `0x41675C099F32341bf84BFc5382aF534df5C7461a` | Safe master copy (mainnet-style)                     |
| SafeL2 (L2 singleton)        | `0x29fcB43b46531BcA003ddC8FCB67FFE91900C762` | Safe master copy emitting events for indexers        |
| SafeProxyFactory             | `0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67` | Deploys Safe proxies (`createProxyWithNonce`)        |
| CompatibilityFallbackHandler | `0xfd0732Dc9E303f09fCEf3a7388Ad10A83459Ec99` | Default fallback handler (EIP-1271, token receivers) |
| MultiSend                    | `0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526` | Batch multiple calls in one Safe tx                  |
| MultiSendCallOnly            | `0x9641d764fc13c8B624c04430C7356C1C7C8102e2` | Batch `CALL`-only txs (no delegatecall)              |
| CreateCall                   | `0x9b35Af71d77eaf8d7e40252370304687390A1A52` | Deploy contracts from within a Safe                  |
| SignMessageLib               | `0xd53cd0aB83D845Ac265BE939c57F53AD838012c9` | On-chain EIP-1271 message signing                    |
| SimulateTxAccessor           | `0x3d4BA2E0884aa488718476ca2FB8Efc291A46199` | `staticcall` tx simulation                           |

{% hint style="info" %}
On Gravity (mainnet and Longevity testnet), point user Safe proxies at the **SafeL2** singleton (`0x29fc…0C762`) rather than the L1 `Safe` — the L2 variant emits the events indexers and the Safe Transaction Service rely on.
{% endhint %}

{% hint style="warning" %}
**Hosted Safe UI:** [`safe.gravity.xyz`](https://safe.gravity.xyz) currently lists Alpha L2 and Gravity Mainnet (L1); Longevity testnet (`7771625`) is **not** in that UI. Create and execute Safes on testnet via Safe SDK, Protocol Kit, or Foundry/`cast` against the addresses above.
{% endhint %}

## Bridged asset tokens

Deployed 2026-08-11 at the **same addresses as mainnet** (deterministic CREATE2 via CreateX). Like on mainnet, supply is 0 and no mint/burn roles are configured until the bridge wire-up completes — on testnet these exist for bridge-partner integration testing.

| Token                           | Address                                      | Decimals | Standard                      |
| ------------------------------- | -------------------------------------------- | -------- | ----------------------------- |
| USDC.e — Bridged USDC (Gravity) | `0x979c024b381E25a093b8B4CEb06e74B8140664ff` | 6        | Circle FiatToken v2.2 (proxy) |
| USDT.e — Bridged USDT (Gravity) | `0x06Fd3e67231baea179676c490482372F7Fb4A3f2` | 6        | Chainlink BurnMintERC20       |
| WETH.e — Bridged WETH (Gravity) | `0x9Da9C5b2CBf7dcC773071338A6480e0E5FDee177` | 18       | Chainlink BurnMintERC20       |

## Verify before you hardcode

Confirm an address has code before relying on it:

```bash
cast code 0xcA11bde05977b3631167028862bE2a173976CA11 --rpc-url https://testnet-rpc.gravity.xyz
```

A non-empty result means the contract is live; an empty `0x` means it is not deployed yet.

## See also

* [Deployed Contracts (Mainnet L1)](/developer-resources/deployed-contracts) — the same preinstalls on Gravity Mainnet (`127001`).
* [Gravity Longevity Testnet (L1)](/gravity-networks/l1-longevity-testnet) — network connection parameters and faucet.
* [Token Contracts on Gravity](/the-g-token/token-contracts) — canonical ERC-20 list (G, wG, …).


# Gravity Skill

Official Agent Skill that teaches AI coding tools how to build on Gravity.

The **Gravity Skill** is an official [Agent Skill](https://docs.claude.com/en/docs/claude-code/skills) that loads Gravity's chain knowledge into your AI coding assistant on demand — network params, the system-contract address map, the native on-chain oracle, the cross-chain G token bridge, safe on-chain randomness, and the canonical EVM preinstalls.

It's written in the standard [Agent Skills](https://github.com/anthropics/agent-skills) (`SKILL.md`) format, so any agent that understands skills — **Claude Code, Cursor, Codex, and 50+ others** — can use it. Source: [Galxe/gravity-skills](https://github.com/Galxe/gravity-skills).

## Install

The easiest way is the [`skills`](https://github.com/vercel-labs/skills) CLI, which installs into whichever agent you use (Claude Code, Cursor, Codex, OpenCode, Cline, Copilot, and more):

```bash
npx skills add https://github.com/Galxe/gravity-skills
```

Then ask your agent anything about building on Gravity and it loads the skill on demand. Re-run `npx skills update` to pull the latest.

{% hint style="info" %}
**Claude Code plugin** — add the marketplace and install:

```
/plugin marketplace add Galxe/gravity-skills
/plugin install gravity@gravity-skills
```

**Manual** — point any `SKILL.md`-aware agent at the [`skills/gravity/`](https://github.com/Galxe/gravity-skills/tree/main/skills/gravity) directory, or copy it into your agent's skills folder.
{% endhint %}

## What it covers

| Skill     | What it covers                                                                                                                                                                                                                                                                                                                                        |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gravity` | Core reference for writing, deploying, and integrating smart contracts on Gravity L1: network parameters, the system-contract address map, the native oracle ABI, the cross-chain G token bridge (including a copy-paste `cast` permit recipe), safe on-chain randomness, and the canonical EVM preinstalls (Multicall3, Permit2, CreateX, ERC-4337). |

Each skill uses progressive disclosure: a short `SKILL.md` entry point that links into focused `references/` docs and runnable `examples/` (e.g. `OracleConsumer.sol`, `RandomnessConsumer.sol`, and the G-bridge walkthrough).

## Sources of truth

Addresses and ABIs in the skill are distilled from the canonical Gravity repositories. When in doubt, defer to:

* Core system contracts: [Galxe/gravity\_chain\_core\_contracts](https://github.com/Galxe/gravity_chain_core_contracts)
* This documentation site: [docs.gravity.xyz](https://docs.gravity.xyz)

{% hint style="warning" %}
Addresses are load-bearing. The skill instructs agents to copy hex addresses verbatim and to surface `TBA` / `blocked` statuses rather than inventing values.
{% endhint %}

## See also

* [Deployed Contracts (EVM Preinstalls)](/developer-resources/deployed-contracts) — the canonical addresses the skill references.
* [System Contracts](/developer-resources/mainnet) — Gravity's system runtime and bridge contracts.
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) — network connection parameters.


# System Contracts

System and bridge contract addresses on Gravity Mainnet (L1).

{% hint style="info" %}
The addresses on this page are for **Gravity Mainnet (L1, chain ID `127001`)**. For the legacy **Gravity Alpha Mainnet (L2, Arbitrum Nitro, chain ID `1625`)** rollup contracts (rollup, inbox, outbox, sequencer, gateways), see [Gravity Alpha Mainnet (L2) Contracts](/legacy-alpha-mainnet-l2/mainnet).
{% endhint %}

Gravity L1 system runtime contracts live at fixed, well-known addresses in the `0x1625F0000`–`0x1625F5xxx` range. They cannot be re-deployed; adding a new system contract requires a hardfork.

## System runtime contracts

### Consensus engine (`0x1625F0xxx`)

| Address       | Contract     | Purpose                                            |
| ------------- | ------------ | -------------------------------------------------- |
| `0x1625F0000` | SystemCaller | Block prologue, NIL blocks, system-initiated calls |
| `0x1625F0001` | Genesis      | Chain initialization (active only at genesis)      |

### Runtime configurations (`0x1625F1xxx`)

| Address       | Contract                 | Purpose                                               |
| ------------- | ------------------------ | ----------------------------------------------------- |
| `0x1625F1000` | Timestamp                | On-chain microsecond-precision time                   |
| `0x1625F1001` | StakeConfig              | Staking parameters (lockup, minimum stake, …)         |
| `0x1625F1002` | ValidatorConfig          | Validator parameters (bond range, unbonding delay, …) |
| `0x1625F1003` | RandomnessConfig         | DKG threshold parameters                              |
| `0x1625F1004` | GovernanceConfig         | Voting threshold, proposal stake                      |
| `0x1625F1005` | EpochConfig              | Epoch interval duration                               |
| `0x1625F1006` | VersionConfig            | Protocol major version                                |
| `0x1625F1007` | ConsensusConfig          | Consensus parameters (BCS-serialized)                 |
| `0x1625F1008` | ExecutionConfig          | VM execution parameters (BCS-serialized)              |
| `0x1625F1009` | OracleTaskConfig         | Continuous oracle task configuration                  |
| `0x1625F100A` | OnDemandOracleTaskConfig | On-demand oracle request type registry                |

### Staking & validator (`0x1625F2xxx`)

| Address       | Contract           | Purpose                                          |
| ------------- | ------------------ | ------------------------------------------------ |
| `0x1625F2000` | Staking            | Governance staking (open to all G holders)       |
| `0x1625F2001` | ValidatorManager   | Validator registration, bonding, set transitions |
| `0x1625F2002` | DKG                | Distributed Key Generation session lifecycle     |
| `0x1625F2003` | Reconfiguration    | Epoch transitions and reconfiguration            |
| `0x1625F2004` | Block              | Block prologue/epilogue handler                  |
| `0x1625F2005` | PerformanceTracker | Per-validator success/failure proposal tracking  |

### Governance (`0x1625F3xxx`)

| Address       | Contract   | Purpose                                           |
| ------------- | ---------- | ------------------------------------------------- |
| `0x1625F3000` | Governance | Proposal lifecycle: submission, voting, execution |

### Oracle (`0x1625F4xxx`)

| Address       | Contract           | Purpose                                                                                                                                         |
| ------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `0x1625F4000` | NativeOracle       | Verified external data (blockchains, JWK providers, DNS)                                                                                        |
| `0x1625F4001` | JWKManager         | JWKs for keyless account authentication                                                                                                         |
| `0x1625F4002` | OracleRequestQueue | User-initiated on-demand oracle requests — **address reserved, not yet deployed** (`eth_getCode` returns `0x`); do not integrate against it yet |

### Precompiles (`0x1625F5xxx`)

| Address       | Contract               | Purpose                                    |
| ------------- | ---------------------- | ------------------------------------------ |
| `0x1625F5000` | NativeMintPrecompile   | Authorized native G mint                   |
| `0x1625F5001` | BlsPopVerifyPrecompile | BLS12-381 proof-of-possession verification |

The full Solidity source for these contracts is published at [Galxe/gravity\_chain\_core\_contracts](https://github.com/Galxe/gravity_chain_core_contracts).

## Cross-chain bridge

The canonical bridge consists of two contracts on **Ethereum mainnet**, paired with the `GBridgeReceiver` contract on Gravity L1 (deployed at genesis) that mints native G via the native-mint precompile once the consensus engine relays a verified message through the native oracle:

| Contract         | Address                                      | Purpose                                                                 |
| ---------------- | -------------------------------------------- | ----------------------------------------------------------------------- |
| `GravityPortal`  | `0x76cf8526Fa9461e50B2c6702a7246ce6915f6E53` | Charges ETH fees, emits `MessageSent` events for consensus              |
| `GBridgeSender`  | `0xE82c61Ac9Ec2041b493118051afa4F18a55dC876` | Locks G ERC-20 from the user, forwards the bridge message to the Portal |
| Owner (multisig) | `0xbD6e434dB90FD8AD4E28d85C133AD34cA6fbfB6D` | Gnosis Safe 3-of-6, owner of both Portal and Sender                     |

Both Ethereum contracts are owned by a 3-of-6 Gnosis Safe multisig. For the end-user bridging flow, see [How to Get G](/the-g-token/how-to-get-g).

## Token contracts

For the canonical ERC-20 token list on Gravity L1 (native G, wG, and bridged assets as their bridge routes go live), see [Token Contracts on Gravity](/the-g-token/token-contracts).

## See also

* [Verify a Smart Contract](/legacy-alpha-mainnet-l2/verify-a-smart-contract) — explorer verification (Foundry / Hardhat).
* [Token Contracts on Gravity](/the-g-token/token-contracts) — ERC-20s on L1.
* [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) — network connection parameters.
* [Legacy: Alpha Mainnet (L2) contracts](/legacy-alpha-mainnet-l2/mainnet) — rollup, inbox, outbox, gateways.


# Gravity Litepaper

Building Gravity Chain: A High-Performance EVM Layer-1 Powered by Grevm and Gravity SDK

{% hint style="warning" %}
**Historical note** — this is the original 2024 design paper for Gravity Chain. Some elements of the proposed architecture, in particular the restaking-based security model (EigenLayer / Babylon integration), have evolved as Gravity moved from proposal through testnet to mainnet. At launch, Gravity L1 uses native G staking under a permissioned initial validator set; restaking integrations are not part of the current network. For up-to-date network details see [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and the [Introduction](/). The rest of this paper — pipelined consensus, parallel EVM (Grevm), Block Stream Reactor execution, storage design — remains the canonical reference for Gravity's architecture.
{% endhint %}

## Abstract

**Gravity Chain** is a pioneering high-performance EVM-compatible layer-1 blockchain designed for mass adoption and an omnichain future, built by Galxe. Offering **1 gigagas per second throughput**, **sub-second finality**, and **restaking-powered PoS security**, at its core, Gravity is built using two major open source components: (1) **Gravity SDK**, a restaking-powered **pipelined** AptosBFT PoS consensus engine, and (2) **Gravity reth**, a Block Stream Reactor (BSR) execution layer powered by our parallel EVM **Grevm (Gravity EVM)**. They are designed to empower web3 applications to launch their own alternative L1s and faster-finality L2s, specifically optimized for EVM chains. This paper introduces the engineering design and technological innovations behind Gravity, illustrating how the Gravity meets high-performance demands through a combination of pipelined architecture, state-of-the-art consensus algorithm, parallel execution, and highly optimized storage layer, specifically by augmenting [reth](https://github.com/paradigmxyz/reth) and refining an open-source consensus engine from [Aptos](https://github.com/aptos-labs/aptos-core).

## Introduction

The development of Gravity was initially driven by the challenges we encountered with Galxe, a leading Web3 application offering a suite of services such as loyalty points, campaign NFTs, token rewards, zk-identity, and omnichain smart savings. Galxe's rapid growth has resulted in a significant volume of transactions, with its loyalty points system processing over 51.2 transactions per second and token rewards campaigns processing over 32.1 transactions per second on average. As we move towards decentralizing Galxe's backend, transitioning all its use cases to an EVM blockchain while maintaining optimal user experience became challenging. This shift highlights the necessity for a high-performance EVM blockchain capable of supporting (1) high transaction throughput, and (2) near-instantaneous finality.

Considering these performance demands, the decision to either adopt existing L2 solutions or develop a new Layer-1 chain is a critical. The core trade-off lies in the approach to achieving transaction finality: using a consensus algorithm, which defines an L1, or rollup protocols, which categorize as an L2. The trade-off is clear—L1s generally have lower theoretical throughput because of the cost of consensus algorithms. However, this also results in significantly faster time-to-finality compared to L2s. For example, with a consensus algorithm like AptosBFT, finality can be achieved in sub-second, whereas optimistic roll-ups can take up to seven days due to the challenge period. Even with using zero-knowledge proof to speed up this process, the time-to-finality remains in the order of hours. Given Gravity's need for near-instant finality—essential for Galxe user experience and particularly for the Gravity's omnichain intent protocol—we decided to develop an L1.

Moreover, while L2s offer native support for messaging with Ethereum, L1 chains like Gravity can provide comparable, and even more extensive, interoperability through the Gravity Intent Protocol and cross-chain bridges built by players of the Ethereum ecosystem. This approach not only enables seamless communication with Ethereum but also extends interoperability to other blockchain networks, enhancing the overall connectivity of the whole web3 ecosystems.

Furthermore, with the adoption of restaking protocols, bootstrapping a Proof-of-Stake (PoS) L1 blockchain is no longer as challenging as it once was. By integrating restaking protocols like EigenLayer and Babylon, L1s can tap into the vast staked value of Ethereum and Bitcoin, and their extensive validator networks. The economic trust provided by these restaking protocols from the outset serves as a solid foundation for PoS consensus, enabling Gravity to achieve similar levels of decentralization and security to that of Ethereum.

In light of these considerations, we decided to build Gravity, a high-performance EVM-compatible layer-1 blockchain, to meet the scalability and performance demands of modern web3 applications. Although the development of Gravity was initially driven by the needs of Galxe, the Gravity SDK and Grevm (Gravity EVM) are designed to offering a flexible framework for building alternative L1s and faster-finality L2s, just like Tendermint/Cosmos SDK.

### Call for 1 gigagas per second throughput

The most critical performance requirement for any blockchain is its throughput, typically measured in transactions per second (TPS) or gas per second (gas/s). Using Galxe's loyalty points system as an example, the system demands a minimum throughput of 4 million gas/s to function effectively. This estimate is based on the average gas usage per loyalty point transaction (80,000 gas) and the observed transaction rate of 51.2 transactions per second, which collectively equates to 4 million gas/s.

This estimate is further validated by real-world data from Gravity Alpha Mainnet, our experimental Layer 2. All loyalty points transactions on Gravity Alpha Mainnet have consistently demonstrated a throughput of approximately 4 million gas/s, confirming the above estimation.

![L2 data from https://rollup.wtf/](/files/OeOl8NIv9vbGqtxVBEYo)

While this demand may decrease slightly due to the higher costs associated with on-chain operations, The growth trajectory of Galxe suggests that during peak periods, the demand could easily reach two to three times the current level. Additionally, when factoring in other applications such as NFTs, token rewards, and future on-chain functionalities like fully on-chain questing powered by zero-knowledge proofs, the blockchain must be able to sustainably handle a throughput of 50 million gas/s, if Galxe becomes a fully on-chain DApp. If we assume a Pareto distribution of gas usage of applications on the [Gravity chain](https://gravity.xyz/), similar to how Uniswap consistently consumes [10% of Ethereum's gas usage](https://etherscan.io/gastracker), the chain should ideally support a sustainable throughput of 500 million gas/s to accommodate the broader ecosystem applications like cross-chain settlement for smart saving LSD, loyalty points trading DEXs, and NFT marketplaces. Given these estimations, it becomes clear that to meet the demands of applications in the ecosystem, we need an EVM blockchain of 1 gigagas per second throughput. This ensures that the performance ceiling is high enough to accommodate even more resource-intensive applications, enabling them to scale without being constrained by the chain's capabilities.

One of the critical parts of achieving such throughput is the parallel EVM. We have developed Grevm, a parallel EVM execution runtime, which is the fastest open-source parallel EVM implementation to date in our benchmark (see more details in the Grevm section below).

### Sub-Second Finality

In addition to throughput, the blockchain's finality time is a critical factor in maintaining a positive user experience. Users expect near-instantaneous responses similar to what they experience with centralized backends, just like web2 apps. In this regard, Galxe's requirements are akin to those of fully on-chain games, where low latency is crucial, though not as extreme. Current EVM blockchains, with time-to-finality ranges from several seconds to days, are far from meeting these expectations. We choose AptosBFT as the consensus algorithm choice for achieving such sub-second finality.

While L2 rollup can theoretically achieve higher throughput by eliminating the need for consensus, they typically introduce significant delays in finalizing transactions due to the challenge period. This latency is problematic for applications requiring near-instantaneous finality, like Galxe. Some DApps, such as cross-chain bridges, attempt to mitigate this by using "trust" modes, implementing external monitoring systems—like running a sequencer replica to check invariance—and bypassing the challenge period. However, these approaches introduce additional risks and complexities, which is not ideal for security-critical applications. To narrow the throughput gap between L2 rollup and L1, after introducing consensus, the Gravity SDK implemented a 5-stage pipeline, which parallelizes consensus for the next block and execution for the current block (see more details in the pipelining section).

### Restaking PoS security

Scaling Ethereum securely is not limited to L2 rollup. The Gravity SDK deliberately opts for a restaking-secured L1 architecture to balance **security**, **throughput**, **time-to-finality** and **interoperability**. Central to this strategy is a restaking module that integrates multiple restaking protocols, such as EigenLayer and Babylon, which provide the economic trust necessary to bootstrap and sustainably power a robust Proof-of-Stake (PoS) consensus.

By leveraging **economic trust** that is programmable on well-established networks, Gravity and chains built on Gravity SDK tap into: (1) Ethereum's $45 billion in staked value and 850,000 validators through building an Actively Validated Service (AVS) on Ethereum, based on EigenLayer, and (2) Bitcoin's $600 billion assets via Babylon's integration, using cryptographic primitives like extractable one-time signature (EOTS). This provides a secure foundation for PoS consensus from the outset, by extending security from well-established networks like Ethereum and Bitcoin, effectively addressing the typical challenges of bootstrapping new PoS blockchains, long-range attacks, and potential risks associated with any single assets like long-term sustainability.

## Gravity Chain Architecture

![Gravity Chain Architecture](/files/TJAO5nzoNyTXtIcKUyJN)

Gravity Chain is built on two major components: Gravity SDK and Gravity reth. Gravity SDK is a blockchain framework refined from the Aptos chain, the state-of-the-art PoS blockchain of the PBFT-family consensus, featuring a pipelined architecture that maximizes throughput and resource utilization. Gravity reth is a pipelined execution layer based on reth, running as a Block Stream Reactor (BSR), consuming the proposed blocks from the consensus layer. By innovating with reth, it is optimized for parallel execution, batched and asynchronous paralleled state commitment computation, and storage optimization. Two components are glued together via Gravity Consensus Engine Interface (GCEI) using a reth adaptor, seamlessly managed by a pipeline controller, which will dynamically adjust the pace of each stage based on the multiple backpressure signals from execution and consensus layer.

In this design, the block execution is decoupled from the block consensus, making execution layer a consumer of the proposed blocks. We optimize reth to make it fit into this pipelined block proposal process, managed by the Block Stream Reactor (BSR).

The flow of a transaction in Gravity Chain is as follows:

1. A transaction will first reach Gravity reth JSON RPC, a fully Ethereum-compatible JSON-RPC endpoint.
2. The transaction is then forwarded to Gravity SDK mempool, propagating across the network. Validators will try to batch transactions and form Quorum Store (QS) certificates.
3. The Leader of the round will propose a new block proposal, containing block metadata and ordered transactions picked mempool and quorum store.
4. Once the block proposal status become ordered, it will be passed to the execution layer.
5. On the execution layer side, Grevm will execute the transactions in parallel and generate execution results. The new state will be pass to state commitment and multi-version state manager.
6. The state commitment box will compute the state root and pass it to state consensus engine, which will try to reach a consensus on the state root.
7. Once the state root is finalized, it will notify execution storage to persistent the state root and the block data.

We will dive into the details of each component in the following sections.

## Gravity SDK: The First Open Source Pipeline Blockchain SDK

Gravity SDK is an open-source, modular blockchain framework that builds upon the world's most production-ready blockchain, Aptos. It is designed to modularize the existing architecture of the Aptos blockchain, borrowing battle-tested components such as the mempool with Quorum Store, the AptosBFT consensus engine to create a the world's first pipelined blockchain SDK.

The decision to base Gravity SDK on Aptos stems from several key factors:

* **State-of-the-Art Blockchain Foundation**: Aptos is the state-of-the-art PoS blockchain of the PBFT-family consensus. By introducing [Order Votes (AIP-89)](https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-89.md), AptosBFT has reduced the consensus latency to 3 hops, which is the theoretically optimal limit on a BFT based consensus protocol.
* **Performance Optimized for Extreme Demands**: Aptos has been meticulously optimized for performance, achieving an impressive throughput of roughly 160,000 transactions per second with a finality time of under one second.
* **Battle-Tested Reliability**: Aptos has already proven its reliability and robustness through real-world deployment in production environments, demonstrating its ability to handle demanding workloads with ease.
* **Rapid and Continuous Innovation**: Aptos continues to evolve at an exceptional pace. Over the past two years, [more than 100 Aptos Improvement Proposals (AIPs)](https://github.com/aptos-foundation/AIPs/wiki/Index-of-AIPs) have been proposed, discussed, implemented, and deployed on the Aptos mainnet. This relentless commitment to improvement keeps Aptos at the cutting edge of blockchain technology, serving as the North Star that continually guides the development of Gravity SDK and the chains built upon it.
* **Avoiding Reinvention**: Building on Aptos allows us to leverage its mature and well-tested foundation, avoiding the unnecessary complexities and risks associated with starting from scratch. Other attempts to outperform Aptos by reinventing the wheel lack both theoretical grounding and convincing innovations.
* **Synergetic Evolution** Aptos is a continuously evolving project, introducing features like the randomness API and other cutting-edge capabilities. By integrating closely with Aptos, Gravity SDK ensures that these innovations can be seamlessly incorporated, creating a synergistic relationship between Aptos and chains built on Gravity SDK, e.g. Gravity Chain. On the other hand, Gravity SDK also contributes back to Aptos, by modularizing the structure and introducing restaking-powered PoS security modules.

Blockchains built on Gravity SDK uses the Gravity Consensus Engine Interface (GCEI) to interact with the pipelined consensus engine. This interface is designed to be compatible with any execution layer, although Gravity SDK offers primary support around Gravity reth. We will dive into more details GCEI in the following section.

### Gravity Consent Engine Interface (GCEI)

The GCEI (Gravity Consensus Execution Interface) protocol is the communication bridge between the consensus and execution layer. It standardizes the interaction between the two layers, ensuring that consensus and execution processes are properly synchronized by the pipeline controller.

![GCEI Protocol](/files/CDdUsgjGqFQKdkTEx65U)

The major difference between the traditional blockchain SDK and Gravity SDK is its pipelined consensus engine. The execution layer must be implemented as a Block Stream Reactor, which means that the it must be able to continuously consume the proposed block stream, and the state commitment must be computed asynchronously from the transaction execution. Moreover, the execution layer must be able to provide backpressure signals to the consensus layer, which will dynamically adjust the pace of block proposing.

Besides, due to the pipelined nature of the Gravity SDK, the execution layer must be able to handle the un-executable transactions in the proposed block, as the mempool does not have the ability to strictly check the validity of any transaction due to lack of access to the newest world state: the execution might have not been finished yet. Also, the execution result, should not block further block generation, as after the Gravity SDK paralleled the block consensus and state consensus, the execution layer becomes a reactor to the proposed block stream, having the freedom to return the execution result in a later stage.

The GCEI protocol specification defines two sets of APIs:

* **Consensus Layer APIs**: These APIs are implemented by the Gravity SDK, and are used by the execution layer to react to the blocks proposed by the consensus engine, and submit the state commitment.
* **Execution Layer APIs**: These APIs must be implemented by the execution layer. Consensus engine will use these APIs to do best-effort validation of a transaction before proposing it in a block, stream proposed blocks, and notify the execution layer of the finalized state commitment.

In the perspective of the lifecycle of a transaction, the GCEI protocol defines the following:

1. **`check_txn`** (Execution Layer API)
   * **Input**: Takes a transaction (`GTxn`) as input
   * **Output**: Returns the sender address, nonce, and gas limit of the transaction.
   * **Usage**: This method is used by the consensus engine to run best-effort validation of a transaction before proposing it in a block. The method can be called multiple times for the same transaction, e.g., when the transaction enters the mempool, before it is proposed in a block, and when a state commitment is finalized.
2. **`submit_txn`** (Consensus Layer API)
   * **Input**: Accept a transaction (`GTxn`) from execution layer.
   * **Output**: Returns `Result<()>`, indicating whether the transaction was successfully added to the mempool.
   * **Usage**: Execution layer can use this method to submit a transaction to the mempool. The consensus engine will then gossip the transaction across the network, and form Quorum Store if a batch of transactions is received.
3. **`recv_ordered_block`** (Execution Layer API)
   * **Input**: Accepts an `ordered_block` (of type `BlockBatch`), which contains ordered transactions and block metadata.
   * **Output**: Returns `Result<()>`, indicating whether the block received and accepted by the execution layer.
   * **Usage**: Once a block is proposed by the consensus engine, it is sent to the execution layer for transaction execution. This method allows the execution layer to receive and process the ordered block.
4. **`update_state_commitment`** (Consensus Layer API)
   * **Input**: State commitment of a block number (`StateCommitment`).
   * **Output**: Returns `Result<()>`, indicating whether the state commitment was successfully accepted by local consensus engine.
   * **Usage**: Once state commitment is computed by the execution layer, it is sent to the consensus layer for finalization, i.e., reaching a 2f+1 light consensus with other validator. If the statement commitment consensus became falling far from proposed blocks, the pipeline controller will adjust the pace of block proposing.
5. **`commit_block_hash`** (Execution Layer API)
   * **Input**: Takes a vector of `block_ids`, representing blocks that are to be committed.
   * **Output**: Returns `Result<()>`, indicating the success or failure of the operation.
   * **Usage**: When the state commitment is finalized, consensus layer will notify the execution layer to commit the block hash to the blockchain storage.

### Blockchain Pipeline

Gravity SDK utilizes a 5-stage pipelined architecture to maximize hardware resource utilization, for higher throughput and lower latency. The pipeline interleaves the execution of tasks across different blocks, and the pipeline manager ensures that the blockchain is moving at a steady pace using feedback mechanisms. The first three stages are part of the consensus layer, while the last two stages are part of the execution layer.

Stages are as explained as follows:

* **Stage 1: Transaction Dissemination**: This stage efficiently disseminate transactions across validators to ensure timely and reliable inclusion during block building. The design decouples the transaction dissemination and consensus mechanisms, following the idea from [Narwhal & Tusk](https://arxiv.org/abs/2105.11827) and [Aptos](https://aptosfoundation.org/whitepaper/aptos-whitepaper_en.pdf), that, validators continuously share batches of transactions, utilizing all network resources concurrently. A proof of availability (PoAv, aka, Proof-of-Store and Quorum Store) is formed when a batch receives 2f + 1 stake-weighted signatures, ensuring that the batch is stored by at least f + 1 honest validators, making it retrievable for execution by all honest validators.
* **Stage 2: Block Metadata Ordering**: This stage establishes a consistent and agreed-upon order of transactions and block metadata within the network. The consensus mechanism (AptosBFT) follows the 2-chain rule to provide a Byzantine fault-tolerant block. The block will then be streamed to the execution stage, ready for parallel processing.
* **Stage 3 (BSR): Parallel Transaction Execution**: This stage is actually part of the execution layer, where transactions are executed in parallel. The execution results are then passed to the state commitment stage.
* **Stage 4: State Commitment**: This stage finalizes the state changes resulting from transaction execution and prepares for block finalization. The state commitment is computed asynchronously from the transaction execution, ensuring that the execution of the next block is not blocked by the state commitment of the current block.
* **Stage 5: State Persistence**: This stage persists the committed state changes to the blockchain's storage. The finalized State Root and associated data are stored in the Gravity Store, which uses a highly optimized storage engine designed for fast access and reliability. It also notifies the mempool and quorum store to clear transactions that can no longer be included in future blocks.

### Staking & Restaking Module

Bootstrapping a secure Proof-of-Stake (PoS) Layer 1 blockchain is a complex challenge, particularly when relying solely on staking chain-specific tokens. Such an approach may not provide sufficient economic security to protect the network, especially during the initial phases when the token value may be volatile and validator participation might be limited. To address this issue, the Gravity SDK introduces a flexible staking and restaking Module designed to enhance network security through both native and external staking mechanisms.

A key strategy employed by the Gravity SDK is the integration of restaking protocols like [EigenLayer](https://www.eigenlayer.xyz/) and [Babylon](https://babylonlabs.io/). These protocols enable validators to restake assets from other established networks like Ethereum and Bitcoin, effectively leveraging their existing security guarantees. By allowing validators to collateralize assets from these chains, the Gravity SDK amplifies the economic security of the network without being solely dependent on its native token. This approach not only bolsters the chain's resilience but also facilitates a more inclusive validator ecosystem. Modularity is a cornerstone of the staking module's design. The restaking component is built to be highly adaptable, allowing for seamless integration of new restaking protocols as the blockchain ecosystem evolves

In addition to supporting restaking assets, the module also accommodates staking of custom ERC20 tokens on supported chains, such as G token on Ethereum. Validators can stake allowed tokens to participate in consensus, contributing to the network's security. The voting power of each validator is calculated based on their total staked value, which includes both custom token stakes and assets from restaking protocols. This calculation adheres to chain-specific configurations, ensuring that each chain can define its staking and restaking parameters according to its unique requirements.

The epoch manager within the consensus engine interacts directly with the staking module to calculate the weight of the next validator set. By reading the staked values from the execution layer, it ensures that the consensus process accurately reflects the most recent staking activities. In this design, cross-chain values, such as the amount of staked assets from Ethereum, must be first bridged to the execution layer, before they are then used to calculate the total staked value of each validator. We leave this bridging mechanism to the execution layer, as it is more flexible for the execution layer to handle cross-chain communication in their preferred ways. PoS-bridge, zero-knowledge proof of chain state, and embedded self-bootstrapping cross-chain messaging are all possible solutions.

Further technical specifications, API design and comprehensive details of the staking and restaking mechanisms will be provided in forthcoming documentation releases.

## Gravity Reth: A Block Stream Reactor EVM Execution Layer

Integrating an Ethereum Virtual Machine (EVM) execution layer into the Gravity SDK architecture presents a unique set of challenges, particularly when aiming to fully exploit the capabilities of its pipelined consensus engine. To achieve seamless integration and unlock the full potential of this architecture, we must perform several key optimizations on reth, the open source Ethereum client. These optimizations fundamentally transform reth into Gravity reth, a pipeline-optimized EVM execution layer tailored for pipelined consensus engines.

Traditional blockchain architectures process blocks sequentially, ensuring that each block is fully validated and executed before the next is proposed. However, the Gravity SDK employs a pipelined consensus mechanism that decouples various stages of block processing to enhance performance. This paradigm shift introduces complexities:

1. **Unexpected Transactions**: In a pipelined chain, the mempool lacks access to the most recent world state because the execution of prior blocks may not have completed. Consequently, transactions included in proposed blocks might be un-executable at the time of proposal, as their validity cannot be strictly verified without the latest state.
2. **Non-Blocking Execution Results**: To prevent pipeline stall, the execution results should not stop subsequent block generation. The execution layer must be capable of processing proposed blocks asynchronously, returning execution outcomes at a later stage without stalling the consensus process. For EVM, this means that we need an alternative definition of `blockhash`, removing the dependency on the `stateRoot` field of the block header.

To address these challenges, we introduce four pivotal optimizations:

* **Block Stream Reactor (BSR)**: The BSR is designed to adapt reth to the pipelined block proposal process of the Gravity SDK. It enables the execution layer to continuously consume a stream of proposed blocks, functioning as a reactor that processes blocks asynchronously. The BSR establishes a dynamic feedback loop with the consensus engine, incorporating proper backpressure signals. These signals adjust the pace of block proposals and state commitments in real-time based on the execution layer's throughput and latency. If the execution layer lags due to complex transactions or resource constraints, the backpressure mechanism throttles the block proposal rate, ensuring system stability.
* **Decoupling State Commitment from Transaction Execution**: The second optimization involves separating the computation of state commitments from transaction execution. By decoupling these processes, we enable asynchronous state commitment computation, allowing the execution of subsequent blocks to proceed without waiting for the finalization of the current block's state commitment. We changed the definition of `blockhash` to remove the dependency on the `stateRoot` field of the block header, ensuring that state root computation do not block further block generation.
* **Optimization of the Storage Layer**: Efficient caching and persistence of multi-version state values and state commitments is critical in a pipelined architecture. The third optimization focuses on enhancing the storage layer to handle these requirements without introducing bottlenecks. By fine-tuning the storage mechanisms, we ensure that state data can be written rapidly and retrieved highly concurrently. This involves building a multi-version storage engine and support asynchronous I/O from the database to storage API.
* **Parallel EVM**: The final optimization involves parallelizing the execution of transactions within the EVM. We have developed Grevm, a parallel EVM runtime that significantly accelerates transaction processing by executing transactions concurrently. . Grevm leverages data dependency hints derived from transaction simulations to optimize parallel execution, minimizing transaction re-executions and enhancing throughput.

![Gravity Reth Architecture](/files/qHXTGZtIwKFY7hIS7dbr)

### Grevm (Gravity EVM) - Parallel EVM Execution

> Grevm is open-sourced on GitHub (If not, soon it will be). Please read its [README](https://github.com/Galxe/grevm/blob/main/README.md) for more details.

[Grevm (Gravity EVM)](https://github.com/Galxe/grevm) is an open-source, parallel EVM runtime based on [revm](https://github.com/bluealloy/revm). Grevm's algorithm is inspired by [BlockSTM](https://arxiv.org/abs/2203.06871), with enhancement of incorporating a transaction data dependency graph derived from simulation results. This mechanism enables more effective scheduling for parallel execution, minimizing transaction re-executions.

In our benchmark, Grevm stands as the **fastest** open-source parallel EVM implementation to date. For conflict-free transactions, Grevm is **4.13×** faster than sequential execution, running at **26.50 gigagas/s.** If we simulate real-world I/O latency of **100 μs**, it is **50.84×** faster than sequential execution, with **6.80 gigagas/s** throughput. This leap in performance is attributed to both the parallelized execution and the integration of asynchronous I/O operations—enabled by the parallelism—which further amplifies the speedup by efficiently overlapping I/O operations.

The seminal idea behind Grevm is to leverage the data dependency between transactions, using speculated transactions read/write set, to optimize parallel execution. While not all hints are perfectly precise, these simulation-based hints are generally accurate enough for practical purposes. For instance, on the Ethereum mainnet, by **historical gas usages**, approximately 30% of transactions are simple Ether transfers, and another 25%-30% are ERC20 token transfers, which typically involve reading and writing to a limited number of accounts and storage slots. In such transactions, simulation results are consistently accurate.

Building upon these insights, we have developed a **three-phase parallel execution framework** for **Grevm**, a follow-up work of **Block-STM** model by incorporating data dependency hints from transaction simulations:

* **Phase 1**: **Hint Generation & State Preloading**—Simulate transactions to gather dependency hints and warm-up memory cache. This phase can be performed at various points in time, depending on the design of the blockchain. For example, when new transactions arrive in the mempool, simulations can be run immediately to prepare dependency hints in advance.
* **Phase 2**: **Dependency Analysis**—Transform the dependency hints gathered during the simulation phase into a DAG that models the dependencies between transactions. This DAG serves as a roadmap for scheduling transactions in the subsequent parallel execution.
* **Phase 3**: **Concurrent Execution with Conflict Resolution**—Execute transactions in parallel using a modified BlockSTM algorithm that leverages the dependency DAG generated in Phase 2. Instead of the scheduler selecting transactions strictly based on their sequence numbers in the block (e.g., 1, 2, 3, ..., n), it now prioritizes transactions according to the DAG to minimize conflicts and reduce the need for re-executions.

![Grevm Parallel Execution Framework](/files/jsUds2Eo4vrHmloWhfQb)

### Asynchronous Batched State Commitment

The generation of state commitments remains a critical bottleneck in the blockchain pipeline, stemming from the inherently sequential nature of merklization. Each sub-tree computation must complete before the final state commitment can be produced, creating significant delays. While existing solutions, such as [reth's account-level parallelization](https://www.paradigm.xyz/2024/04/reth-perf), have introduced some degree of parallelism, there is ample room for further optimization. This is particularly relevant in the context of Gravity reth, a Block Stream Reactor (BSR) execution layer, where state commitment consensus is decoupled from transaction execution, where deferred and batched state commitment computation can be performed asynchronously without blocking execution.

To address these challenges, the proposed framework introduces the following key innovations:

**Asynchronous Batched Hash Computation**: Leveraging the decoupling of state commitment consensus from transaction execution, the framework enables asynchronous computation of state commitments. State root updates are batched—e.g., computed every 10 blocks—to reduce the frequency of state root calculations. This batching approach minimizes the overhead of frequent updates and reduces overall computational costs by aggregating shared dirty nodes for efficient hash computation. For small blocks, batching can significantly increase its parallelism, and for large blocks, it can reduce the overall computational cost.

**Full Parallelization**: The framework extends parallelization beyond individual account trees the whole state tree. For nodes marked as "dirty," the framework employs a Parallel State Calculation algorithm, which partitions the tree into independent subtrees. These subtrees are processed concurrently. The results are aggregated at the top level to compute the final root efficiently. This approach ensures that large blocks, with numerous transactions and state changes, can fully utilize multi-threading, maximizing throughput.

**Alternative Fast State Root**: To accommodate Ethereum's block header and `BLOCKHASH` opcode, which require access to the last 256 block state roots, we redefined the state root. Instead of relying on finalized state commitments—which are unavailable during transaction execution—we calculate the state root as the hash of the block's change sets combined with the previous state root. This approach enables faster state root computation without waiting for full state commitment finalization.

![Fully Parallel State Commitment Computation](/files/fdecUEBozSukAjOCZyXo)

### Gravity Store

High-performance blockchains require a more efficient storage layer to manage the vast amount of data generated by transaction execution and state commitment. The Gravity Store, a fine-tuned multi-version storage layer, builds on the foundation provided by reth, which already separates the state commitment store from the state storage store to mitigate state bloating and lower read/write amplification. However, additional demands arise to support parallel execution and asynchronous state commitment in the Gravity reth execution layer.

![Gravity Store](/files/ydbLLmRAldwYCMuSngPA)

To address these requirements, the Gravity Store introduces a highly efficient multi-version tree to facilitate the unique needs of our BSR architecture. It is used to manage state updates across multiple versions. Instead of recalculating hashes immediately after modifications, altered nodes are marked as dirty, allowing for deferred and batched hash computation against specific tree versions. This structure supports efficient operations like creating new versions, querying values from specific versions, and deleting versions below a certain height, thereby offering significant performance benefits for managing blockchain state.

We are also exploring developing our own storage engine, Gravity DB, which is designed to optimize the storage layer for blockchain use cases, and support fully asynchronous I/O operations. The design will be similar as [LETUS](https://dl.acm.org/doi/abs/10.1145/3626246.3653390), a log-structured Efficient Trusted Universal BlockChain Storage high-performance database engine for blockchain. We will publish more details in our upcoming blog post.

## Conclusion

Gravity Chain is a high-performance EVM-compatible layer-1 blockchain designed to meet the scalability and performance demands of modern web3 applications. By combining the Gravity SDK, a pipelined AptosBFT PoS consensus engine, and Gravity reth, a Block Stream Reactor execution layer powered by Grevm, Gravity offers 1 gigagas per second throughput, sub-second finality, and restaking-powered PoS security. These components are designed to empower web3 applications to launch their own alternative L1s and faster-finality L2s, specifically optimized for EVM chains.


# Gravity Reth

Gravity Reth is the fastest open-source EVM execution client, a performance-engineered fork of Reth.

### Abstract

We introduce [Gravity Reth](https://github.com/Galxe/gravity-reth/tree/main), an open-source, performance-engineered fork of Reth, designed to push the upper bounds of EVM execution speed. Through a suite of architectural innovations—including Grevm, a DAG-based optimistic parallel EVM; a **fully parallelized merklization** framework, a **high-performance caching** layer, an **optimized mempool,** and **a pipelined execution architecture**—Gravity Reth achieves state-of-the-art performance. In a benchmark involving ERC20 transfers across 100,000 accounts, Gravity Reth sustains \~**41,000 transactions per second (TPS)**, equivalent to \~**1.5 Gigagas/s**. This represents a greater than **4x performance boost** over the baseline Reth 1.4.8 client. We present the design and evaluation of Gravity Reth and our broader goal of contributing these optimizations to the open-source community to advance the performance of the EVM ecosystem.

## Introduction

For EVM-based ecosystems, the execution client is a critical component of the system stack, often representing a significant performance bottleneck that limits on-chain throughput and raises transaction costs. While modern clients like Reth have made substantial strides in performance, their architectures are not primarily optimized for high-performance Layer 1s and Layer 2 roll-ups, which target sub-second finality and massive scalability, require a fundamental rethinking of client design to overcome bottlenecks in transaction execution, state commitment, and expensive I/O.

This paper introduces Gravity Reth, a fork of the Reth execution client engineered for maximum throughput with reasonable CPU/RAM resources. We systematically re-architected some critical components to unleash the full potential of Reth. Our primary contributions are:

1. **Grevm 2.1:** A hybrid parallel EVM that integrates a Data Dependency Directed Acyclic Graph (DAG) with Block-STM-style optimistic execution. This design minimizes redundant computations in high-contention workloads and achieves near-optimal parallelism in low-contention scenarios.
2. **Parallel Merklization:** A complete redesign of the state root calculation process. We replace Reth's sequential, bottom-up MPT generation with a 16-way, top-down parallel framework that delivers a 3-10x performance increase.
3. **Gravity Cache:** A concurrent, LRU-based caching layer built with `DashMap` that provides an efficient "latest view" of the state, drastically reducing I/O pressure and resolving performance degradation associated with managing numerous in-memory blocks in high-frequency environments.
4. **Optimized Memory Pool:** A two-tier data structure and batch processing mechanism for highly concurrent transaction insertion and management.
5. **Pipeline Architecture:** A five-stage asynchronous pipeline (Execution, Merklization, Verification, Commit) that decouples execution stages, allowing Gravity Reth to effectively overlap computation and I/O and fully leverage multi-core processors to service rapid block production from high-throughput consensus engines.

Our evaluation demonstrates that Gravity Reth achieves \~41,000 TPS in a standard ERC20 transfer benchmark, compared to `Reth 1.4.8`'s 9,800 TPS on identical hardware. We believe Gravity Reth represents the fastest open-source EVM execution client to date and offer our architecture and results as a blueprint for future high-performance blockchain systems.

## Architectural Innovations

Gravity Reth's performance gains stem from a holistic redesign of the core components of an EVM client. We detail each major innovation below.

### Grevm: Fastest Parallel EVM

Optimistic parallel execution in blockchain, as popularized by Block-STM, offers significant speedups for low-contention workloads but suffers performance degradation in scenarios with highly dependent transactions due to frequent aborts and re-executions. To address this, we developed [**Grevm**](https://github.com/galxe/grevm), a parallel execution engine that intelligently combines optimistic execution with dependency-based scheduling.

Grevm first asynchronously performs a parallel simulation of a block's transactions based on most recent state, to construct a Data Dependency Directed Acyclic Graph (DAG). Based on this graph, it dynamically schedules non-dependent transactions for parallel execution while grouping strongly-conflicting transactions into **Task Groups**. Transactions in a group are executed sequentially within a single thread, preserving the benefits of parallelism for independent work while minimizing the overhead of re-execution for contentious operations. Furthermore, we developed **Lock-Free DAG** implementation, replaces global locking with fine-grained, node-level synchronization, reducing DAG scheduling overhead by 60% and improving overall throughput by over 30%, with nearly a **2x** gain in workloads dominated by fast-executing transactions (e.g., ERC20 and raw transfers).

This hybrid approach yields significant performance benefits across a wide spectrum of workloads. Key achievements of Grevm 2.1 include:

* **Robustness in High-Contention Scenarios:** In workloads with high dependency, Grevm avoids the 20-30% performance penalty observed in pure optimistic models, maintaining performance near that of sequential execution while using up to **95% less** CPU.
* **Superior Hybrid Workload Throughput:** For mixed workloads with a 30% contention ratio, Grevm delivers a **5.5x** throughput increase over its predecessor, achieving 2.96 Gigagas/s by minimizing re-executions.

A comprehensive analysis of the Grevm 2.1 architecture, including its lock-free DAG design and implementation, parallel state store, and detailed benchmark comparisons, is available in our previous [research report](https://docs.gravity.xyz/research/grevm2).

### Fully Parallel Merklization

Our analysis identified the state root calculation (Merklization) as a primary performance bottleneck in the native Reth. For a block with `6,000` transactions and a state of `100,000` accounts, this process alone could take `380ms`, imposing a theoretical ceiling of `~16,000 TPS` on the entire system, even in an ideal pipeline model. This limitation stems from several core design choices in Reth's Merkle Patricia Trie (MPT) implementation.

Reth’s MPT implementation is designed for storage compactness. It only persists Branch Nodes, dynamically reconstructing Extension Nodes from raw data when needed. While this saves disk space, it incurs significant computational overhead during state access. The primary bottlenecks are:

* **Bottom-up, Cursor-Dependent Construction:** Reth builds the trie from the bottom up, starting from leaf nodes and moving towards the root. This process fundamentally relies on ordered database access via a `cursor` interface. This dependency makes it difficult to leverage simple, high-performance Key-Value (KV) caches, as they cannot guarantee the ordered iteration required by the algorithm.
* **Redundant Node Processing:** The bottom-up traversal often results in accessing and processing numerous unmodified intermediate nodes simply to reconstruct the path to a modified leaf.
* **Limited Parallelism:** While Reth can parallelize Merklization *between* different storage tries, it lacks the ability to do so *within* a single trie. The main Account Trie and the storage trie of a single "hot" contract, which may be the target of thousands of transactions in a block, are both processed serially. This severely limits performance in common, high-contention scenarios.

To overcome these limitations, we re-engineered a new Merklization framework, inspired by the design of Geth.

![Gravity Fully Parallel Merklization Framework](/files/GZY934OZ4PgB0kPrZ8YH)

Our approach systematically addresses each bottleneck:

1. **Top-Down, KV-Based Traversal:** We abandoned the bottom-up approach in favor of a **top-down** search. Our trie structure persists both Branch and Extension nodes, allowing for direct, fast access using a standard KV interface. This eliminates the dependency on slow database cursors and makes the entire process extremely cache-friendly.
2. **Elimination of Redundant Work:** We introduced a logical nested tree structure with a `dirty` flag for each node and cached node hashes. This ensures that only modified nodes and their direct ancestors are ever re-calculated, completely avoiding redundant hashing of unmodified parts of the trie.
3. **Comprehensive Intra-Trie Parallelism:** The most critical innovation is our **16-way parallel strategy**, which unlocks true intra-trie parallelism for both the Account Trie and individual storage tries. The challenge with parallelizing updates to a single trie lies in managing complex structural changes (node expansions/contractions) that can cause race conditions. Our design elegantly bypasses this problem:
   * All pending updates (for accounts or storage slots) are first grouped based on the **first nibble (4 bits) of their trie path**.
   * This partitioning divides the entire set of modifications into 16 independent groups, each affecting a different child node of the trie root.
   * These 16 groups are then processed in parallel, with each thread working on a completely disjoint subtree, thus eliminating any possibility of conflict.
   * After all parallel tasks are complete, the system performs a final, atomic update to combine the new hashes from the 16 child nodes into the final state root.

This architecture is summarized below:

| **Optimization Dimension** | **Reth (Native)** | **Gravity-Reth**         |
| -------------------------- | ----------------- | ------------------------ |
| **Trie Structure**         | Branch Nodes Only | Extension + Branch Nodes |
| **Construction Method**    | Bottom-up         | Top-down                 |
| **Access Pattern**         | Cursor-based Scan | Direct KV Indexing       |
| **Intra-Trie Parallelism** | ❌                 | ✅ (16-way)               |

*Table 1: Gravity Reth Fully Parallel Merklization Comparison*

#### Evaluation

The impact of this new architecture is dramatic. To quantify the gains, we benchmarked the Merklization latency for a fixed block size of 6,000 ERC20 transactions against varying state sizes (number of accounts).

| **Account Scale** | **Reth Merklization** | **Gravity-Reth Merklization** | **Speedup** |
| ----------------- | --------------------- | ----------------------------- | ----------- |
| 10k               | 78ms                  | 25ms                          | 3.1x        |
| 50k               | 237ms                 | 43ms                          | 5.5x        |
| 100k              | 380ms                 | 62ms                          | 6.1x        |
| 500k              | 756ms                 | 108ms                         | 7.0x        |
| 1,000k            | 1180ms                | 143ms                         | 8.3x        |

*Table 2: Gravity Reth Fully Parallel Merklization v.s. Reth Native*

The results demonstrate a **3x to over 8x performance improvement** across all tested scales. The advantage of parallel Merklization becomes more significant as the state size increases, highlighting its scalability for chains with large numbers of accounts. This reduction in latency is critical for overall system throughput; for instance, at the 100k account scale, the decrease from **380ms to 62ms** is essential for enabling the Merklization stage to keep pace with an execution throughput of approximately 1.5 Gigagas/s, ensuring it does not become a bottleneck in our high-performance pipeline.

### Gravity Cache: A High-Performance State Cache

In high-throughput systems, state access I/O can be another primary performance bottleneck. Our analysis revealed two key opportunities:

1. It is feasible to cache most of the state (e.g., 100 million accounts in 10-30GB of RAM) on commodity hardware, and
2. Both execution and merklization show significant data locality, with frequent re-access of hot contract states and upper-level MPT nodes.

Reth's native cache, however, was not designed to leverage them. Its architecture (`in_memory.rs`, `memory_overlay.rs`) is tailored for asynchronous persistence on Ethereum's \~12-second block schedule. On a high-performance chain producing over 5 blocks per second, more than 200 unpersisted blocks can accumulate in memory. To read the latest state, Reth may iterate backward through this entire chain of block deltas, merging and sorting the results. This process causes read latency to degrade linearly, soaring from a few milliseconds to over 50-100ms under load, creating a severe bottleneck.

To solve this, **Gravity Cache** (`cache.rs`) is a new framework built on two principles: providing an instantaneous "latest view" and implementing an intelligent LRU cache to minimize I/O. Architecturally, it functions as a unified, concurrent caching layer directly over the database, not as an overlay of pending blocks.

* **Efficient Latest View:** Implemented with `DashMap`, it provides a high-performance, concurrent cache for key data types (Accounts, Storage, ByteCode, Trie nodes), eliminating the need to traverse pending blocks.
* **Guaranteed Consistency:** Correctness is ensured by a simple but powerful rule. Each cached entry is tagged with its `block_number`. The LRU eviction policy is forbidden from discarding any data whose `block_number` is newer than a global `persist_block_number` marker (which tracks the last block flushed to disk). This elegantly prevents the cache from ever dropping unpersisted state.

![Gravity Reth Cache Arch](/files/HBYyA3ouu7WFxDkFlNed)

#### Evaluation

In our benchmark, for a 5,000-transaction block, a full update to the Gravity Cache takes only **\~10 milliseconds**, while providing a near-instant "latest view." Furthermore, the cache dramatically reduces I/O pressure. In a 100,000-account test, Gravity Reth with the cache enabled performed only **20% slower** than a theoretical pure-in-memory baseline. In contrast, Reth's approach degraded by **over 50%** in the same scenario. These results demonstrate that Gravity Cache is a critical component for achieving stable, high-throughput performance.

### High-Throughput Mempool

We re-architected the mempool in Gravity Reth to solve two critical performance bottlenecks: an inefficient core data structure and high-contention RPC handling under concurrent loads.

**From Global to Per-Account BTreeMap**

Reth's native mempool uses a single, global `BTreeMap<(Address, Nonce), Txn>`. While this ensures nonce ordering, it suffers from three major issues in high-throughput scenarios:

1. **High Global Complexity:** All operations have an O(logN) complexity, where N is the total number of transactions in the mempool. This is inefficient in typical Web3 workloads where the number of pending transactions per account (M) is far smaller than N.
2. **Inefficient Account Traversal:** Retrieving all transactions for a single account requires a costly `range` query over the `BTreeMap`, performing expensive `U256` address comparisons and iterator advancements, all while holding a lock.
3. **Poor Memory Layout:** The `(Address, Nonce)` composite key causes the 20-byte `Address` to be stored repeatedly within the tree's nodes, wasting memory and reducing CPU cache-line utilization.

Our solution replaces this with a two-level structure: **`HashMap<Address, BTreeMap<Nonce, Txn>>`**. This design provides immediate benefits:

* Account lookups are reduced to **O(1)**.
* The logarithmic complexity is confined to the per-account `BTreeMap` (O(logM)), which is near-constant time as M is typically very small.
* The memory layout is optimized, as each address is stored only once as a key in the `HashMap`.

**RPC Handling: Asynchronous Batch Processing**

High-frequency `send_raw_transaction` calls create another bottleneck, causing:

* **Redundant I/O:** Each transaction individually triggers database lookups for validation (nonce, balance), even for the same account.
* **Intense Lock Contention:** Each insertion requires a brief but frequent write lock, leading to severe lock queueing under high concurrency.
* **CPU Overhead:** Frequent locking and unlocking increases thread context switching and hurts CPU cache performance.

To solve this, we implemented an **asynchronous batch processing queue**. This architecture decouples validation from insertion in a producer-consumer pattern.

* **Batched Validation (Producer):** Incoming transactions are grouped by address in a short time window. This allows the system to perform a single database lookup to validate multiple transactions from the same sender.
* **Batched Insertion (Consumer):** A background thread periodically acquires a single write lock to insert an entire batch of validated transactions, dramatically reducing lock contention and amortizing its cost over many transactions.

Because these optimizations are applicable to any EVM ecosystem using Reth, all of these foundational changes have been successfully contributed back to the main Reth repository. The table below summarizes some of these key contributions.

| **Pull Request**                                                                                                   | **Problem Description**                                                             | **Optimization**                                                                    |
| ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| [#16159](https://github.com/paradigmxyz/reth/pull/16159)                                                           | Unnecessary memory allocation (`Box`) inside a frequently called critical section.  | Streamlined the locked section to reduce overhead and contention.                   |
| [#16189](https://github.com/paradigmxyz/reth/pull/16189), [#16408](https://github.com/paradigmxyz/reth/pull/16408) | Transaction validation was purely sequential, even when called in a batch.          | Implemented a true batch interface enabling parallel transaction validation.        |
| [#16407](https://github.com/paradigmxyz/reth/pull/16407)                                                           | Inconsistent state handling in `eth_getTransactionCount` logic.                     | Resolved inconsistencies in transaction count calculation.                          |
| [#17392](https://github.com/paradigmxyz/reth/pull/17392)                                                           | Status queries cloned the entire transaction list, causing long read-lock holds.    | Optimized the query to return only transaction counts, shortening lock hold times.  |
| [#17396](https://github.com/paradigmxyz/reth/pull/17396)                                                           | Pending transactions were not consistently rebroadcast after account state changes. | Corrected the broadcast logic to ensure proper propagation of pending transactions. |
| [#17434](https://github.com/paradigmxyz/reth/pull/17434)                                                           | The global `BTreeMap` caused O(logN) complexity and poor memory layout.             | Replaced with a two-level `HashMap` for O(1) account lookups.                       |

*Table 3: Gravity Reth Mempool Optimization Pull Request List (merged to Reth)*

### Asynchronous Execution Pipeline

In the standard Ethereum Engine API, the execution and consensus layers operate in lockstep; the consensus layer cannot propose a new block until the previous one has been fully executed and verified. Gravity's consensus layer, inspired by AptosBFT, breaks this synchronous model by **decoupling block production from execution**. It sends a continuous, high-frequency stream of ordered blocks to the execution layer, demanding an architecture that can process blocks in parallel.

To meet this demand, we designed a multi-stage asynchronous pipeline. This design is enabled by two core principles:

1. **Decoupling Blockhash from State Root:** The `BLOCKHASH` opcode introduces a cross-stage dependency, coupling the execution stage to the preceding block's Merklization stage, since the block hash requires the `stateRoot`. To decouple these stages, we redefined the `BLOCKHASH` opcode to return a 'block ID' instead of the `stateRoot`-dependent block hash. This block ID is determined entirely by the `Ordered Block`'s contents at the consensus level, removing this pipeline stall.
2. **Pipelined Execution:** With the `blockhash` dependency broken, we can process multiple blocks concurrently. For example, the pipeline can be executing Block `N+1` while computing the state root for Block `N` and committing Block `N-1`. This ensures the system's throughput is bound by the latency of the single slowest stage, not the cumulative time of all stages.

![Gravity Reth Pipeline Simplified](/files/p6MLUq8fmX6ViIe7vfN2)

Our pipeline divides block processing into five distinct stages:

* **Transaction Execution:** Executes all transactions in a block using Grevm. It begins with the state provided by our Gravity Cache and updates the cache in real-time with the results.
* **Merklization:** Computes the `stateRoot` for the current block using the state changes from the Execution stage.
* **Block Verification:** Calculates the `BLOCKHASH` and submits the execution results to the consensus layer for confirmation.
* **Commit:** Once consensus provides confirmation, this stage commits the verified block and its state to the canonical chain.
* **Persistence**: We reuse Reth's existing `EngineApiTreeHandler` for asynchronous, batched persistence to disk.

![Gravity Reth Pipeline Architecture](/files/UwkS1K7VTubrnbhAjh7z)

This pipeline model is not limited to our specific consensus engine. It is highly beneficial for **Layer 2 roll-ups** and other systems where block building is decoupled from execution. The key prerequisite is a persistent, pre-execution ordering of transactions, which can serve as a Write-Ahead Log (WAL) for the execution engine to safely recover from failures.

#### Evaluation

The pipeline architecture's impact is significant, even in isolation from other major optimizations like Grevm and Parallel Merklization. The following table highlights these gains.

**Note:** Both configurations include our mempool optimizations. This was a necessary prerequisite, as the original mempool design was a bottleneck that would have otherwise masked the performance improvements from the pipeline.

| **Version**                    | **TPS** | **Avg. Block Interval** | **Block Size** | **Execution (EVM Time)** | **Merklization** |
| ------------------------------ | ------- | ----------------------- | -------------- | ------------------------ | ---------------- |
| Reth 1.4.8 (Baseline)          | 9.8k    | 0.66s                   | \~6.4k txns    | 140ms (118ms)            | 380ms            |
| **Greth (Pipeline + Mempool)** | **20k** | **0.2s**                | **\~4k txns**  | 95ms (74ms)              | 240ms            |

*Table 4: Gravity Reth Pipeline Performance Comparison*

**Performance Impact of the Pipeline Architecture (100k Accounts, ERC20 Transfers)**

As the data shows, these architectural changes **doubled the system's TPS from 9.8k to 20k** and cut the block time by 69%, from 0.66s to 0.2s. The shorter duration for individual stages like Execution and Merklization reflects the system's new equilibrium: processing smaller blocks at a much higher frequency to achieve greater overall throughput.

## Benchmark & Evaluation

We conducted a systematic performance evaluation of Gravity-Reth against the baseline Reth 1.4.8. This section details the experimental setup, end-to-end performance results, scalability analysis, and the impact of workload complexity.

### Experimental Setup

* **System Environment:** All benchmarks were run in **Solo Mode**, which bypasses consensus and networking to isolate the performance of the execution client itself. The baseline Reth client was also configured in a comparable test mode.
* **Hardware Configuration:**
  * **Instance:** Google Cloud `c4-highcpu-16`
  * **CPU:** 16 vCPUs, 2.3 GHz
  * **Memory:** 32 GB
  * **Disk:** 1 TB SSD (200 MB/s max throughput, 30,000 max IOPS)
* **Benchmark Tool:** We used a custom, high-performance transaction generator, `gravity_bench`, to create sustained transaction loads for two primary workloads:
  * **Reproducibility:** The benchmark suite and instructions are open-source and available at [`https://github.com/Galxe/gravity_bench`](https://github.com/Galxe/gravity_bench)
    * **ERC20 Transfers:** A simple, high-throughput workload.
    * **Uniswap V2 Swaps:** A more complex workload with higher gas costs, execution complexity and different pattern of state contention.

### End-to-End Performance: ERC20 Transfers

This benchmark measures the end-to-end performance improvement on a standard ERC20 transfer workload with a state size of 100,000 accounts.

| Version                       | TPS  | Gigagas/s | Avg. Block Interval | Block Size  | Mempool (Insert) | Execution (EVM) | Merklization |
| ----------------------------- | ---- | --------- | ------------------- | ----------- | ---------------- | --------------- | ------------ |
| Reth 1.4.8 (Baseline)         | 9.8k | \~0.4     | 0.66s               | \~6.4k txns | 55ms             | 140ms (118ms)   | 380ms        |
| Reth: Pipeline & Mempool opt. | 20k  | \~0.8     | 0.2s                | \~4k txns   | 5ms              | 95ms (74ms)     | 240ms        |
| Gravity Reth                  | 41k  | \~1.6     | 0.15s               | \~6.2k txns | 10ms             | 52ms (32ms)     | 62ms         |

*Table 5: Gravity Reth End-to-End Performance Comparison*

We found that:

* The fully-optimized Gravity Reth achieves **41,000 TPS**, a **4.18x improvement** over the baseline Reth.
* The gains are attributable to the entire suite of optimizations. The **pipeline** and **mempool** changes immediately **double** performance. **Grevm** and **parallel merklization** provide the remaining **2x** boost by drastically reducing time spent on execution and merklization, respectively.
* In the baseline, Merklization (380ms) is the clear bottleneck. In the final version, all stages are significantly faster and more balanced, allowing for a much shorter block interval (0.15s).

### Scalability Analysis

We then tested how performance scales as the number of accounts grows, using the same ERC20 transfer workload.

![image.png](/files/G5rKRd0kldhOYy4xDrPC)

| Account Scale | Reth 1.4.8 | Reth: Pipeline & Mempool opt. | Gravity Reth |
| ------------- | ---------- | ----------------------------- | ------------ |
| 10k           | 17k        | 29k                           | 46k          |
| 50k           | 16k        | 25k                           | 42k          |
| 100k          | 9.8k       | 20k                           | 41k          |
| 500k          | 7.5k       | 15k                           | 34k          |
| 1,000k        | 5k         | 10k                           | 33k          |

*Table 6: TPS vs. Account Scale (ERC20 Transfers)*

We found some key observations:

* Gravity Reth's performance advantage grows significantly with state size. At the 1,000,000-account scale, the pipeline provides a foundational 2x boost over the baseline, while Grevm and Parallel Merklization deliver an additional 3.3x improvement, culminating in a total throughput **6.6 times greater** than Reth.
* The performance degradation for Gravity Reth is graceful, indicating that the **Gravity Cache** is highly effective at mitigating I/O latency by servicing requests for hot state from memory.

To understand the cost drivers, we broke down the latency for each component in the fully-optimized Gravity Reth.

| Account Scale | TPS | Throughput (Size × Rate) | Mempool | Execution (EVM) | Merklization |
| ------------- | --- | ------------------------ | ------- | --------------- | ------------ |
| 10k           | 46k | 5.2k txns × 9 blocks/s   | 12.5ms  | 40ms (25ms)     | 25ms         |
| 50k           | 42k | 5.3k txns × 8 blocks/s   | 10.5ms  | 50ms (30ms)     | 43ms         |
| 100k          | 41k | 6.2k txns × 6.6 blocks/s | 10ms    | 55ms (35ms)     | 62ms         |
| 500k          | 34k | 11.3k txns × 3 blocks/s  | 9ms     | 150ms (75ms)    | 210ms        |
| 1,000k        | 33k | 15k txns × 2.2 blocks/s  | 8ms     | 230ms (120ms)   | 350ms        |

*Table 7: Impact of Account Scale on Stage Latency*

![Gravity Reth TPS v.s. Account Scale](/files/YMEymrXaCSbPlpsOU52V)

The data reveals that as the state size grows, the cost of **Merklization scales more steeply than Execution**. Although absolute execution time per block increases, this is because the pipeline produces larger blocks at slower intervals. When normalized, the execution cost per 1k transactions grows by less than 2x from the 10k to 1M account scale, whereas the Merklization cost increases by over 4.8x (normalized). This identifies Merklization as the primary frontier for future optimization.

### Impact of Workload Complexity: Uniswap Swaps

Finally, we compared performance on simple transfers versus more complex Uniswap V2 swaps.

| Metric                   | ERC20 Transfer           | Uniswap V2 Swap          |
| ------------------------ | ------------------------ | ------------------------ |
| TPS                      | 41k                      | 21k                      |
| Gigagas/s                | 1.5                      | 1.9                      |
| Throughput (Size × Rate) | 6.2k txns × 6.6 blocks/s | 5.8k txns × 3.6 blocks/s |
| Execution (EVM)          | 52ms (32ms)              | 135ms (120ms)            |
| Merklization             | 62ms                     | 54ms                     |
| IOPS                     | 11.1k                    | 5.8k                     |

*Table 8: Performance Comparison (ERC20 vs. Uniswap) at 100k Accounts*

While TPS is halved for the more complex Uniswap workload (as expected), the computational throughput, measured in gigagas/s, actually *increases* from 1.5 to 1.9. Most signaficant change is the time spend on execution, and more specifically, Grevm. The total time spend on Grevm raises from 32ms to 120ms. This matches our benchmark result in the Grevm paper. Interestingly, with a lower TPS, pressure on the mempool and I/O decreases, allowing other stages like merklization to proceed slightly faster.

## Conclusion & Future Work

Gravity Reth demonstrates that substantial performance gains are achievable in modern EVM clients through a holistic approach to optimization. By systematically re-architecting parallelism, I/O, state management, and data structures, we have created an execution client that is over four times faster than its baseline and capable of supporting the demanding requirements of next-generation blockchain systems.

Our work is fundamentally open-source. We have already upstreamed all memory pool optimizations to the main Reth repository and intend to continue this collaboration. While architectural changes as significant as our Parallel Merklization and Pipeline frameworks present greater challenges for integration, we are committed to working with the community to share these innovations. The performance data indicates that Merklization, despite our 10x improvement, remains a critical path for achieving even lower finality times, marking it as one of key area for our future research. We present Gravity Reth as both a high-performance tool for builders and a contribution to the collective effort of scaling the EVM.

## Authors

* <https://github.com/AshinGau>
* <https://github.com/ByteYue>
* <https://github.com/keanji-x>
* <https://github.com/Lchangliang>
* <https://github.com/nekomoto911>
* <https://github.com/stumble>


# Grevm 2.1 (Gravity EVM)

Gravity Parallel EVM (Grevm) is a high-performance, parallel EVM runtime.

## **TL;DR – Highlights of Grevm 2.1**

* **Grevm 2.1 achieves near-optimal performance in low-contention scenarios**, matching Block-STM with **11.25 gigagas/s** for Uniswap workloads and outperforming it with **95% less CPU usage** in inherently non-parallelizable cases by **20–30%**, achieving performance close to sequential execution.
* **Breaks Grevm 1.0’s limitations in handling highly dependent transactions**, delivering a **5.5× throughput increase** to **2.96 gigagas/s** in **30%-hot-ratio hybrid workloads** by minimizing re-executions through **DAG-based scheduling** and **Task Groups**.
* **Introduces Parallel State Store**, leveraging **asynchronous execution result bundling** to **overlap and amortize 30-60ms of post-execution overhead within parallel execution**, effectively hiding these costs within execution time. It also seamlessly handles **miner rewards and the self-destruct opcode** without the performance penalties of sequential fallbacks.
* **In-depth analysis of optimistic parallel execution** reveals the **underestimated efficiency of Block-STM** and the strength of **optimistic parallelism**, providing new insights into parallel execution.
* **Lock-Free DAG** (introduced in 2.1) replaces global locking with fine-grained, node-level synchronization. This change reduces DAG scheduling overhead by **60%** and improves overall performance by more than **30%**. In workloads with fast-executing transactions—such as raw and ERC20 transfers—it delivers nearly **2×** higher throughput.

## Abstract

Grevm 2.1 integrates Block-STM with an execution scheduling mechanism based on **Task Groups** and a **Data Dependency Directed Acyclic Graph (DAG)**, derived from simulated transaction execution results. Unlike Block-STM, which schedules tasks solely based on the lowest index, Grevm 2.1 dynamically schedules execution based on the DAG, prioritizing lower-index transactions with no dependencies for parallel execution while grouping strongly dependent transactions into task groups. Within each task group, transactions execute sequentially within the same thread to minimize re-executions, reduce scheduling overhead, and optimize CPU utilization. This design significantly reduces transaction re-executions in high-conflict scenarios and maximizes parallelism by enabling a parallel execution order that mirrors an optimally reordered sequence—without altering the original transaction order.

Our benchmark results demonstrate that, compared to Grevm 1.0, Grevm 2.1 achieves **5.5× higher throughput** for a **30%-hot-ratio hybrid workload** (Uniswap, ERC20, and raw transfers), reaching **2.96 gigagas/s**. Additionally, while Grevm 2.1 matches Block-STM’s performance for low-conflict workloads, it outperforms Block-STM in extreme cases by maintaining the same performance as sequential execution—avoiding the 20–30% slowdown observed in Block-STM—while using **95%** less CPU usage.

From an engineering perspective, Grevm 2.1 introduces **parallel state**, an asynchronous state storage mechanism that bundles final execution results in parallel. This approach elegantly addresses challenges related to miner rewards and the **self-destruct** opcode without compromising correctness or imposing a performance penalty when falling back to sequential execution.

In this report, we first present the design of Grevm 2.1 and its benchmark results. Then, we share rarely discussed data highlighting Block-STM's impressive optimistic execution efficiency, which we discovered during our experiments and which shaped our key design choices.

## Algorithm Design

Grevm 2.1 consists of three core modules: **Dependency Manager (DAG Manager)**, **Execution Scheduler**, and **Parallel State Storage**. It employs a DAG-driven task scheduling mechanism to:

1. Dynamically maintain the data dependency DAG using using a **selective update strategy**.
2. Group adjacent dependent transactions into **task groups**.
3. Execute task groups and the lowest-index transactions with no dependencies (i.e., out-degree of 0).

![Grevm 2.1 Algorithm](/files/XDjQrCfxJmAmUw8Tp7tO)

### Dependency Manager and Execution Scheduler

The **Dependency Manager** tracks and resolves transaction dependencies during parallel execution. Like in Grevm 1.0, transactions are represented in a **Directed Acyclic Graph (DAG)**:

* **Nodes represent transactions**, identified by unique indices. Let $$T\_i$$ be a transaction with index $$i$$.
* **Edges denote dependencies**, where an edge from $$T\_j$$ to $$T\_i$$ exists if $$T\_i$$ writes data that $$T\_j$$ reads, indicating a read-after-write dependency. Notably, $$j$$ is always strictly less than $$i$$.

Before execution, dependencies are inferred using **hints**—speculated read/write sets obtained from static analysis or simulation (executing transactions on the last committed state).

The **Execution Scheduler** manages both transaction **execution** and **validation**, following this workflow:

1. **Parallel Execution**: The scheduler selects and executes transactions with the smallest index from the DAG that have no dependencies (out-degree = 0). For a task group, its index is the smallest among all grouped transactions.
2. **Validation**: After execution, transactions enter a **pending** validation phase. The scheduler checks whether the read set of the smallest-index pending transaction has changed:
   * If unchanged, the transaction moves to the **unconfirmed** state. Consecutive unconfirmed transactions transition into **finality**, starting from the lowest index.
   * If changed, the transaction is marked as a **conflict**, reinserted into the DAG, and its dependencies are updated before re-execution.

When consecutive transactions have dependencies, they are grouped into a **Task Group**, which is scheduled and executed sequentially within the same thread. For example, if $$tx\_2$$ depends on $$tx\_3$$, $$tx\_2$$ must finish before $$tx\_3$$ begins. By executing them sequentially within a thread, **task groups reduce task switching, re-execution, and scheduling overhead**, making them highly effective in **high-conflict workloads** like NFT minting and DeFi transactions.

In the worst-case scenario, where all transactions form a dependency chain, **task group execution remains as efficient as serial execution**. This design **balances optimistic parallelism with efficient CPU utilization**, while maintaining the simplicity of Block-STM's scheduling logic—avoiding excessive complexity that could degrade performance for simple, fast-executing transactions, like ERC20 and raw transfers.

### Selective Dependency DAG Update Strategy

Grevm 2.1 follows a **selective dependency strategy**, adding only the most necessary edges to minimize DAG modifications. Dependencies are added in three scenarios:

1. **Misestimated Reads**: When a transaction reads estimated data that later proves changed, instead of aborting immediately and marking it as dependent, Grevm 2.1 completes execution, analyzes the actual read-write set, and adds **only the most significant dependency**—specifically, the highest-index transaction it depends on.
2. **Reads from Miner or Self-Destructed Accounts**: If a transaction $$T\_j$$ reads from a **miner account** or a **self-destructed account** while the parallel state for $$T\_{j-1}$$ has not yet been committed, instead of linking to all prior transactions, Grevm 2.1 adds only $$T\_{j-1}$$ as a dependency, reducing redundant edges.
3. **Validation Phase Conflicts**: If a transaction's read set changes during validation, Grevm 2.1 recalculates dependencies and adds only the **most recent transaction** as a dependency. Specifically, if $$T\_i$$ detects a conflict with multiple transactions, it finds the one with the **largest index** $$k$$ and adds a dependency edge from $$T\_k$$ to $$T\_i$$.

Efficient dependency removal is also crucial for balancing scheduling speed and minimizing re-executions. Dependencies can be removed at different stages, each with trade-offs:

* **After Execution**: Enables faster scheduling of subsequent transactions but increases the risk of re-execution if dependencies were misestimated.
* **After Validation**: Delays scheduling slightly but reduces unnecessary re-executions.
* **After Finality**: Eliminates all re-execution risks but introduces the longest scheduling delay.

Grevm 2.1 adopts a **hybrid Execution + Finality strategy** to achieve an optimal balance:

* **Pre-execution dependencies** (inferred before execution) are removed immediately after execution to maximize scheduling throughput.
* **Dynamically detected dependencies** (discovered during execution or validation) are removed only after finality to ensure correctness and minimize re-execution.

This strategy ensures efficient scheduling when dependency hints are accurate while mitigating re-execution overhead when hints are unreliable. Empirical results demonstrate that this hybrid approach effectively balances execution throughput and re-execution probability, delivering robust performance across diverse workload conditions.

### Parallel State Storage

![Parallel State Storage](/files/qBiG0mkWGxaqiXVBOMjD)

The **Storage** module implements **DatabaseRef** and provides two key functionalities: **Parallel State** and **Multi-Version Memory (MvMemory)**. It introduces a **Parallel State** layer between EvmDB and MvMemory to enhance performance.

After transaction $$T\_i$$ completes execution, its results are stored in **MvMemory**. Once it reaches the **Finality** state, an asynchronous task commits the results to **Parallel State**. When transaction $$T\_j$$ accesses data, it reads from **Parallel State** if dealing with a miner or self-destructed account; otherwise, it retrieves data from **MvMemory**.

This design offers several advantages:

* **Amortized Result State Building**: Transactions continuously generate Reth-compatible result states, eliminating the **\~30ms latency** of bundling them after full block execution.
* **Efficient State Management**: Since Parallel State implements all [EVM State](https://github.com/bluealloy/revm/blob/main/crates/database/src/states/state.rs) interfaces, transactions can retrieve the latest miner or self-destructed account state without relying entirely on MvMemory.

In cases where a transaction executes **self-destruct**, conflicts arise if later transactions attempt to access that account. The self-destruct operation updates MvMemory's write set and marks the account as **self-destructed**. If a subsequent transaction retrieves self-destructed account data from MvMemory, it must re-fetch the latest state from Parallel State.

Parallel State's **commit ID** serves as a version number, ensuring that for transaction $$j$$, only data from version $$j-1$$ is valid—otherwise, the transaction is marked as conflicting.

### Lock-Free DAG (New in Grevm 2.1)

Grevm 2.0 initially used a global lock to maintain correctness during DAG updates and scheduling. However, benchmark results ([Issue 64](https://github.com/Galxe/grevm/issues/64)) showed that even with a minimized critical section, this approach led to over 40% performance degradation.

Grevm 2.1 replaces this with a fully lock-free DAG design, featuring two key improvements:

* **Fine-Grained Node Locking**: Rather than locking the entire DAG, updates now lock only the involved nodes. For example, when adding a dependency like $$tx\_j \rightarrow tx\_i$$, only $$tx\_j$$ and $$tx\_i$$ are locked.
* **Atomic Scheduler Cursor**: Inspired by Block-STM, the scheduler uses an atomic `execution_idx` cursor to poll for dependency-free nodes. When $$tx\_i$$ completes, it clears $$tx\_j$$'s dependency and updates the cursor via `execution_idx.fetch_min(j)`. Unlike Block-STM, Grevm cannot rely solely on comparing `validation_idx` and `execution_idx` to schedule validation, since execution order may diverge from transaction order (e.g., if $$tx\_0$$ and $$tx\_2$$ execute before $$tx\_1$$, validating $$tx\_2$$ is pointless before $$tx\_1$$ completes). To handle this, Grevm introduces the `ContinuousDetectSet` module, detecting contiguous executed spans, using some unchecked code for performance.

For **asynchronous commits** (`StateAsyncCommit`), Grevm addresses edge cases such as: $$tx\_2$$ and $$tx\_4$$ remain unconfirmed while $$tx\_3$$—dependent on $$tx\_2$$—triggers a rollback to `validation_idx = 3`. Under concurrency, if $$tx\_3$$ re-enters the unconfirmed state before $$tx\_4$$ validates, $$tx\_4$$ may commit incorrectly. Locks could prevent this but would reintroduce performance bottlenecks. Instead, Grevm uses a **Logical Timestamp Check**: when rolling back to $$tx\_i$$, it increments `logical_ts` via `fetch_add(1)`. This ensures that any $$tx\_n$$ ($$n \geq i$$) still in the unconfirmed state will observe a timestamp newer than the rollback, preventing stale commits.

## Benchmark

We evaluate the Grevm 2.1 implementation with the same setup as 1.0:

* aws c7g.8xlarge 32 vCPUs @2.6 GHz
* Ubuntu 22.04.5 LTS
* cargo 1.81.0 (2dbb1af80 2024-08-20)
* Grevm git commit hash: `15f7134cc434fbd9da63b96b3b23d3f77f9b8fc6`
* pevm git commit hash: `d48fae90b6ad36ddc5d613ee28ad23214353e81e`
* Benchmark code: <https://github.com/Galxe/grevm/blob/main/benches/gigagas.rs>

To reproduce the benchmark, run

```bash
JEMALLOC_SYS_WITH_MALLOC_CONF="thp:always,metadata_thp:always" NUM_EOA=${NUM_EOA} HOT_RATIO=${HOT_RATIO} DB_LATENCY_US=${DB_LATENCY_US} cargo bench --bench gigagas
```

Replace `${NUM_EOA}`, `${HOT_RATIO}`, and `${DB_LATENCY_US}` with the desired parameters:

* `NUM_EOA`: Number of accounts.
* `HOT_RATIO`: Ratio of transactions accessing common ("hot") account.
* `DB_LATENCY_US`: Simulated database latency in microseconds.

### Gigagas Block Test

We conducted the same gigagas block test as 1.0, a benchmark designed to evaluate the efficiency of parallel execution under varying workloads and conditions. Each mock block contains transactions totaling **1 gigagas** in gas consumption. The transactions include vanilla Ether transfers, ERC20 token transfers, and Uniswap swaps. Pre-state data is stored entirely in-memory to isolate execution performance from disk I/O variability. To mimic real-world conditions where disk I/O latency can impact performance, we introduced artificial latency using the `db_latency` parameter.

### Conflict-Free Transactions

We first evaluated our implementation using conflict-free workloads to measure optimal performance. In this scenario, transactions consist of independent raw transfers, ERC20 transfers, and Uniswap swaps, each involving separate contracts and accounts to ensure no data dependencies. This setup provides a baseline to assess the maximum achievable performance improvement through parallel execution without the impact of transaction conflicts.

| Test            | Num Txs | DB Latency | Sequential | Grevm 1.0 | Grevm 2.1 | Speedup | Gigagas/s |
| --------------- | ------- | ---------- | ---------- | --------- | --------- | ------- | --------- |
| Raw Transfers   | 47620   | 0          | 185.74     | 69.172    | 66.17     | 2.81    | 15.11     |
|                 |         | 20us       | 3703.5     | N/A       | 95.66     | 38.72   | 10.45     |
|                 |         | 40us       | 4654.0     | N/A       | 108.79    | 42.78   | 9.19      |
|                 |         | 60us       | 5612.0     | N/A       | 122.96    | 45.64   | 8.13      |
|                 |         | 80us       | 6560.6     | N/A       | 138.95    | 47.22   | 7.20      |
|                 |         | 100us      | 7511.1     | 179.03    | 155.34    | 48.35   | 6.44      |
| ERC20 Transfers | 33628   | 0          | 329.55     | 96.559    | 65.19     | 5.06    | 15.34     |
|                 |         | 20us       | 5297.6     | N/A       | 120.34    | 44.02   | 8.31      |
|                 |         | 40us       | 6643.3     | N/A       | 138.40    | 48.00   | 7.23      |
|                 |         | 60us       | 7992.8     | N/A       | 158.81    | 50.33   | 6.30      |
|                 |         | 80us       | 9335.1     | N/A       | 182.73    | 51.09   | 5.47      |
|                 |         | 100us      | 10681      | 243.27    | 205.48    | 51.98   | 4.87      |
| Uniswap Swaps   | 6413    | 0          | 771.83     | 108.2     | 88.89     | 8.68    | 11.25     |
|                 |         | 20us       | 12188      | N/A       | 238.91    | 51.02   | 4.19      |
|                 |         | 40us       | 15261      | N/A       | 285.36    | 53.48   | 3.50      |
|                 |         | 60us       | 18378      | N/A       | 336.01    | 54.69   | 2.98      |
|                 |         | 80us       | 21433      | N/A       | 387.18    | 55.36   | 2.58      |
|                 |         | 100us      | 24530      | 439.89    | 439.35    | 55.83   | 2.28      |

*Table 1: Grevm 2.1 Conflict-Free Transaction Execution Speedup (uint = milliseconds)*

Compared to Grevm 1.0, Grevm 2.1 does not achieve the same level of speedup when transaction complexity is low. This is expected, as DAG-based scheduling incurs higher overhead than 1.0’s partitioning algorithm. However, as transaction complexity increases, Grevm 2.0’s performance matches and slightly surpasses 1.0. For instance, in the Uniswap swap test with 100µs access latency, Grevm 2.1 achieves a **60.8× speedup**, compared to 1.0’s **58.06×**. Even in cases where 2.0 is less efficient than 1.0—such as raw and ERC20 transfers—its throughput still significantly exceeds **1 gigagas/s**, making this trade-off well-suited for production workloads.

Like Grevm 1.0, Grevm 2.1 benefits from **asynchronous I/O**, enabled by parallel execution, further amplifying its performance advantage over sequential execution.

Additionally, with **parallel state storage**, all tests now include overheads that were excluded in 1.0, such as state bundling. This explains why the Grevm 1.0 benchmark results referenced here are **end-to-end execution time**, as reported in Table 3 of the original paper.

Compared to Grevm 2.0, the new lock-free scheduler in Grevm 2.1 significantly improves overall performance, especially for simple and fast transactions like ERC20 and raw transfers, where we observed nearly **2×** higher throughput. For more complex transactions such as Uniswap swaps, performance drops by 32%. However, since the achieved throughput already surpasses our target of 1 Gigagas/s—reaching 11.25 Gigagas/s—we believe this is a worthwhile trade-off.

| Test            | Num Txs | DB Latency | Sequential | Grevm 2.0 | Grevm 2.1 | Speedup |
| --------------- | ------- | ---------- | ---------- | --------- | --------- | ------- |
| Raw Transfers   | 47620   | 0          | 185.74     | 123.01    | 66.17     | 1.85    |
|                 |         | 100us      | 7511.1     | 152.96    | 155.34    | 0.98    |
| ERC20 Transfers | 33628   | 0          | 329.55     | 105.51    | 65.19     | 1.61    |
|                 |         | 100us      | 10681      | 205.30    | 205.48    | 0.99    |
| Uniswap Swaps   | 6413    | 0          | 771.83     | 60.36     | 88.89     | 0.68    |
|                 |         | 100us      | 24530      | 403.18    | 439.35    | 0.91    |

*Table 2: Grevm 2.0 v.s. Grevm 2.1 (uint = milliseconds)*

### Contention Transactions

We uses the same setup for contention transactions as 1.0, with a **hot ratio** parameter to simulate contention in transaction workloads. This parameter allows us to model skewed access patterns, where certain accounts or contracts are accessed more frequently than others.

* **Number of User Accounts**: **100,000** accounts used in the test.
* **Hot Ratio**: Defines the probability that a transaction will access one of the hot accounts.
  * **Hot Ratio = 0%**: Simulates a uniform workload where each read/write accesses random accounts.
  * **Hot Ratio > 0%**: Simulates a skewed workload by designating 10% of the total accounts as **hot accounts**. Each read/write operation has a probability equal to the hot ratio of accessing a hot account.

We also introduced a a test set called **Hybrid**, consisting of

* **60% Native Transfers**: Simple Ether transfers between accounts.
* **20% ERC20 Transfers**: Token transfers within three ERC20 token contracts.
* **20% Uniswap Swaps**: Swap transactions within two independent Uniswap pairs.

| Test            | Num Txs | Total Gas     |
| --------------- | ------- | ------------- |
| Raw Transfers   | 47,620  | 1,000,020,000 |
| ERC20 Transfers | 33,628  | 1,161,842,024 |
| Hybrid          | 36,580  | 1,002,841,727 |

*Table 3: Contention Transactions Execution Test Setup*

In Grevm 1.0, the performance of high-contention transactions was constrained by their high interdependence. Grevm 2.1 significantly improves performance in high-conflict scenarios. With a **30% hot ratio**, Grevm 2.1 outperforms 1.0 in all test cases except for ERC20 transfers with zero latency, where experimental variance is a factor. The most notable improvement is in the **Hybrid test case**, where Grevm 2.1 achieves a **29× speedup over sequential execution**, which is **5.55× over Grevm 1.0**, reaching a throughput of **2.96 gigagas/s**.

| Test            | Num Txs | DB Latency | Sequential | Grevm 1.0 | Grevm 2.1 | Total Speedup | ThroughPut(Gigagas/s) |
| --------------- | ------- | ---------- | ---------- | --------- | --------- | ------------- | --------------------- |
| Raw Transfers   | 47620   | 0          | 228.03     | 171.65    | 85.54     | 2.67          | 11.69                 |
|                 |         | 100us      | 8933.0     | 4328.08   | 183.14    | 48.78         | 5.46                  |
| ERC20 Transfers | 33628   | 0          | 366.76     | 92.07     | 88.89     | 4.13          | 11.25                 |
|                 |         | 100us      | 11526      | 438.03    | 226.48    | 50.89         | 4.42                  |
| Hybrid          | 36580   | 0          | 333.66     | 220.14    | 235.33    | 1.42          | 4.25                  |
|                 |         | 100us      | 9799.9     | 1874.7    | 344.88    | 28.42         | 2.90                  |

*Table 4: Grevm 2.1 Contention Transactions Execution Speedup (unit = milliseconds, hot ratio = 30%)*

### Non-Parallelizable Transactions

To compare the performance of Grevm 2.1 and Block-STM in inherently non-parallelizable cases, we conducted a test with transactions that are highly dependent on each other. In this scenario, transactions form a chain where each transaction depends on the previous one, making parallel execution impossible. All tests are running with `db_latency = 0`. Same as Grevm 1.0, we use pevm as the reference implementation for Block-STM.

| Test                  | Num Txs | Sequential | Parallel | Speedup | Gigagas/s | CPU Usage |
| --------------------- | ------- | ---------- | -------- | ------- | --------- | --------- |
| Worst ERC20 Transfers | 33,628  | 350.32     | 369.96   | 0.95    | 2.70      | 128%      |
| Worst Uniswap         | 6,414   | 550.19     | 567.32   | 0.97    | 1.76      | 115%      |

*Table 5: Grevm 2.1 Non-Parallelizable Transactions Test (unit = milliseconds)*

In these tests, Grevm 2.1 experiences only a **5% performance degradation** for ERC20 transfers and **3%** for Uniswap swaps compared to sequential execution. This result is a significant improvement over Block-STM, which suffers a **\~30% slowdown** in similar scenarios in our benchmark (see Table 5), aligning with the worst-case benchmark results reported in the Block-STM paper.

A more impressive result is the **CPU usage**, sampled using `pidstat`. Grevm 2.1 uses only **128% CPU for ERC20 transfers** and **115% CPU for Uniswap swaps**, whereas Block-STM consumes **2987% and 2761% CPU**, respectively. This represents a **95% reduction in CPU usage** compared to Block-STM. These findings highlight Grevm 2.1's efficiency in handling inherently non-parallelizable transactions, enhancing the execution engine's resilience against worst-case transaction dependencies.

| Test          | Num Txs | Sequential Total | Grevm Parallel | Speedup | Gigagas/s | CPU Usage |
| ------------- | ------- | ---------------- | -------------- | ------- | --------- | --------- |
| Worst ERC20   | 33,628  | 292.45           | 423.45         | 0.69    | 2.36      | 2987%     |
| Worst Uniswap | 6,414   | 488.12           | 687.13         | 0.71    | 1.46      | 2761%     |

*Table 6: Block-STM (pevm implementation) Non-Parallelizable Transactions Test (unit = milliseconds)*

## Comparison, Analysis, and Future Work

### Optimistic Parallelism (Block-STM) Is MORE Efficient Than Expected

In parallel block execution, the dependencies between transactions play a crucial role in system performance. To quantify this impact, we introduce two key metrics: **Dependency Distance** and **Dependent Ratio**. If a transaction $$T\_j$$ depends on a preceding transaction $$T\_i$$, their dependency distance is defined as:

$$
\text{dependency\_distance} = j - i
$$

where $$j$$ and $$i$$ are the transaction indices. The number of transactions within a block that have dependencies is denoted as `with_dependent_txs`, and the dependent ratio is given by:

$$
\text{dependent\_ratio} = \frac{\text{with\_dependent\_txs}}{\text{block\_txs}}
$$

where **block\_txs** represents the total number of transactions in the block. The following figure illustrates the relationship between conflict rate and dependency distance under **fully optimistic execution**, based on a **1 Gigagas** block containing **47,620** normal transfer transactions:

![Dependency Distance v.s. Conflict Ratio](/files/3O2VmICaadVDqIzu3uGx)

The analysis reveals that even when **dependency\_distance = 1**, later transactions still have a certain probability of reading the correct data from earlier ones. When **dependency\_distance ≥ 4**, conflict rates drop significantly, showing an approximately inverse relationship with dependency distance.

This insight is highly practical: even in blocks with a high number of interdependent transactions, optimistic execution strategies (such as **Block-STM**) do not necessarily lead to excessive transaction re-execution. This is because transactions with greater dependency distances are less likely to conflict, minimizing performance degradation caused by re-executions. Moreover, when simple transactions—such as raw transfers and ERC20 transfers—are executed quickly, later transactions are more likely to read correct data from earlier ones. This happens because earlier transactions may have already completed execution, even when later transactions are running in parallel. Furthermore, if transaction reordering is an option, interleaving transactions with gapped dependencies can significantly improve optimistic parallelism by minimizing conflicts caused by short dependency distances.

This principle provides us the theoretical foundation for optimizing parallel execution engines, enabling maximum performance while ensuring correctness. For transactions with **short dependency distances (dependency\_distance ≤ 3)**, a more conservative scheduling strategy (e.g., **Task Group**) can help reduce conflicts. Meanwhile, transactions with **larger dependency distances** can be processed using fully optimistic execution to maximize parallelism and throughput.

### Implications of Dependency Distance on DAG Scheduling

When `dependency_distance` is large enough, hints and the dependency DAG play a less critical role, as transactions can be optimistically executed in parallel with minimal risk of re-execution. However, when it is small (e.g., $$≤ 3$$), the likelihood of conflicts increases, leading to frequent re-execution of affected transactions. Without dynamic dependency updates, some conflicting transactions may require over 10 execution attempts before confirmation. Introducing dynamic updates to the dependency DAG can significantly reduce the number of retries:

* **Execution-phase updates**: Lowers retries to about 5.
* **Validation-phase updates**: Further reduces retries to around 3.
* **Finality-phase updates**: Limits retries to at most 2.

Both dependency updates and transaction re-executions introduce overhead, requiring a balance where `dependency_distance` serves as the primary optimization metric.

In high-conflict scenarios, hints accuracy becomes particularly important. When hints are reliable, even execution-phase dependency removals can prevent conflicts, enabling faster scheduling. Conversely, inaccurate hints lead to frequent dependency DAG updates, degrading performance.

Task Group mechanism also mitigates reliance on hints accuracy. To ensure less-conflict execution even when hints are inaccurate, only transactions with `dependency_distance = 1` are grouped into task groups, preserving sequential execution and minimizing performance loss.

Overall, Grevm 2.1 offers no major advantage over Block-STM in low-conflict scenarios. However, in high-conflict environments, Grevm 2.1 significantly reduces retries (lowering CPU consumption) and optimizes execution based on `dependency_distance` when hints are reliable.

### Validation Scheduling

In Grevm 2.1, validation scheduling is slower than in Block-STM for two key reasons.

The first is straightforward: Grevm 2.1 does not execute transactions strictly in index order, whereas validation must proceed sequentially. As a result, validation often stalls, waiting for earlier transactions to complete before it can proceed, causing scheduling delays.

The second reason stems from an often-overlooked Block-STM optimization for validation. Block-STM introduces a `write_new_locations` flag for each transaction, indicating whether transactions have written to a new memory location. If a transaction encounters a conflict, `validation_idx` advances immediately to `tx + 1`, meaning validation does not need to wait for the conflicting transaction to be re-executed. After re-execution, if `write_new_locations = false`, only a single validation task is required, and `validation_idx` remains unchanged. It only advances when `write_new_locations = true`. Since this flag is rarely `true` after a retry, Block-STM efficiently accelerates validation by avoiding unnecessary re-validations for non-conflicting transactions.

Since validation is a prerequisite for finality, and features like remove dynamic dependency, async-commit, miner, and self-destruct all depend on finality, optimizing Grevm 2.0’s validation speed is critical.

A simple approach would be to validate transactions immediately after execution, following Block-STM’s strategy of checking the `write_set` of earlier transactions. However, this method also requires scanning the `read_set` of later transactions, which is computationally expensive. Checking the `write_set` of earlier transactions involves verifying only the latest written location, whereas checking the `read_set` of later transactions requires scanning all subsequent transactions to confirm they accessed the correct data—an inefficient process.

A more effective solution is to validate a transaction’s `write_set` and, if its modifications exceed the predicted range of hints, handle those out-of-range transactions using the standard validation process. However, for transactions within the hints range, their read/write sets do not require validation. Thus, optimizing Grevm 2.0’s validation speed relies heavily on hints accuracy. By dynamically refining hints and improving the validation mechanism, the system can significantly enhance performance while maintaining correctness.

### Future Work

Based on the above analysis, we propose several directions for future research:

1. **More efficient dependency DAG management.** Our findings indicate that using a single lock—whether Rust’s standard locks or a high-performance implementation like `parking_lot`—can reduce scheduler and overall performance by **10-20% (\~20ms, depending on transaction count and execution time).**, comparing with Block-STM's neat atomic index counter, To address this, we plan to investigate lock-free data structures to enhance the DAG manager’s efficiency.
2. **Optimizing validation.** Inspired by Block-STM’s `write_new_locations` flag, we aim to develop more efficient validation algorithms using sophisticated, high-performance data structures to minimize unnecessary re-validations.
3. **Empirical hints accuracy analysis.** We plan to conduct a comprehensive study on hints accuracy to determine the optimal balance between hints-based scheduling and dynamic dependency updates, based on real-world data from EVM blockchains like Ethereum, BNB chain, and Base.

## Authors

* <https://github.com/AshinGau>
* <https://github.com/nekomoto911>
* <https://github.com/stumble>


# Native Oracle

Cross-chain data has always been the soft spot of L1 design. Whether it's an asset bridge, a price feed, or any other piece of off-chain truth, the data has to enter the chain *somewhere* — and where that "somewhere" lives determines who you have to trust.

Most chains push that responsibility outside their consensus. An external oracle network signs the data, or a separate committee of bridge signers attests to deposits. The chain itself stays clean, but a new trust assumption is bolted on the side. If that side-channel breaks, the chain keeps running — but the data is wrong.

Gravity L1 collapses this. The same validators that produce blocks under AptosBFT also observe external data, vote on it, and write it to L1. There is no external oracle network. No multisig committee. The bridge isn't a separate service; it's a contract that receives data **already committed by the validator set**.

This is what "native" means in **Native Oracle**: the validator-attestation pipeline is part of the chain's state machine, not a service running next to it. The security of any data that lands on Native Oracle is the security of the chain itself — same validator set, same BFT thresholds, same finality window.

This post walks through the primitive, the one application built on it today (the Ethereum → Gravity L1 asset bridge), and the design space it opens up.

***

## The Core Abstraction

Native Oracle is a single contract deployed at a fixed system address on Gravity L1:

```
NativeOracle  →  0x00000000000000000000000000000001625F4000
```

It exposes one core operation, callable only by `SYSTEM_CALLER` — a privileged consensus-time identity, *not* a normal account:

```solidity
function record(
    uint32  sourceType,        // 0 = BLOCKCHAIN; more reserved
    uint256 sourceId,          // e.g. chain ID
    uint128 nonce,             // must equal currentNonce + 1
    uint256 blockNumber,       // source-side provenance
    bytes   payload,           // opaque blob
    uint256 callbackGasLimit
) external;
```

A `recordBatch(...)` variant exists for delivering multiple events from the same source in one transaction.

Three design choices are worth pulling out:

**1. Replay protection is centralized.** Native Oracle enforces `nonce == currentNonce + 1` per `(sourceType, sourceId)` — strictly sequential, no gaps. An old message can never be replayed because the contract has already moved past its nonce. Application-level handlers don't need to maintain their own seen-nonce maps; in fact, the bridge receiver explicitly drops that work and leaves only a `__deprecated_processedNonces` storage slot for layout compatibility.

**2. Callbacks are routed, not pulled.** Each `(sourceType, sourceId)` pair can register a callback contract. When data is recorded, Native Oracle calls `onOracleEvent(...)` on the registered handler with a caller-specified gas limit. Resolution is two-layer: a default handler per source type, optionally overridden by a specialized handler for a specific `sourceId`. Governance manages the registry.

**3. Callbacks are fail-safe.** The handler returns `shouldStore: bool` — a handler that has fully consumed the payload (applied it to its own state) can return `false` to skip persistence and save gas. If the handler reverts or runs out of gas, Native Oracle catches it, emits `CallbackFailed(reason)`, and stores the payload anyway. The recording succeeds regardless. The data is committed by consensus; the application logic is best-effort.

The result is a clean separation: **Native Oracle is responsible for&#x20;*****truth*** (consensus-attested, replay-safe), **and the application contract is responsible for&#x20;*****meaning*** (decoding and acting on the payload).

***

## The Consensus Layer

Each Gravity validator runs an oracle observer alongside its block-production duties. For every registered task, the observer:

1. Polls the source endpoint (today, an Ethereum RPC) for the relevant events.
2. Restricts itself to **finalized** state — only events past Ethereum finality are eligible, eliminating reorg surprises.
3. Tracks a cursor (last scanned block) and a last-processed nonce, persisted to disk for fast restart.
4. Emits its observed batch into the consensus layer.

These observations then flow through the *same* AptosBFT machinery that orders normal transactions. Validators sign their observations; a quorum certificate forms; the agreed batch is committed in-line with regular block production. **There is no separate consensus instance, no separate signer set, no separate liveness assumption.**

When the batch is committed, the system call `NativeOracle.recordBatch(...)` is constructed and dispatched as a SYSTEM\_CALLER transaction, landing the data on L1 in the same block-execution flow as everything else.

This is what gives the bridge its security guarantee: **a deposit is finalized on Gravity when ⅔+ of validators have attested to its Ethereum finalization**, enforced by the same BFT thresholds the network uses to produce blocks. There is no separate bridge to compromise.

***

## End-to-End Today: ETH → Gravity Asset Bridge

The first application wired end-to-end through Native Oracle is the G token bridge: lock G on Ethereum, receive native G on Gravity. Here's the full path.

![Native Oracle at launch: Ethereum → Gravity L1 asset bridge via validator attestation](/files/V1uipnnxGHHXRzA9f5GH)

### Step 1 — Ethereum side

The user calls `GBridgeSender.bridgeToGravity(amount, recipient)` (or `bridgeToGravityWithPermit(...)` for gasless approval). The sender:

* Escrows `amount` G tokens (ERC-20) in itself.
* Calls `GravityPortal.send(abi.encode(amount, recipient))` with an ETH fee.

`GravityPortal.send` uses a compact 36-byte header format:

```
payload = sender (20 bytes) || nonce (16 bytes) || message
```

This trims the typical 128+ bytes of `abi.encode` overhead down to 36, charged as:

```
fee = baseFee + (36 + message.length) * feePerByte   // wei, paid in ETH
```

The portal rejects both under- and over-payment (`InsufficientFee` / `ExcessiveFee`) to keep fees deterministic. It then assigns a monotonic `uint128` nonce and emits:

```solidity
event MessageSent(
    uint128 indexed nonce,
    uint256 indexed block_number,
    bytes payload
);
```

### Step 2 — Validator observation & attestation

Every Gravity validator's observer polls Ethereum for `MessageSent` events, filtered on the GravityPortal address, between its cursor and the latest finalized block. New events with `nonce > last_processed_nonce` are accepted and emitted into AptosBFT.

The BFT layer reaches agreement on the observed batch in the same finality window as normal transactions. There's no delayed settlement — the validators that order blocks also order observations.

### Step 3 — On-chain commit

The agreed batch becomes a `SYSTEM_CALLER` transaction calling:

```solidity
nativeOracle.recordBatch(
    /* sourceType        */ 0,                  // BLOCKCHAIN
    /* sourceId          */ 1,                  // Ethereum mainnet
    /* nonces            */ [...],              // strictly sequential
    /* blockNumbers      */ [...],              // provenance from MessageSent
    /* payloads          */ [...],              // raw PortalMessage bytes
    /* callbackGasLimits */ [...]
);
```

Native Oracle enforces `nonces[i] == currentNonce + 1` for each entry, reverting `NonceNotSequential(...)` on any gap or duplicate. For each accepted record, it resolves the callback — `(sourceType=0, sourceId=1) → GBridgeReceiver` — and invokes it.

### Step 4 — Callback & native mint

`GBridgeReceiver` extends `BlockchainEventHandler` and implements `IOracleCallback`. On invocation it:

1. Decodes the PortalMessage: `(sender, messageNonce, message) = decode(payload)`.
2. Verifies `sourceId == trustedSourceId` (Ethereum mainnet) — rejects with `InvalidSourceChain(...)` otherwise.
3. Verifies `sender == trustedBridge` (the deployed `GBridgeSender`) — defense in depth.
4. Decodes the application message: `(amount, recipient) = abi.decode(message, (uint256, address))`.
5. Calls the native mint precompile:

```
NativeMintPrecompile  →  0x00000000000000000000000000000001625F5000
```

The precompile mints native G tokens directly to the recipient — **no wrapper, no synthetic asset.** The user holds the L1's native gas asset, just as if it had been minted at genesis.

Total trip from `bridgeToGravity` call to native G in the recipient's address: one Ethereum-finality window plus one Gravity finality window. No external relayer, no wrapped representation, no separate signer set.

***

## Reliability & Recovery

A few mechanics that matter for operators and integrators:

* **Finalized-only polling.** Observers only ingest events past Ethereum finality. Reorgs on the source chain cannot land on Native Oracle — by definition, they cannot land on a finalized block.
* **Persisted cursors.** Each observer writes `(cursor_block, last_processed_nonce)` to disk per source. After a crash or restart, the observer resumes from its checkpoint instead of rescanning from genesis.
* **On-chain reconciliation.** On startup, the observer reads `NativeOracle.getLatestNonce(sourceType, sourceId)`. If the on-chain nonce is ahead of the local checkpoint (e.g., the validator was offline while peers committed), the observer fast-forwards both cursor and last-processed state. No duplicate delivery, no missed events.
* **Exactly-once delivery, structurally.** Combining (a) sequential nonces in the contract, (b) strictly monotonic filtering in the observer, and (c) finalized-only polling: each `MessageSent` event maps to at most one `record(...)` call across the whole network. There is no per-handler dedup logic to get wrong.
* **Fail-safe callback semantics.** A bug in the callback contract — revert, out-of-gas, wrong logic — does not block the oracle. The record is committed, `CallbackFailed(reason)` is emitted, and operators can patch the handler (via governance-managed callback registration) without losing data.

***

## Live Contract Map

| Chain      | Contract               | Address                                               |
| ---------- | ---------------------- | ----------------------------------------------------- |
| Ethereum   | `GravityPortal`        | `0x76cf8526Fa9461e50B2c6702a7246ce6915f6E53`          |
| Ethereum   | `GBridgeSender`        | `0xE82c61Ac9Ec2041b493118051afa4F18a55dC876`          |
| Ethereum   | `G` (ERC-20)           | `0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649`          |
| Gravity L1 | `NativeOracle`         | `0x00000000000000000000000000000001625F4000` (system) |
| Gravity L1 | `NativeMintPrecompile` | `0x00000000000000000000000000000001625F5000` (system) |

Source addresses for the system precompiles are fixed; ABIs are available in the [gravity\_chain\_core\_contracts](https://github.com/Galxe/gravity_chain_core_contracts) repository.

***

## Beyond the Bridge: What the Primitive Enables

![Native Oracle as a primitive: asset bridge, perp DEX oracle, payments / x402, on-chain AI agent, and generic messaging — five application lanes around one consensus-attested core](/files/9K9NeGFYH3FN9szCGSlR)

Native Oracle isn't *the* bridge — the bridge is the first application built on Native Oracle. The primitive itself is just `(sourceType, sourceId, nonce, payload, callback)`; everything above that line is policy. The substrate that today routes Ethereum deposits to a mint precompile can route any externally attested event to any callback governance approves. The primitive doesn't change; only the tuples registered on top of it do.

To make that concrete, here are application shapes the primitive supports **by design**, not by deployment. Each is a different `(sourceType, sourceId, callback)` registration:

**Asset bridges (today).** Validators observe `MessageSent` events on Ethereum; the callback decodes `(amount, recipient)` and mints native G. More chains under `sourceType = 0` are a governance registration, not a code change. Bidirectional flow — burn on Gravity, release on Ethereum — is the symmetric callback on the same primitive.

**Perp DEX oracles.** Mark price, index price, and funding-rate updates require fresh, consensus-attested data — exactly what most perp DEXes today pay an external oracle network for. A registered price-feed source, observed by validators and routed to the perp protocol's callback, removes that external dependency. Liquidations execute against prices the chain itself agreed to, not prices a side network signed.

**Payments and x402.** The bridge is one shape of payment; payments in general are another. A payer authorizes on chain A, validators attest it on Gravity, a callback credits the payee — same primitive, different decoder. HTTP-402-style pay-per-call services can use this to verify "the client paid X on chain Y" inside the same finality window that serves the request: no off-chain receipt, no trusted indexer.

**On-chain AI agents.** Agents acting on-chain need verifiable inputs they can react to — prices, balances on other chains, the result of off-chain computation they didn't perform themselves. Native Oracle is the substrate they read from. An agent does not have to trust an oracle network the chain itself doesn't trust; whatever the chain sees, the agent sees, in the same finality window.

**Arbitrary application messaging.** The PortalMessage format already carries an opaque `message` field. Fungible-token transfer is the first decoder; arbitrary cross-chain calls are a small step from there.

The connective thread: every one of these uses the same `(sourceType, sourceId, nonce, payload, callback)` shape, the same AptosBFT machinery, the same fail-safe callback resolution. Adding a new application doesn't mean adding a new trust assumption — it means writing a callback contract and asking governance to register it. The security envelope doesn't expand; only what lives inside it does.


# Build Your Own 100k+ TPS Chain Using Gravity SDK

A developer-focused guide explains how to build a fully functional, custom L1 blockchain application using the Gravity SDK framework.

This developer-focused guide explains how to build a fully functional, custom L1 blockchain application using the **Gravity SDK** framework. We walk through the end-to-end development process with a simple **`key-value store (KvStore)`** application as the running example ([repository](https://github.com/Galxe/gravity-kvstore)).

This guide covers:

* **Core Architecture**: How Gravity SDK decouples complex consensus from application logic through a modular pipeline model.
* **Key Module Implementation**: How to implement the **TxPool** and **Executor/Committer** modules that interface directly with Gravity SDK.
* **Full Lifecycle**: The journey of a transaction—submission, ordering, execution, consensus, and durable persistence.

***

### **1. Core Architecture: The Decoupled Pipeline Model**

At its core, building a blockchain node means constructing a distributed state machine. The design philosophy of **Gravity SDK** is to decompose this complexity into a clear, parallelizable **pipeline model**. This dramatically lowers the development barrier, allowing developers to focus on business logic rather than low-level networking or consensus algorithms.

The pipeline cleanly separates responsibilities between **Gravity SDK** and the **application developer**.

#### **Gravity SDK’s Responsibilities (Consensus & Scheduling Layer)**

* **Consensus Engine**: The heart of Gravity SDK, responsible for the most challenging distributed-systems problems:
  * **Transaction Ordering**: Pulling transactions from the pool and determining their global order in a block.
  * **Block Production & Broadcast**: Packaging ordered transactions into blocks and propagating them across the network.
  * **Networking**: Managing node-to-node P2P communication.
  * **Consensus Finalization**: Running the AptosBFT consensus algorithm to ensure all honest nodes agree on both block contents and execution results.
* **BlockBufferManager**: The bridge between the consensus layer and the execution layer. It tracks block states across their lifecycle (`Ordered`, `Executed`, `Committed`) and enables pipeline parallelism.

#### **Developer’s Responsibilities (Application Logic / State Machine)**

* **Transaction Pool (TxPool / Mempool)**: The entry point for user transactions, buffering them before consensus.
* **Executor**: Where your business logic lives. It receives ordered blocks from the consensus engine, executes each transaction, and computes the resulting state transitions.
* **State / Storage**: The blockchain’s ledger. It maintains the latest in-memory state (balances, KV pairs, etc.) and persists finalized changes to a database.
* **RPC Service**: The application’s external interface, enabling users to query chain data or submit new transactions.

> **Key Advantages: Decoupling & Parallelism**
>
> By abstracting away networking and consensus complexity, Gravity SDK frees developers to focus solely on evolving the state machine through a few well-defined traits.
>
> Furthermore, the three pipeline stages — **Ordering (Consensus)**, **Execution (Executor)**, and **Commit (Committer)** — run as independent, parallel tasks. This architecture enables high throughput (TPS) by fully leveraging concurrency.

This document will guide you through implementing the two most critical developer-side components: the **transaction pool** and the **execution/commit logic**. The architecture is illustrated in the diagram below:

![image.png](/files/GIDtuQyzWAaj7vcCDYNa)

***

### **2. Step 1: Implementing the Transaction Pool (TxPool) – Connecting to Transaction Sources**

The transaction pool is the first stop for any transaction entering the consensus pipeline. Once a user submits a transaction (txn), the consensus engine continuously pulls from your implemented TxPool, selecting the most suitable transactions to package into a new block.

#### **2.1 Understanding Gravity SDK’s Transaction Format (`VerifiedTxn`)**

Regardless of how your application-level transaction (Transaction) is defined, it must be convertible into the standardized `VerifiedTxn` format that Gravity SDK recognizes. This structure bridges your application logic and the SDK.

```rust
// Standardized transaction format defined by Gravity SDK
pub struct VerifiedTxn {
    // The transaction payload, serialized into bytes
    pub bytes: Vec<u8>,
    // The sender’s account address, used for identity and filtering
    pub sender: ExternalAccountAddress,
    // Nonce to prevent replay attacks
    pub sequence_number: u64,
    // Chain ID, ensuring transactions are not reused across different chains
    pub chain_id: ExternalChainId,
    // Transaction hash, serving as the unique identifier.
    // OnceCell ensures the hash is computed only once for efficiency.
    #[serde(skip)]
    pub committed_hash: OnceCell<TxnHash>,
}
```

In our **KvStore** example, we define an `into_verified()` method to perform this conversion. The process typically involves two steps:

1. **Serialization**: Use a serialization library (e.g., `serde` + `bcs`) to encode the custom transaction object into a byte stream (`Vec<u8>`).
2. **Metadata Population**: Fill in essential metadata such as sender address, nonce, and other fields to complete the `VerifiedTxn` structure.

#### **2.2 Implementing the `TxPool` Trait**

The next step is to implement the `TxPool` trait provided by Gravity SDK. Among its methods, the most critical—and the only one you must implement—is `best_txns`.

```rust
pub trait TxPool: Send + Sync + 'static {
    // Returns a batch of the most suitable "Pending" transactions to be included in a block.
    fn best_txns(
        &self,
        filter: Option<Box<dyn Fn((ExternalAccountAddress, u64, TxnHash)) -> bool>>
    ) -> Box<dyn Iterator<Item = VerifiedTxn>>;
}
```

The purpose of this method is straightforward: **return a batch of the highest-quality pending transactions from your pool for block inclusion.**

**Key detail: the `filter` function**

Gravity SDK supplies a `filter` closure when calling `best_txns`. Apply it before returning any transactions; it removes transactions that the consensus engine has already cached or is actively processing.

Why is this necessary?

The consensus engine and your transaction pool operate asynchronously. After the engine pulls a batch of transactions, your pool may not change before the next pull. Without the `filter`, the same transactions could be repackaged into multiple blocks. The `filter` ensures uniqueness and prevents duplication.

***

#### **2.3 Example: `KvStore` Implementation**

Below is the `best_txns` implementation from the KvStore example, with detailed inline commentary:

```rust
impl TxPool for KvStoreTxPool {
    fn best_txns(
        &self,
        filter: Option<Box<dyn Fn((ExternalAccountAddress, u64, TxnHash)) -> bool>>,
    ) -> Box<dyn Iterator<Item = VerifiedTxn>> {
        // Step 1: Take a snapshot of all transactions in the mempool.
        // Locking and cloning ensures thread safety during iteration.
        let txns = (*self.mempool.mempool.lock().unwrap()).clone();
        let filter = Arc::new(filter); // Wrap the filter in Arc for thread-safe sharing.

        // Step 2: Flatten user -> transaction list into a single iterator.
        let res = Box::new(txns.into_iter().flat_map(move |(addr, user_txns)| {
            let filter_clone = filter.clone();
            user_txns.into_iter().filter_map(move |(seq, txn)| {
                let verified_txn = txn.raw_txn.clone().into_verified();

                // Step 3: Apply filter if provided.
                if let Some(f) = filter_clone.as_ref() {
                    // `f` expects (address, nonce, hash) as input.
                    // If it returns false, this txn should be discarded.
                    if !f((
                        addr.clone(),
                        seq,
                        TxnHash::new(verified_txn.committed_hash()), // Compute txn hash
                    )) {
                        return None;
                    }
                }

                // Step 4: If filter passes (or no filter exists), return the transaction.
                Some(verified_txn)
            })
        }));
        res
    }
}
```

Once the `TxPool` trait is implemented, the Gravity SDK consensus engine can automatically start pulling transactions from your pool. It will call `best_txns` periodically, order the returned transactions, and generate blocks.

### **3. Step 2: Implementing Execution Logic (Executor) – Processing Ordered Blocks**

Once the consensus engine agrees on the order of a batch of transactions, it produces an **Ordered Block**—a set of transactions and their agreed-upon order, accepted by all honest nodes in the network.

The Executor continuously fetches these ordered blocks from the `BlockBufferManager` in a dedicated asynchronous task, executes the transactions, and updates the in-memory state.

***

#### **3.1 `execute_task` Pseudocode Walkthrough**

```rust
// Example: Execution task logic
pub async fn execute_task(state: State, pending_blocks: PendingBlocks) {
    loop {
        // Step 1: Fetch ordered blocks that have not yet been executed
        // from the BlockBufferManager. This is async; if no blocks are
        // available, it will wait.
        let ordered_blocks = get_block_buffer_manager()
            .get_ordered_blocks(start_num, max_size)
            .await;

        for (block, _) in ordered_blocks {
            // Step 2: Core execution logic
            // 2.1 Deserialize: Convert Gravity SDK's VerifiedTxn
            //     back into the application’s native transaction type.
            // 2.2 Apply business logic: Iterate over transactions
            //     and update the in-memory state.
            //     (e.g., in KvStore: `map.insert(key, value)`).
            // 2.3 Compute StateRoot: After all txns are executed,
            //     compute the new global state Merkle Root (StateRoot),
            //     a cryptographic commitment to the current state.
            let exec_res = Self::execute_block(block, &state, &pending_blocks).await;

            // Step 3: Report execution results back to BlockBufferManager.
            // This updates the block’s lifecycle from "Ordered" → "Executed".
            get_block_buffer_manager()
                .set_compute_res(block.block_meta.block_id, exec_res, ...)
                .await;

            // Step 4: Increment to the next block number.
            start_num += 1;
        }
    }
}
```

***

> **Key Insight: In-Memory Execution & Result Consensus.**
>
> At this stage, all state changes occur only in memory. **Why?** Although transactions have been executed, the results have not yet gone through consensus. Only after the network agrees on the execution results can the block be considered finalized.
>
> The computed results (`StateRoot/ExecHash`) are sent back to Gravity SDK for a **second round of consensus**.

### **4. Step 3: Implementing Commit Logic (Committer) – Persisting the Final State**

A block and its associated state changes can be considered **finalized** only after a majority of nodes have also reached consensus on the **execution result** (i.e., the `StateRoot/ExecHash`). At this point, it is safe to persist the data to disk. This is the role of the Commit stage.

Similar to the execution task, the commit logic runs in its own dedicated asynchronous task.

#### **4.1 `commit_task` Pseudocode Walkthrough**

```rust
// Example: Commit task logic
pub async fn commit_task(storage: Storage, pending_blocks: PendingBlocks) {
    loop {
        // Step 1: Fetch blocks whose execution results
        // have already reached consensus and are ready to commit.
        // Within Gravity SDK, these blocks are now marked as "Committed".
        let committed_blocks = get_block_buffer_manager()
            .get_committed_blocks(start_num, max_size)
            .await;

        for block_info in committed_blocks {
            // Step 2: Retrieve the previously executed block data
            // and state changes from the in-memory cache (e.g., pending_blocks).
            // This associates the execution phase results with the commit phase confirmation.

            // Step 3: Atomically persist the block data and state changes
            // to the underlying storage (e.g., RocksDB, Sled).
            // This is the first time the transaction lifecycle data
            // is permanently written to disk.
            Self::persist_block(block_info.num, &pending_blocks, storage.as_ref()).await;

            // (Optional) Step 4: Cleanup.
            // After persistence, remove the committed block data
            // from in-memory caches (pending_blocks) to free resources.
        }
    }
}
```

At this point, a transaction’s full lifecycle—from submission, to consensus on ordering, to execution, and finally to durable persistence—has been fully completed and permanently recorded on-chain.

### **5. Step 4: Assembly & Startup**

The final step is to integrate all implemented modules (TxPool, Executor, Committer, Storage, etc.) and launch the blockchain node.

A typical startup workflow is as follows:

1. **Initialize Core Modules**: Load node configuration, initialize storage, load the genesis block to establish the initial state, and create the transaction pool (Mempool) instance.
2. **Start the Consensus Engine**: Using the node configuration and the TxPool instance, initialize and start the `ConsensusEngine`. This is the heart of Gravity SDK.
3. **Launch Background Tasks**: Use an asynchronous runtime (e.g., `tokio::spawn`) to start the previously defined `execute_task` and `commit_task` as independent background services.
4. **Start RPC Service** (not detailed in the example): Launch an RPC server to listen for external requests and inject transactions into the TxPool.
5. **Block the Main Thread**: Keep the main thread alive to ensure the node runs continuously.

***

#### **Example: KvStore Startup Code**

```rust
fn main() -> Result<()> {
    // 1. Initialize storage, genesis state, etc.
    let storage = Arc::new(SledStorage::new("blockchain_db")?);
    let blockchain = Blockchain::new(storage.clone(), "genesis.json");
    let state = blockchain.get_latest_state();
    let mempool = KvStoreTxPool::new();
    let pending_blocks = Arc::new(DashMap::new()); // Shared data between execution and commit tasks

    // 2. Initialize and start the Gravity SDK Consensus Engine
    // Pass configuration, networking components, and our TxPool implementation
    let _consensus_engine = ConsensusEngine::init(
        ConsensusEngineArgs { ... },
        Box::new(mempool), // Instance implementing the TxPool Trait
    ).await;

    // 3. Launch execution task
    let state_clone = state.clone();
    let pending_blocks_clone = pending_blocks.clone();
    tokio::spawn(async move {
        PipelineExecutor::execute_task(start_num, None, state_clone, pending_blocks_clone).await;
    });

    // 4. Launch commit task
    let pending_blocks_clone2 = pending_blocks.clone();
    tokio::spawn(async move {
        PipelineExecutor::commit_task(start_num, None, storage, pending_blocks_clone2).await;
    });

    // 5. Block the main thread to keep the node running
    // Typically, the RPC service would be launched here and wait for termination signals
    // ...
    Ok(())
}
```

***

> **Multi-Node Cluster Configuration**
>
> When deploying a multi-node network, each validator node requires its own configuration file (`validator.yaml`), private keys, and an initial waypoint to ensure that all nodes boot from the same trusted genesis state. Refer to Gravity SDK’s official documentation for details.

### **6. Data Flow Recap: The Complete Lifecycle of a Transaction**

Let’s use a simple key-value transaction to illustrate the full process:

1. **Submission**: The user calls the RPC interface to submit a transaction `Set("key", "value")`.
2. **Pooling**: The RPC service receives the request, wraps it into the application’s native transaction object, and inserts it into the implemented `KvStoreTxPool` for processing.
3. **Ordering Consensus**: The Gravity SDK `ConsensusEngine` pulls this transaction from the `KvStoreTxPool` (via the `best_txns` method), packages it together with other transactions into an **ordered block**, and reaches consensus across the network on its contents and order.
4. **Execution**: The `execute_task` retrieves the ordered block from the `BlockBufferManager`. It deserializes the `Set("key", "value")` transaction, updates the key-value state **in memory**, and computes the new global `StateRoot`. This execution result is then reported back to the `BlockBufferManager`.
5. **Result Consensus**: The `ConsensusEngine` runs a second round of consensus on the block’s execution result (`StateRoot`), ensuring that all nodes agree on the outcome.
6. **Committing**: Once result consensus is achieved, the `commit_task` fetches this block from the `BlockBufferManager` and **persists** the state changes (the updated `"key"` value) together with the block information to the disk database.

At this point, the transaction is finalized, and the state update is permanently recorded.

Through this lifecycle, we show how Gravity SDK lets developers leverage its robust consensus framework while seamlessly integrating their custom application logic to build a simple yet fully functional blockchain application.


# Validator Cluster Deployment Guide

Deploy a local multi-validator Gravity EVM cluster using Gravity SDK in minutes — the fastest way to run a high-performance, EVM-compatible chain from scratch.

Gravity SDK makes it straightforward to spin up your own EVM-compatible chain with the same [AptosBFT](https://aptos.dev/en/network/blockchain/bft-consensus) consensus and parallel execution engine that powers the Gravity L1. Whether you want to run a local devnet for development, benchmark raw throughput, or evaluate the technology, this guide walks you through a complete cluster deployment in five steps.

> For a deeper dive into the SDK architecture and how to build production-grade chains, see [Build Your Own 100k+ TPS Chain Using Gravity SDK](/research-and-development/gravity-sdk-tutorial).

***

## Prerequisites

Ensure you have the following installed:

* **Rust**: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
* **Foundry** (for genesis contract deployment): `curl -L https://foundry.paradigm.xyz | bash` then `foundryup`
* **Python 3**: For parsing configurations.
* **envsubst**: Usually part of the `gettext` package (`sudo apt install gettext` on Ubuntu).

## Quick Start (4-Node Cluster)

### 1. Clone the Repository

```bash
git clone https://github.com/Galxe/gravity-sdk.git
cd gravity-sdk
```

### 2. Build the Node Binary

Benchmark results are only meaningful when the node is compiled with optimizations:

```bash
make BINARY=gravity_node MODE=quick-release
```

Refer to [gravity-sdk/readme.md](https://github.com/Galxe/gravity-sdk/blob/main/readme.md) for full build options.

### 3. Setup Configuration

```bash
cd cluster
cp genesis.toml.example genesis.toml    # Genesis / validator config
cp cluster.toml.example cluster.toml    # Node deployment config
```

The default configuration sets up 4 nodes on localhost. Edit `genesis.toml` to customize validators, stake amounts, and network parameters. Edit `cluster.toml` to adjust ports or the path to your binary.

### 4. Initialize Node Keys

```bash
make init
```

This generates `identity.yaml` for each validator node.

### 5. Generate Genesis (New Networks Only)

```bash
make genesis
```

Outputs `./output/genesis.json` and `./output/waypoint.txt`.

> **Note**: `genesis.sh` clones `gravity_chain_core_contracts` into `external/` on first run but does **not** auto-update it. To update manually: `cd external/gravity_chain_core_contracts && git pull origin main`

### 6. Deploy and Start

```bash
make deploy_start
```

Your cluster is now running. Useful commands:

```bash
make status   # Show PID, status, and current block number
make stop     # Gracefully stop all nodes
```

***

## Configuration Reference

### `genesis.toml` (New Networks Only)

| Section                      | Description                                              |
| ---------------------------- | -------------------------------------------------------- |
| `[genesis]`                  | Core genesis parameters (chain ID, epoch interval, etc.) |
| `[genesis.faucet]`           | Pre-funded faucet account for testing                    |
| `[genesis.validator_config]` | Validator bond limits and restrictions                   |
| `[[genesis_validators]]`     | Genesis validator list with addresses and stake          |

**Key validator fields:**

* `address` — Validator's ETH address (required)
* `stake_amount` — Initial stake in Wei (required)
* `voting_power` — Initial voting power (must be ≥ stake\_amount)

### `cluster.toml` (Node Deployment)

| Section            | Description                                |
| ------------------ | ------------------------------------------ |
| `[cluster]`        | Cluster name and base directory            |
| `[build]`          | Path to the `gravity_node` binary          |
| `[genesis_source]` | Paths to `genesis.json` and `waypoint.txt` |
| `[[nodes]]`        | Node definitions with ports and roles      |
| `[faucet_init]`    | Optional faucet initialization config      |

**Node roles:**

* `genesis` — Included in the genesis validator set
* `validator` — Validator that joins via on-chain transaction
* `vfn` — Full node using on-chain discovery

***

## Makefile Reference

| Target              | Description                               |
| ------------------- | ----------------------------------------- |
| `make genesis`      | Generate `genesis.json` + `waypoint.txt`  |
| `make init`         | Generate node identity keys               |
| `make deploy`       | Prepare runtime environment for each node |
| `make start`        | Start all nodes                           |
| `make stop`         | Stop all nodes                            |
| `make status`       | Check cluster status                      |
| `make faucet`       | Initialize faucet accounts                |
| `make clean`        | Remove generated artifacts                |
| `make deploy_start` | Deploy and start (convenience)            |
| `make restart`      | Stop, deploy, and start                   |

***

## Next Steps

Once your cluster is running, follow the [Benchmark Reproduction Guide](/research-and-development/benchmark-guide) to benchmark throughput and latency using `gravity_bench`.


# Benchmark Reproduction Guide

Step-by-step guide to reproducing the Gravity EVM benchmark and collecting throughput and latency data using gravity\_bench.

### Overview

* **Goal**: Continuously stress Gravity's RPC endpoints and measure throughput (TPS) and latency.
* **Repository**: `https://github.com/Galxe/gravity_bench`
* **What the tool does**:
  * Deploys the required ERC20 contracts.
  * Prepares a large pool of accounts/addresses.
  * Concurrently sends transactions to one or more RPC endpoints.

### Prerequisites

1. **A `gravity_node` binary built in release mode** — benchmark results are only meaningful when the node is compiled with optimizations. Refer to [gravity-sdk/readme.md](https://github.com/Galxe/gravity-sdk/blob/main/readme.md) for full build instructions. The recommended command is:

   ```bash
   make BINARY=gravity_node MODE=quick-release
   ```
2. **A running Gravity EVM cluster** (refer to: [Validator Cluster Deployment Guide](/research-and-development/cluster-deployment)):
   * Code: <https://github.com/Galxe/gravity-sdk> (see [releases](https://github.com/Galxe/gravity-sdk/releases) for tagged versions)
     * Note: example cluster configurations are available at: <https://github.com/Galxe/gravity-sdk/tree/main/cluster/example>
   * `chain_id`: `1337 (example)`
   * `nodes1`: `http://127.0.0.1:8545 (example Validator1)`
   * `nodes2`: `http://127.0.0.1:8546 (example Validator2)`
   * `nodes3`: `http://127.0.0.1:8547 (example Validator3)`
3. **A funded EOA** for use as **faucet + deployer**:

   * You must provide this account's private key in the config file.
   * The account needs sufficient native token balance to:
     * Fund a large number of test accounts (directly or via cascading faucet mode).
     * Pay gas for contract deployment.

   A test faucet account is pre-funded in genesis.toml, with private key\
   `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`,\
   corresponding to address `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266`.\
   The following configuration must be present in genesis.toml to give this address a balance:

   ```toml
   [genesis.faucet]
   address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
   private_key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
   balance = "1000000000000000000000000"   # 1M ETH
   ```

### System Dependencies (Ubuntu)

Install all required build and runtime packages in one step:

```bash
sudo apt update && sudo apt install -y \
  build-essential clang pkg-config libssl-dev git curl \
  libudev-dev libusb-1.0-0-dev \
  python3 python-is-python3 python3-pip python3-venv \
  nodejs npm
```

> `python-is-python3` creates the `python` command alias required by gravity\_bench's internal scripts. `libudev-dev` / `libusb-1.0-0-dev` prevent common build errors when compiling `hidapi`.

### Environment Setup

1. **Clone the repository**

   ```bash
   git clone https://github.com/Galxe/gravity_bench.git
   cd gravity_bench
   ```
2. **Run the initialization script**

The script will:

* Check and install missing tools (Rust, Node.js, Python)
* Create a Python virtual environment
* Install Python and Node dependencies
* Clone the contract repositories required for benchmarking

**Recommended (keep the environment active in the current shell):**

```bash
source setup.sh
```

> ⚠️ On Ubuntu, if you see `Failed to create Python virtual environment`, first run:
>
> ```bash
> sudo apt install python3-venv
> ```
>
> Then re-run `source setup.sh`.

**Alternative (requires manual environment activation):**

```bash
bash setup.sh
# Then manually activate the environment:
source venv/bin/activate
source ~/.cargo/env  # only needed if the script installed Rust
```

### Configuration

1. **Create a local config file**

   ```bash
   cp bench_config.template bench_config.toml
   ```
2. **Edit `bench_config.toml`**

Key fields to review:

* `nodes`: one or more RPC endpoints
* `target_tps`: target benchmark TPS; recommended not to exceed 9k on a 3-node cluster
* `[faucet].private_key`: **private key of the funded faucet/deployer account**
* `[accounts].num_accounts`: number of benchmark accounts; 100k recommended
* `[performance]`: concurrency and pool configuration

**Configuration constraints** — violating these will cause an assertion failure on startup:

* `accounts.num_accounts` ≥ `target_tps`
* `performance.num_senders` ≤ `accounts.num_accounts`

Example (abbreviated):

```toml
# Gravity Bench Configuration File

# Uniswap configuration file path (generated by deployment)
contract_config_path = "deploy.json"

# Target sending rate
target_tps = 9000

# RPC endpoints, replace with your chain_id and addresses
nodes = [
    { rpc_url = "http://127.0.0.1:8545", chain_id = 1337 },
    { rpc_url = "http://127.0.0.1:8546", chain_id = 1337 },
    { rpc_url = "http://127.0.0.1:8547", chain_id = 1337 },
]

num_tokens = 1
enable_swap_token = false

# Address pool type: "random" (default) or "weighted" (hot/normal/long-tail distribution)
address_pool_type = "random"

[faucet]
# Private key (replace with your real key)
private_key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"

# Faucet Level:
# - 10 enables cascade mode: 1 -> 10 -> 100 (amplification chain)
# - 0 disables cascading
faucet_level = 10

# Wait between faucet distribution levels (increase if you see insufficient funds)
wait_duration_secs = 1

# Target ETH balance per funded account (in wei)
fauce_eth_balance = "1000000000000000000000"

[accounts]
num_accounts = 100000

[performance]
# Number of concurrent transaction sending tasks inside TxnConsumer
num_senders = 600

# Max in-memory pool size inside the consumer
max_pool_size = 100000

# Benchmark duration in seconds (0 = run indefinitely)
duration_secs = 0

# Sampling strategy: integer = sample every N txns, or "full" to check all pending
sampling = 20
```

### Running the Benchmark

#### First Run (includes faucet distribution + contract deployment)

For the first run (or when you want to re-initialize accounts/contracts):

```bash
cargo run --release -- --config bench_config.toml
```

This step will:

* Distribute funds to test accounts using the faucet private key.
* Deploy the required contracts.
* Generate (or update) `deploy.json`, referenced by `contract_config_path`.

#### Subsequent Runs (reuse existing state)

Once contracts are deployed and `deploy.json` exists, use recovery mode:

```bash
cargo run --release -- --config bench_config.toml --recover
```

### Diagnostics

**Verify an RPC endpoint is reachable and get its `chain_id`:**

```bash
curl -s http://127.0.0.1:8545 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# expect 0x539 for chainId 1337
```

**Check a faucet account balance:**

```bash
curl -s http://127.0.0.1:8545 \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getBalance","params":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","latest"]}'
```

### Troubleshooting

| Symptom                                                       | Fix                                                                                                                    |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Build error: `libudev.pc` / `hidapi` / `pkg-config` not found | `sudo apt install -y libudev-dev libusb-1.0-0-dev pkg-config`                                                          |
| `python: command not found`                                   | `sudo apt install -y python-is-python3`                                                                                |
| `ModuleNotFoundError: No module named 'web3'`                 | Ensure you're in the `gravity_bench` directory and run `source setup.sh` again                                         |
| `SolcError` or missing Uniswap/OpenZeppelin contracts         | Remove `contracts/` and `node_modules/` then re-run `source setup.sh`                                                  |
| `insufficient funds for gas * price + value`                  | Increase `faucet.wait_duration_secs` in `bench_config.toml`; for a local cluster, restart all nodes to reset state     |
| `assertion failed: accounts.num_accounts >= target_tps`       | Increase `accounts.num_accounts` to be ≥ `target_tps`                                                                  |
| `Connection refused` / wrong network                          | Verify `rpc_url` is correct and the cluster is running; confirm `chain_id` matches the value returned by `eth_chainId` |

### Visualization

For Grafana / Prometheus deployment and dashboard import, refer to:

* Grafana / Prometheus deployment guide coming soon.


# 3-Validator Cluster Benchmark Results

3-validator cluster benchmark results from 2026-02-28, covering TPS benchmarks and bottleneck analysis across CPU, memory, and I/O.

### Test Environment

| Parameter        | Value                           |
| ---------------- | ------------------------------- |
| **Topology**     | 3 validators + 1 VFN            |
| **Machine spec** | 8 vCPU / 16 GB RAM              |
| **Disk**         | 200 GB pd-balanced (4,200 IOPS) |
| **Accounts**     | 100k accounts                   |

### Load Test Results (transaction removal rate)

* **Before write buffer is full**: \~**11k TPS** ERC20 transfer
* **After write buffer is full**: \~**9.5k TPS** ERC20 transfer

<figure><img src="/files/oEoZjpppwL4bkv0bS8DP" alt="TPS chart before and after write buffer saturation"><figcaption><p>TPS over time</p></figcaption></figure>

<figure><img src="/files/pYfILdufs25lcesglr5x" alt="TPS detail chart"><figcaption><p>TPS detail</p></figcaption></figure>

***

### Bottleneck Analysis

#### Resource Utilization

**1. CPU**

* CPU was **not** the bottleneck (usage \~**800%** on a 16-core machine)
* Execution, Merkle computation, and other pipeline stages all completed within the block time (\~**200 ms**)

<figure><img src="/files/JzLd7lUswM8bgL9RCC8R" alt="CPU utilization chart"><figcaption><p>CPU utilization during load test</p></figcaption></figure>

**2. Memory**

* Memory grew continuously during the block cache fill phase, eventually reaching the **16 GB** limit

<figure><img src="/files/FPgB0mUng48eKo6r0YmQ" alt="Memory usage chart"><figcaption><p>Memory growth as block cache fills</p></figcaption></figure>

**3. Persistence (I/O)**

* Persistence latency was noticeably higher than the block time (\~**300 ms** vs \~**200 ms**)
* This caused the write buffer to accumulate and memory to grow
* Significant back-pressure appeared once the buffer reached the limit of **64**

<figure><img src="/files/S8zT4W96O6J5Hw19srXK" alt="I/O persistence latency chart"><figcaption><p>Persistence latency vs. block time</p></figcaption></figure>


# (Archived) Grevm 1.0

Gravity Parallel EVM (Grevm) is a high-performance, parallel EVM runtime.

## Introducing Grevm

We are excited to announce the release of [Grevm 1.0 (Gravity EVM)](https://github.com/Galxe/grevm), an open-source, parallel EVM runtime based on [revm](https://github.com/bluealloy/revm). Grevm's algorithm is inspired by [BlockSTM](https://arxiv.org/abs/2203.06871), and we've enhanced it by incorporating a transaction data dependency graph derived from simulation results. This mechanism enables more effective scheduling for parallel execution, minimizing transaction re-executions.

In our benchmark, Grevm stands as the **fastest** open-source parallel EVM implementation to date. For fully parallelizable transactions, Grevm is **4.13×** faster than sequential execution, running at **26.50 gigagas/s.** If we simulate real-world I/O latency of **100 μs**, it is **50.84×** faster than sequential execution, with **6.80 gigagas/s** throughput. This leap in performance is attributed to both the parallelized execution and the integration of asynchronous I/O operations—enabled by the parallelism—which further amplifies the speedup by efficiently overlapping I/O operations.

This marks our first step toward the broader vision of **Gravity Chain** and **Gravity SDK**—an open-source, high-performance Layer 1 blockchain toolkit. **Grevm** is a critical component of this vision, serving as the execution runtime that enables Gravity Chain to achieve a throughput of 1 gigagas per second, essential for supporting the next generation of Web3 applications. Together, they provide a modern toolkit for launching high-performance EVM Layer 1 solutions, effectively scaling Ethereum.

Grevm's development builds upon and greatly benefits from the pioneering work of several key projects in the blockchain space. We extend our gratitude to [Paradigm](https://www.paradigm.xyz/) and [ithacaxyz](https://x.com/ithacaxyz) for [reth](https://github.com/paradigmxyz/reth) & [revm](https://github.com/bluealloy/revm), which form the foundation upon which Grevm is built. Our sincere thanks go to [Aptos](https://aptoslabs.com/) for their implementation of the **BlockSTM** algorithm and insightful optimizations implemented in the codebase. Additionally, we are also grateful to [Rise](https://www.riselabs.xyz/) for their exploration of parallel EVM execution using BlockSTM ([pevm](https://github.com/risechain/pevm)), as well as the **BNB Chain team** for their in-depth exploration of [parallel EVM performance](https://www.bnbchain.org/en/blog/road-to-high-performance-parallel-evm-for-bnb-chain). These foundational efforts have been instrumental in shaping Grevm and guiding its design.

Grevm 1.0 is still a PoC implementation, where its known limitations are discussed in the following sections. We are currently working on the next version of Grevm 2.0, which will be release soon in December 2024.

> Grevm 1.0 is reth-ready, please see [use-with-reth.md](https://github.com/Galxe/grevm/blob/main/use-with-reth.md) for more details.

## Technical Design

![An Ideal Parallel Execution Example](/files/sioZ1pT6tp7YGEfN7Tya)

*Figure 1: Ideal Parallel Execution*

Before diving into the specifics of our algorithm, it's instructive to consider what an ideal parallel execution would look like. *Figure 1* illustrates this perfect scenario, where transactions are processed in parallel without conflicts, effectively maximizing throughput and resource utilization.

Consider a sequence of transactions ordered as **Tx₁**, **Tx₂**, ..., **Txₙ**. The ideal process involves:

1. **Precise Analysis of Transaction Dependencies**:
   * Transaction dependencies are *accurately* analyzed and represented using a **Directed Acyclic Graph (DAG)**, which captures the data (read-after-write) dependencies between transactions.
   * Specifically, a transaction **Txⱼ** depends on **Txᵢ** (where **j > i**) if and only if **Txⱼ** reads from a storage slot that **Txᵢ** writes to. This indicates a true read-after-write dependency.
   * *Example*: If **Tx₃** reads ERC20 balance of Alice that **Tx₂** would modify, **Tx₃** must wait for **Tx₂** to complete, ensuring data consistency.
2. **Optimal Distribution of Transactions Across Threads**:
   * The scheduler *optimally* distribute transactions across multiple threads, balancing the computational (CPU-intensive) and input/output (I/O-intensive) workloads.
3. **Parallel Execution on Software Transactional Memory (STM) System**:
   * A high-performance **STM** provides multi-version state access to each thread
   * During execution, each transaction can read the writes of all preceding transactions but not those of subsequent ones, effectively avoiding write-after-read hazards.
   * **Write-After-Write Conflict Resolution**:
     * If multiple transactions write to the same storage slot, the STM resolves the conflict by using the value from the transaction with the highest sequence number (i.e., the latest transaction in the sequence).
     * This ensures that the final state reflects the correct order of transactions as intended in the original sequence.

However, achieving this ideal in live block execution contexts—such as running a validator node or performing block synchronization—is challenging due to several factors:

* **Unpredictability of Transaction Interactions**: The precise data dependencies and resource requirements of each transaction are difficult to determine without sequentially executing them, due to the dynamic nature of high-contention transactions, e.g., DEX swaps.
* **Real-Time Analysis Overhead**: Performing exact dependency analysis in real-time introduces significant computational overhead, potentially negating the benefits of parallel execution.

Recognizing these limitations, our approach leverages transaction simulation results obtained by running each transaction against the most recent available state view before execution. These simulations provide estimates of which storage slots a transaction will read or write, which serves as input to build the data dependency DAG. These hints can be computed before parallel execution, avoiding introducing additional computational overhead during execution.

![Data From Glassnode Studio: Ethereum Tx Type Breakdown](/files/bE0qFNGw1rvZ9H4saHuW)

*Screenshot 1: Ideal Parallel Execution*

While not all hints are perfectly precise, these simulation-based hints are generally accurate enough for practical purposes. For instance, on the Ethereum mainnet, by **historical gas usages**, approximately 30% of transactions are simple Ether transfers, and another 25%-30% are ERC20 token transfers, which typically involve reading and writing to a limited number of accounts and storage slots. In such transactions, simulation results are consistently accurate.

Building upon these insights, we have developed a **three-phase parallel execution framework** for **Grevm**, a follow-up work of **Block-STM** model by incorporating data dependency hints from transaction simulations:

* **Phase 1**: **Hint Generation & State Preloading**—Simulate transactions to gather dependency hints and warm-up memory cache. This phase can be performed at various points in time, depending on the design of the blockchain. For example, when new transactions arrive in the mempool, simulations can be run immediately to prepare dependency hints in advance.
* **Phase 2**: **Dependency Analysis**—Transform the dependency hints gathered during the simulation phase into a DAG that models the dependencies between transactions. This DAG serves as a roadmap for scheduling transactions in the subsequent parallel execution.
* **Phase 3**: **Concurrent Execution with Conflict Resolution**—Execute transactions in parallel using a modified BlockSTM algorithm that leverages the dependency DAG generated in Phase 2. Instead of the scheduler selecting transactions strictly based on their sequence numbers in the block (e.g., 1, 2, 3, ..., n), it now prioritizes transactions according to the DAG to minimize conflicts and reduce the need for re-executions.

## Implementation and Evaluation

### Grevm 1.0: A Proof-of-Concept Implementation

![Grevm 1.0 PoC Arch](/files/7yqQ7soAhuAmqGn4Qew2)

*Figure 2: Grevm 1.0 PoC Implementation*

To validate the above framework and assess their practical impact, we developed **Grevm 1.0** as a preliminary proof of concept. The source code can be found on our Github: <https://github.com/Galxe/grevm>. Grevm is ready to be integrated with reth, please see <https://github.com/Galxe/grevm/blob/main/use-with-reth.md>.

This initial implementation focuses on testing our hypotheses while minimizing engineering complexity. Despite its known limitations, Grevm 1.0 has demonstrated significant performance improvements in parallel transaction execution.

The three phases of our framework are executed iteratively across multiple rounds (see Figure 2). This iterative approach simplifies the engineering effort and allows for flexible experimentation. For each round, the above three phrases is implemented as the following:

1. **Hint Generation**
   * **First Round:** We simulate each transaction against the last known state to gather initial dependency hints, specifically the read and write sets.
   * **Subsequent Rounds**: Instead of re-simulating, we use the read and write sets obtained from the previous round's execution.
2. **Dependency Analysis**
   * **Dependency Graph Construction**: We construct a dependency graph based on the read and write sets of transactions based on hints.
   * **Partitioning Transactions**: We break the DAG into Weakly Connected Components (WCCs). Each WCC represents a group of transactions that are interdependent and must be considered together to avoid conflicts.
   * **Greedy Partitioning Algorithm**: We assign these WCCs to partitions using a greedy algorithm
     * The number of partitions is set to **2 × number of CPU cores + 1** to maximize parallelism.
     * Each transaction is assigned a weight based on the estimated gas usage.
     * We aim to distribute the total weight evenly across partitions.
3. **Concurrent Execution**
   * **Execution:** Each partition is executed independently and in parallel using its own executor. Within each partition, transactions are executed sequentially to respect intra-partition dependencies. After all partitions complete execution, we attempt to merge the changesets from each partition into a single state.
   * **Validation:** We validate transactions by comparing their read sets against the writes from other partitions. Transactions are classified into three states:
     * **Finalized**: No conflicts detected, and transaction IDs are sequentially continuous from the last finalized transaction.
     * **Unconfirmed**: No conflicts detected, but transaction IDs are not sequentially continuous.
     * **Conflict**: Conflicts are detected; these transactions require re-execution.
   * **Merge:** If all transactions are finalized, exit. Otherwise, we merge all finalized transaction into a new state, and go back to step 1 with the remaining unconfirmed and conflict transactions, with their read/write set as the updated speculation.

The above phases are repeated for up to **three rounds**. If convergence (i.e., all transactions being finalized) is not achieved after three rounds, we fallback to sequential execution for the remaining transactions.

Despite its advantages, our simplified implementation has known limitations. By partitioning based on Weakly Connected Components (WCCs), we treat all data dependencies within a WCC as transitive across all included transactions, which is overly restrictive. For example, with a hot ratio of 30%—meaning 30% of transactions access a set of common storage slots—about half of the transactions may be grouped into a single WCC. This significantly limits parallelism, often reducing it to two or fewer concurrent partitions, underutilizing available resources. Additionally, if dependency hints are highly inaccurate, the system may fail to resolve conflicts after three rounds of parallel execution and revert to sequential execution, resulting in worse performance compared to algorithms like BlockSTM, which experience only about a 30% slowdown in their worst-case scenarios in their benchmark.

## Evaluation

We evaluate the 1.0 implementation with the following setup:

* gcloud n2d-standard-32 32 vCPUs @2450MHz
* Ubuntu 20.04.6 LTS
* cargo 1.81.0 (2dbb1af80 2024-08-20)
* Grevm git commit hash: `ef3f2cb7b43a37f0acd69798d99678a1f1784f62`
* pevm git commit hash: `d48fae90b6ad36ddc5d613ee28ad23214353e81e`
* Benchmark code: <https://github.com/Galxe/grevm/blob/main/benches/gigagas.rs>

To reproduce the benchmark, run

```bash
JEMALLOC_SYS_WITH_MALLOC_CONF="thp:always,metadata_thp:always" NUM_EOA=${NUM_EOA} HOT_RATIO=${HOT_RATIO} DB_LATENCY_US=${DB_LATENCY_US} cargo bench --bench gigagas
```

Replace `${NUM_EOA}`, `${HOT_RATIO}`, and `${DB_LATENCY_US}` with the desired parameters:

* `NUM_EOA`: Number of accounts.
* `HOT_RATIO`: Ratio of transactions accessing common ("hot") account.
* `DB_LATENCY_US`: Simulated database latency in microseconds.

### Gigagas Block Test

We conducted the gigagas block test, a benchmark designed to evaluate the efficiency of parallel execution under varying workloads and conditions. We reused some portions of the benchmarking code from pevm. Each mock block contains transactions totaling **1 gigagas** in gas consumption. Note that we use the actual gas consumption of transactions to calculate the total gas, which accounts for the gas refunds. The transactions include vanilla Ether transfers, ERC20 token transfers, and Uniswap swaps. Pre-state data is stored entirely in-memory to isolate execution performance from disk I/O variability. To mimic real-world conditions where disk I/O latency can impact performance, we introduced artificial latency using the `db_latency` parameter.

### Conflict-Free Transactions

We first evaluated our implementation using conflict-free workloads to measure optimal performance. In this scenario, transactions consist of independent raw transfers, ERC20 transfers, and Uniswap swaps, each involving separate contracts and accounts to ensure no data dependencies. This setup provides a baseline to assess the maximum achievable performance improvement through parallel execution without the impact of transaction conflicts.

| Test            | Num Txs | DB Latency | Sequential Execution (ms) | Parallel Execution (ms) | Execution Speedup | Total Gas     | Throughput (Gigagas/s) |
| --------------- | ------- | ---------- | ------------------------- | ----------------------- | ----------------- | ------------- | ---------------------- |
| Raw Transfers   | 47620   | 0          | 155.86                    | 37.73                   | 4.13              | 1,000,020,000 | 26.5                   |
|                 | 47620   | 100us      | 7476.21                   | 146.99                  | 50.84             | 1,000,020,000 | 6.8                    |
| ERC20 Transfers | 33628   | 0          | 285.64                    | 63.88                   | 4.47              | 906,276,572   | 14.19                  |
|                 | 33628   | 100us      | 10636.06                  | 208.94                  | 50.87             | 906,276,572   | 4.34                   |
| Uniswap Swaps   | 6413    | 0          | 679.99                    | 82.71                   | 8.22              | 1,000,004,742 | 12.09                  |
|                 | 6413    | 100us      | 24440.75                  | 420.91                  | 58.06             | 1,000,004,742 | 2.38                   |

*Table 1: Grevm 1.0 Conflict-Free Transaction Execution Speedup*

Under conflict-free conditions, parallel execution with Grevm 1.0 showed significant speedup compared to sequential execution, especially when simulated I/O latency was introduced. For raw transfer, we observed a 4.13x speed up and when DB access latency is 100us, we achieved a 50.84x speedup. Similar results can be found for ERC20 transfers and uniswap swaps.

![Speedup v.s. IO Latency](/files/SjS6c7G3hCgY6AqWBcSH)

*Figure 3: IO Latency v.s. Speedup, Hot Ratio = 0%*

The introduction of I/O latency amplified the performance advantages of parallel execution. While sequential execution suffers from increased latency due to its linear processing nature, parallel execution mitigates this effect by overlapping I/O operations across multiple threads. See Figure 3.

|                 | Num Txs | DB Latency | Sequential Execution pevm (ms) | Parallel Execution pevm (ms) | Execution Speedup | Throughput (Gigagas/s) |
| --------------- | ------- | ---------- | ------------------------------ | ---------------------------- | ----------------- | ---------------------- |
| Raw Transfers   | 47620   | 0          | 156.47                         | 55.488                       | 2.82              | 18.02                  |
|                 | 47620   | 100us      | 7484.1                         | 259.18                       | 28.88             | 3.85                   |
| ERC20 Transfers | 33628   | 0          | 278.24                         | 65.127                       | 4.27              | 15.35                  |
|                 | 33628   | 100us      | 10628                          | 683.13                       | 15.55             | 1.46                   |
| Uniswap Swaps   | 6413    | 0          | 665.96                         | 33.787                       | 19.71             | 29.59                  |
|                 | 6413    | 100us      | 26368                          | 839.49                       | 31.4              | 1.19                   |

*Table 2: pevm Benchmark Result of Conflict-Free Transaction Execution*

To compare Grevm with the vanilla BlockSTM algorithm, we ran [the same benchmark](https://github.com/risechain/pevm/pull/398) using **pevm**. For conflict-free workloads, Grevm should theoretically perform similarly, which is confirmed in our tests with raw and ERC20 transfers. However, the integration of asynchronous I/O in Grevm allows for better utilization of system resources, leading to significantly superior performance when I/O latency is present. For Uniswap transactions, Grevm's results are slower because the state merging part remains sequential in the current implementation. It introduces many unnecessary copies, and when changesets are large, e.g. Uniswap transactions, these copies significantly slow down the execution. But since this component will be completely reworked in the upcoming 2.0 implementation, we will not optimize it in the current version.

We noticed that some transactions in our benchmark may refund gas, e.g. when ERC20 balances become zero. The refunded gas are not accounted for in the total gas in our case, which may lead to a slight discrepancy in the throughput calculation with pevm. We will conduct a more detailed analysis in the future.

For a fair comparison, The above test result of *Table 1* excludes certain overheads

* **State Bundling**: The time spent creating bundle states from cache states is not included, as this is a necessary step for interfacing with the **reth** API but is not present in other implementations' benchmarks.
* **Initial Hint Parsing and Partitioning**: When integrated with pipelined blockchain, the time taken for the initial simulation and transaction partitioning is also excluded, because they will be ready before the start of execution.

But even with the above overheads, the total speedup is still considerably significant, especially when DB latency is non-zero, see Table 3.

| Test            | Num Txs | DB Latency | Sequential Total (ms) | Parallel Total (ms) | Total Speedup | Total Gas     | Throughput (Gigagas/s) |
| --------------- | ------- | ---------- | --------------------- | ------------------- | ------------- | ------------- | ---------------------- |
| Raw Transfers   | 47620   | 0          | 190.12                | 69.176              | 2.75          | 1,000,020,000 | 14.46                  |
|                 | 47620   | 100us      | 7512.8                | 179.03              | 41.96         | 1,000,020,000 | 5.59                   |
| ERC20 Transfers | 33628   | 0          | 317.13                | 96.559              | 3.28          | 906,276,572   | 9.39                   |
|                 | 33628   | 100us      | 10673                 | 243.27              | 43.87         | 906,276,572   | 3.73                   |
| Uniswap Swaps   | 6413    | 0          | 719.08                | 108.2               | 6.65          | 1,000,004,742 | 9.24                   |
|                 | 6413    | 100us      | 24485                 | 439.89              | 55.66         | 1,000,004,742 | 2.27                   |

*Table 3: Grevm 1.0 Conflict-Free Transaction E2E Total Speedup*

### Contention Transactions

In this gigagas block test, we introduce the concept of a **hot ratio** to simulate contention in transaction workloads. This parameter allows us to model skewed access patterns, where certain accounts or contracts are accessed more frequently than others.

* **Number of User Accounts**: **100,000** accounts used in the test.
* **Hot Ratio**: Defines the probability that a transaction will access one of the hot accounts.
  * **Hot Ratio = 0%**: Simulates a uniform workload where each read/write accesses random accounts.
  * **Hot Ratio > 0%**: Simulates a skewed workload by designating 10% of the total accounts as **hot accounts**. Each read/write operation has a probability equal to the hot ratio of accessing a hot account.

We also introduced a a test set called **Hybrid**, consisting of

* **60% Native Transfers**: Simple Ether transfers between accounts.
* **20% ERC20 Transfers**: Token transfers within three ERC20 token contracts.
* **20% Uniswap Swaps**: Swap transactions within two independent Uniswap pairs.

| Test            | Num Txs | Total Gas     |
| --------------- | ------- | ------------- |
| Raw Transfers   | 47,620  | 1,000,020,000 |
| ERC20 Transfers | 33,628  | 1,161,842,024 |
| Hybrid          | 36,580  | 1,002,841,727 |

*Table 4: Contention Transactions Execution Test Setup*

| Test            | DB Latency | Sequential Execution(ms) | Parallel Execution(ms) | Execution Speedup | Throughput (Gigagas/s) |
| --------------- | ---------- | ------------------------ | ---------------------- | ----------------- | ---------------------- |
| Raw Transfers   | 0          | 207.25                   | 77.05                  | 2.69              | 12.98                  |
|                 | 100us      | 9610.52                  | 217.2                  | 44.29             | 4.6                    |
| ERC20 Transfers | 0          | 316.57                   | 92.63                  | 3.42              | 12.54                  |
|                 | 100us      | 12233.27                 | 263.9                  | 46.38             | 4.4                    |
| Hybrid          | 0          | 295.44                   | 206.71                 | 1.43              | 4.85                   |
|                 | 100us      | 10327.62                 | 1334.9                 | 7.73              | 0.75                   |

*Table 5: Grevm 1.0 Contention Transactions Execution Speedup (hot ratio = 0%)*

| Test            | DB Latency | Sequential Execution(ms) | Parallel Execution(ms) | Execution Speedup | Throughput (Gigagas/s) |
| --------------- | ---------- | ------------------------ | ---------------------- | ----------------- | ---------------------- |
| Raw Transfers   | 0          | 208.05                   | 77.86                  | 2.67              | 12.84                  |
|                 | 100us      | 9632.2                   | 217.31                 | 44.33             | 4.6                    |
| ERC20 Transfers | 0          | 313.59                   | 94.28                  | 3.33              | 12.32                  |
|                 | 100us      | 12289.76                 | 270.19                 | 45.5              | 4.3                    |
| Hybrid          | 0          | 294.52                   | 204.64                 | 1.44              | 4.9                    |
|                 | 100us      | 10333.63                 | 1315.46                | 7.85              | 0.76                   |

*Table 6: Grevm 1.0 Contention Transactions Execution Speedup (hot ratio = 10%)*

| Test            | DB Latency | Sequential Execution(ms) | Parallel Execution(ms) | Execution Speedup | Throughput (Gigagas/s) |
| --------------- | ---------- | ------------------------ | ---------------------- | ----------------- | ---------------------- |
| Raw Transfers   | 0          | 194.95                   | 171.65                 | 1.14              | 5.83                   |
|                 | 100us      | 8879.44                  | 4328.08                | 2.05              | 0.23                   |
| ERC20 Transfers | 0          | 313.48                   | 92.07                  | 3.41              | 12.62                  |
|                 | 100us      | 11434.4                  | 438.03                 | 26.14             | 2.65                   |
| Hybrid          | 0          | 292.63                   | 220.14                 | 1.33              | 4.56                   |
|                 | 100us      | 9742.6                   | 1874.7                 | 5.19              | 0.53                   |

*Table 7: Grevm 1.0 Contention Transactions Execution Speedup (hot ratio = 30%)*

![Speedup v.s. Hot Ratio](/files/1vUbhbtbcpXmhUTdP9zj)

*Figure 4: Hot Ratio v.s. Speedup*

![Speedup v.s. Hot Ratio, Latency=100us](/files/oJMxN7oWXhz41XcdPMoO)

*Figure 5: Hot Ratio v.s. Speedup, Latency=100us*

When the **hot ratio** is **0%**, representing a uniform workload, Grevm 1.0 maintains high levels of parallelism and shows significant performance improvements over sequential execution.

As the hot ratio increases (e.g., **hot ratio ≥ 30%**), we observe a noticeable decrease in parallel execution performance. It is an expected behavior as it is related to a known issue of 1.0 implementation, that it only parallelizes execution between WCC of transaction dependencies. All transactions within a WCC are executed sequentially within the same partition, even if many transactions are actually independent. With a hot ratio of 30%, there's a 51% chance that a transaction will involve a hot account, calculated by `1−(1−0.3)^2=0.51` . With **10%** of accounts (10,000) designated as hot accounts, which is much less than the number of transactions (47620), this results in over half of the transactions being interconnected through shared hot accounts, forming a large partition. Consequently, the execution becomes bottlenecked by an abnormally long tail in one partition, significantly reducing overall parallelism and performance.

This issue will be addressed in the upcoming Grevm 2.0, allowing independent transactions within a WCC to be executed concurrently.

## Future work

### More Detailed Analysis

With the implementation of Grevm 1.0, we can conduct more detailed analyses to further evaluate our future design.

* **Memory Footprint and DoS Vulnerability**: Evaluate the memory usage to identify any potential vulnerabilities to Denial-of-Service attacks due to excessive memory consumption.
* **Re-execution Counts and CPU Utilization**: Compare the number of re-executions and overall CPU usage with other implementations. Grevm is expected to use fewer CPU cycles because of reduced re-executions.
* **Dependency Hint Accuracy**: Collect statistics on dependency hint errors, analyzing false positives and false negatives to understand their impact of parallelism and the number of executions.

### Grevm 2.0

![Grevm 2.0 Arch](/files/jsUds2Eo4vrHmloWhfQb)

*Figure 5: Grevm 2.0*

Grevm 2.0 will address the limitations of version 1.0 by introducing:

* **Finer-Grained Transaction-Level Concurrency**: This enhancement allows transactions with shared dependencies to execute in parallel once those dependencies are finalized. It overcomes the limitation where such transactions were previously executed serially, significantly improving parallelism and resource utilization, especially in high-contention workloads.
* **Fully Asynchronous I/O**: Grevm 2.0 will implement true asynchronous I/O throughout the system—from the underlying database to the multi-version state memory. This eliminates redundant coroutine context switches associated with non-I/O operations in the current implementation, enhancing execution efficiency and reducing latency.

## Authors

<https://github.com/AshinGau>

<https://github.com/nekomoto911>

<https://github.com/stumble>


# Wallets & Exchanges

Wallets and exchanges that support Gravity Mainnet (L1) and the legacy Gravity Alpha Mainnet (L2).

### Wallets

The wallets below work with **Gravity Mainnet (L1, chain ID `127001`)** and the legacy **Gravity Alpha Mainnet (L2, chain ID `1625`)**.

{% hint style="info" %}
**No wallet ships Gravity Mainnet (L1) as a built-in network yet.** Add it as a custom EVM network — the one-click [ChainList entry](https://chainlist.org/chain/127001) does this for you. Some wallets do ship the legacy Alpha Mainnet (L2) built in, which is why L2 may appear in a network list while L1 does not.
{% endhint %}

See \[Gravity Mainnet (L1)]\(../network/l1-mainnet.md) and \[Legacy: Alpha Mainnet (L2)]\(../legacy-l2/network/using-gravity-alpha-mainnet-l2.md) for the canonical connection parameters.

* [MetaMask](https://metamask.io/download/) — add via ChainList: [Gravity L1 (127001)](https://chainlist.org/chain/127001) / [Alpha L2 (1625)](https://chainlist.org/chain/1625)
* [Safe](https://safe.gravity.xyz/welcome?chain=gravity) (deployed by Gravity Team)
* [OKX Web3 Wallet](https://www.okx.com/web3/wallet/gravity-alpha)
* [Trust Wallet](https://trustwallet.com/download) ([add custom network](https://community.trustwallet.com/t/how-to-add-a-custom-network-on-the-trust-wallet-mobile-app/626781))
* [Rainbow](https://rainbow.me/download)
* [MyEtherWallet](https://www.myetherwallet.com/)
* [Zerion](https://zerion.io/download)
* [Gate.io Wallet](https://www.gate.io/web3)
* [Bitget Wallet](https://web3.bitget.com/en/)
* [SafePal](https://www.safepal.com/en/)
* [Keplr](https://www.keplr.app/)

### Exchanges

The following exchanges have supported Gravity Alpha Mainnet.

* OKX
* BitMart
* MEXC
* Bitget
* KuCoin
* Bithumb


# Node Providers

Explore node providers for Gravity, offering scalable and reliable RPC endpoints to streamline on-chain development.

## Overview

**Node providers** offer infrastructure services that allow developers to interact with blockchain networks without the need to run their own nodes. They provide **RPC (Remote Procedure Call) endpoints**, enabling applications to read from and write to blockchains efficiently.

### Public Endpoints

Public endpoints are open-access URLs suitable for development and testing. They may have rate limits and are less reliable for production use.

### Private Endpoints

Private endpoints are secured, subscription-based URLs offering higher reliability, enhanced security, and better performance, ideal for production environments.

## Official Public Endpoints

| Network                           | RPC                               |
| --------------------------------- | --------------------------------- |
| Gravity Mainnet (L1)              | <https://mainnet-rpc.gravity.xyz> |
| Gravity Longevity Testnet (L1)    | <https://testnet-rpc.gravity.xyz> |
| Gravity Alpha Mainnet (legacy L2) | <https://rpc.gravity.xyz>         |
| Gravity Alpha Sepolia (legacy L2) | <https://rpc-sepolia.gravity.xyz> |

These public endpoints are open-access and rate-limited; production workloads should use a private endpoint from one of the providers below or run their own node.

## Node Providers

### QuickNode

QuickNode is a high-performance blockchain infrastructure provider supporting over 68 chains across 115+ networks. It offers fast and reliable RPC endpoints with a 99.99% uptime SLA, making it ideal for developers seeking scalable and dependable access to multiple blockchains.

**Supported Networks**

| Network                           | Public Endpoints | Private Endpoints                                                  |
| --------------------------------- | ---------------- | ------------------------------------------------------------------ |
| Gravity Alpha Mainnet (legacy L2) | TBD              | [Register to get your endpoint](https://auth.quicknode.com/signup) |

***

### Conduit

Conduit specializes in providing infrastructure for deploying and scaling rollups, offering a complete Rollup-as-a-Service platform. It delivers high-performance RPC nodes optimized for throughput and reliability, suitable for teams looking to deploy custom rollups with robust infrastructure support.

**Supported Networks**

| Network                                   | Public Endpoints                  |
| ----------------------------------------- | --------------------------------- |
| Gravity Alpha Mainnet (legacy L2)         | <https://rpc.gravity.xyz>         |
| Gravity Alpha Sepolia Testnet (legacy L2) | <https://rpc-sepolia.gravity.xyz> |

***

### dRPC

dRPC is a fast, reliable, and decentralized RPC infrastructure provider offering access to over 100 blockchain networks across 190+ supported chains. Its NodeCloud platform features AI-powered load balancing, 8 geo-distributed clusters for low-latency global coverage, and built-in MEV front-run protection.

**Supported Networks**

| Network                                   | Public Endpoints                         | Private Endpoints                                       |
| ----------------------------------------- | ---------------------------------------- | ------------------------------------------------------- |
| Gravity Alpha Mainnet (legacy L2)         | <https://gravity-alpha.drpc.org>         | [Register to get your endpoint](https://drpc.org/login) |
| Gravity Alpha Sepolia Testnet (legacy L2) | <https://gravity-alpha-sepolia.drpc.org> | [Register to get your endpoint](https://drpc.org/login) |

***

### ZAN

ZAN is a high-performance Web3 infrastructure provider developed by Ant Group Digital Technologies. It offers stable and fast RPC connections to over 22 popular blockchain networks, including Ethereum, Solana, and Gravity.

**Supported Networks**

| Network                           | Public Endpoints                                     | Private Endpoints                                           |
| --------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
| Gravity Alpha Mainnet (legacy L2) | <https://api.zan.top/public/gravity\\_alpha-mainnet> | [Register to get your endpoint](https://zan.top/sign/login) |

***

### Ankr

Ankr provides decentralized Web3 infrastructure, offering access to over 75 blockchain networks. It features a decentralized node network (DePIN) for low-latency responses and supports services like staking solutions and Supernets creation, catering to developers seeking decentralized and flexible infrastructure options.

**Supported Networks**

| Network                           | Public Endpoints               |
| --------------------------------- | ------------------------------ |
| Gravity Alpha Mainnet (legacy L2) | <https://rpc.ankr.com/gravity> |

{% hint style="info" %}
For Gravity Mainnet (L1, chain ID `127001`) endpoints from these third-party providers, see [Official Public Endpoints](#official-public-endpoints) above. L1 onboarding with each provider is in progress and will be listed in the per-provider tables as it lands.
{% endhint %}

***

### Self-Hosting

For teams requiring complete control over their infrastructure, self-hosting a node is an available option.

* **Gravity Mainnet (L1):** see the [Validator Cluster Deployment Guide](/research-and-development/cluster-deployment) for the L1 node stack (Gravity SDK + Gravity Reth) and topology.
* **Gravity Alpha Mainnet (legacy L2):** see the [legacy L2 Archive Node Setup](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-archive-node) or the [Full Node from Snapshot](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-full-node-from-snapshot) guide.


# Developer Utilities

## Developer Utilities

### CreateX & Create2

CreateX and Create2 are smart contract factories designed to facilitate deterministic deployments across EVM-compatible blockchains. They enable developers to predictably deploy contracts to the same address across different networks, which is essential for multi-chain applications and counterfactual interactions.

* **Deployment Addresses on Gravity**:
  * CreateX: `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed`
  * Create2 Factory: `0x4e59b44847b379578588920cA78FbF26c0B4956C`

These factories support various deployment opcodes, including `CREATE`, `CREATE2`, and `CREATE3`, allowing for flexible and secure contract deployments.

For more information, you can explore the [CreateX GitHub repository](https://github.com/pcaversaccio/createx) and the [Hardhat Ignition documentation](https://hardhat.org/ignition/docs/guides/create2).

***

### Multicall3

Multicall3 is a smart contract that enables batching multiple read-only function calls into a single call. This is particularly useful for applications that need to aggregate data from various contracts.

* **Deployment Address on Gravity**: `0xca11bde05977b3631167028862be2a173976ca11`
* **Functionality**: Batch multiple read-only function calls into a single call to reduce RPC requests.

[Learn More about Multicall3](https://github.com/mds1/multicall)

***

### Succinct SP1

Succinct SP1 is a high-performance, open-source zero-knowledge virtual machine (zkVM) that verifies the execution of arbitrary Rust programs or any LLVM-compiled language. It enables developers to generate zero-knowledge proofs (ZKPs) for smart contract execution, enhancing scalability and privacy.

* **SP1 Verifier Gateway Address**: `0x3B6041173B80E77f038f3F2C0f9744f04837185e`
* **Supported Verifier Routes**:
  * **Groth16 v3.0.0**: `0x95F70a7DE0AeDdb1166343524934D2aaE5609a53`
  * **Plonk v3.0.0**: `0xd2832Cf1fC8bA210FfABF62Db9A8781153131d16`
* **Functionality**: The SP1VerifierGateway automatically routes SP1 proofs to the appropriate verifier for on-chain verification.

[Explore Succinct SP1 Documentation](https://docs.succinct.xyz/docs/sp1/introduction)

***

### Thirdweb

thirdweb is a comprehensive Web3 development platform that empowers developers to build, deploy, and manage decentralized applications (dApps) across over 2,000 EVM-compatible blockchains. It offers a suite of tools, including SDKs, smart contract templates, and infrastructure services, designed to simplify the development process and accelerate time-to-market for Web3 applications.

Supported Tools:

* Contracts
* Connect SDK
* RPC Edge
* Engine
* Universal Bridge
* Nebula

[Explore Gravity on Thirdweb](https://thirdweb.com/gravity-alpha)

***

### Zerion API

Zerion API offers a comprehensive solution for building feature-rich Web3 applications, wallets, and protocols. It provides access to wallets, assets, and chain data across all major blockchains including Gravity.

[Get Started with Zerion API](https://developers.zerion.io/reference/intro/getting-started)


# Explorers

## Overview

Blockchain explorers serve as essential tools for navigating and analyzing blockchain networks. They allow users to search for transactions, view wallet balances, inspect smart contracts, and access various on-chain data.

## Explorers

### Blockscout

Blockscout is an open-source blockchain explorer tailored for EVM-compatible chains. It offers features like transaction tracking, smart contract interaction, and API support. Blockscout provides a user-friendly interface for developers and users alike.

#### Supported Networks

| Network                                   | Link                                                                  |
| ----------------------------------------- | --------------------------------------------------------------------- |
| Gravity Mainnet (L1)                      | [mainnet-explorer.gravity.xyz](https://mainnet-explorer.gravity.xyz/) |
| Gravity Longevity Testnet (L1)            | [explorer-testnet.gravity.xyz](https://explorer-testnet.gravity.xyz/) |
| Gravity Alpha Mainnet (legacy L2)         | [explorer.gravity.xyz](https://explorer.gravity.xyz/)                 |
| Gravity Alpha Sepolia Testnet (legacy L2) | [explorer-sepolia.gravity.xyz](https://explorer-sepolia.gravity.xyz/) |

***

### OKLink

OKLink is a comprehensive multi-chain explorer and Web3 analytics platform. It supports over 60 blockchains, offering real-time data, contract verification, and extensive API services. OKLink is designed for both casual users and developers seeking in-depth blockchain insights.

#### Supported Networks

| Network                           | Link                                   |
| --------------------------------- | -------------------------------------- |
| Gravity Alpha Mainnet (legacy L2) | <https://www.oklink.com/gravity-alpha> |

***

### NFTScan

NFTScan is a leading multi-chain NFT data infrastructure platform that supports over 25 blockchain networks, including Gravity. It offers comprehensive NFT data indexing, real-time analytics, and developer-friendly APIs. Users can explore NFT collections, track transactions, and access detailed asset information.

#### Supported Networks

| Network                           | Link                                                |
| --------------------------------- | --------------------------------------------------- |
| Gravity Alpha Mainnet (legacy L2) | [gravity.nftscan.com](https://gravity.nftscan.com/) |


# Cross-chain Interoperability

## Overview

Cross-chain interoperability is fundamental to Gravity's mission of enabling seamless asset transfers across diverse blockchain networks. Gravity ships with an official canonical bridge for Ethereum → Gravity L1, and a range of third-party protocols extend G's reach across the multi-chain landscape.

{% hint style="warning" %}
**Bridge support during the L1 transition:**

* **Gravity Mainnet (L1):** only the **Gravity Native Bridge** (below) supports L1 today. L1 support for the other bridges is being migrated.
* **Gravity Alpha Mainnet (L2):** all the third-party bridges on this page currently bridge to L2.
  {% endhint %}

## Gravity Native Bridge (canonical)

Gravity's canonical bridge for **Ethereum → Gravity L1** asset flow is built on the [Native Oracle](/research-and-development/native-oracle) primitive: the same validators that produce blocks under AptosBFT observe `GravityPortal.MessageSent` events on Ethereum (past Ethereum finality), attest them through the consensus layer, and the on-chain commit triggers the `NativeMintPrecompile` to mint native G to the recipient. No external relayer, no wrapped-asset trust assumption layered on top of consensus.

| Chain      | Contract               | Address                                               |
| ---------- | ---------------------- | ----------------------------------------------------- |
| Ethereum   | `GravityPortal`        | `0x76cf8526Fa9461e50B2c6702a7246ce6915f6E53`          |
| Ethereum   | `GBridgeSender`        | `0xE82c61Ac9Ec2041b493118051afa4F18a55dC876`          |
| Gravity L1 | `NativeOracle`         | `0x00000000000000000000000000000001625F4000` (system) |
| Gravity L1 | `NativeMintPrecompile` | `0x00000000000000000000000000000001625F5000` (system) |

At launch the bridge is one-way (Ethereum → Gravity L1); the reverse path (burn on Gravity, release on Ethereum) is on the roadmap. For the architecture, end-to-end flow, and reliability semantics, see [Native Oracle](/research-and-development/native-oracle). For the end-user bridging UI, see [How to Get G](/the-g-token/how-to-get-g).

***

## Third-Party Bridges

The third-party protocols below extend G's reach across the multi-chain landscape — chains other than Ethereum, alternative liquidity routes, and intent-based aggregators.

{% hint style="danger" %}
**These integrations still deliver to the legacy Alpha Mainnet (L2), not to Gravity Mainnet (L1).** The L2 is being deprecated — do not bridge new funds into it, and move any existing L2 assets back to Ethereum before **November 1, 2026** (see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum)).

To get G on **Gravity Mainnet (L1)**, use the official bridge — see [How to Get G](/the-g-token/how-to-get-g). L1 support for the routes below is being migrated; until then, "Gravity" in each description below means the L2.
{% endhint %}

### LayerZero & Stargate

LayerZero is a cross-chain communication protocol that enables interoperability between different blockchain networks. Built atop LayerZero, Stargate is a liquidity transport protocol facilitating native asset transfers across chains. It enables users to bridge assets such as USDC from core chains to Gravity, where the assets are minted as Omnichain Fungible Tokens (OFTs). These OFTs can be redeemed back to their native form on any core Stargate chain, ensuring flexibility and composability across the network.

[Explore Gravity on Stargate](https://stargate.finance/bridge?srcChain=gravity)

***

### Symbiosis Finance

Symbiosis Finance is a decentralized cross-chain liquidity protocol that enables seamless token swaps across multiple blockchains, including both EVM and non-EVM networks. It aggregates liquidity from various networks, allowing users to swap tokens and move assets across different chains effortlessly.

[Explore Symbiosis Zap](https://app.symbiosis.finance/zap)

***

### Celer Network

Celer Network is a blockchain interoperability protocol that enables seamless cross-chain communication and asset transfers across multiple blockchain networks. Through its products like cBridge and the Inter-chain Messaging (IM) Framework, Celer facilitates fast, secure, and low-cost token transfers and generic message passing between chains. Celer now supports Gravity and allows users to bridge the native G token between Gravity, Ethereum, and BNB Chain.

[Explore cBridge for Gravity](https://cbridge.celer.network/)

***

### Orbiter Finance

Orbiter Finance is a decentralized cross-rollup bridge that facilitates fast, low-cost, and secure asset transfers across various blockchain networks, including Ethereum Layer 2 solutions like Arbitrum, Optimism, zkSync, and Gravity. By leveraging zero-knowledge proof (ZK) technology, Orbiter ensures trustless transactions without relying on centralized liquidity pools.

[Explore Orbiter Finance](https://orbiter.finance/)

***

### Owlto Finance

Owlto Finance is an intent-centric interoperability protocol designed to facilitate seamless cross-chain asset transfers across a wide range of blockchain networks. With support for over 40 networks including Gravity, Owlto enables users to bridge assets quickly and cost-effectively.

[Explore Owlto Finance](https://owlto.finance/)

***

### Rubic Exchange

Rubic is a decentralized cross-chain aggregator that enables seamless token swaps across over 100 blockchain networks including Gravity. By integrating more than 360 decentralized exchanges (DEXs), bridges, and intent-based protocols, Rubic offers users access to over 15,500 tokens with optimal rates and high liquidity.

[Explore Rubic Exchange](https://rubic.exchange/)

***

### Relay

Relay Protocol is a cross-chain payments system that enables instant, low-cost bridging and cross-chain execution. By connecting users with relayers—financial agents who act on users’ behalf across chains—Relay facilitates rapid and cost-effective transactions. This design minimizes gas costs and execution latency, making it ideal for applications such as payments, bridging, NFT minting, and gas abstraction.

[Explore Relay Protocol](https://www.relay.link/bridge)

***

### oooo Protocol

oooo Protocol is a modular omnichain interoperability protocol designed to enhance the Bitcoin ecosystem by enabling seamless asset circulation between Bitcoin and other public blockchains. It supports various BTC-native assets, including BTC and inscription assets, facilitating secure, rapid, and cost-effective transfers across the Bitcoin mainnet and its Layer 2 solutions. oooo has integrated with over 30 ecosystems, including Ethereum, BNB Chain, Polygon, and Gravity to provide users with a comprehensive cross-chain experience.

[Explore oooo Protocol](https://oooo.money/)

***

### Comet Bridge

Comet Bridge is a cross-chain interoperability protocol that facilitates seamless asset transfers and communication between major blockchain ecosystems, including Ethereum, Bitcoin, and various Layer 1 networks like Gravity. It offers features such as InstantGas, enabling users to acquire native gas tokens across different chains efficiently.

[Explore Comet Bridge](https://cometbridge.app/)

***

#### RetroBridge

RetroBridge is a cross-chain bridging solution designed to simplify asset transfers across multiple blockchain networks. By utilizing concentrated liquidity pools and bypassing traditional smart contracts, RetroBridge offers faster and more cost-effective transactions.

[Explore RetroBridge](https://retrobridge.io/)


# Onramps

Explore reliable fiat-to-crypto onramps that connect users from traditional payment methods directly to Gravity, enabling smooth and secure blockchain access.

## **Overview**

Fiat onramps are essential gateways that allow users to purchase cryptocurrencies using traditional payment methods like credit cards, bank transfers, and e-wallets. They simplify Web3 access by bridging the gap between fiat currencies and crypto assets.

## **Onramps**

### Onramp.money

Onramp.money is a secure crypto onramp platform that enables users to buy, sell, and swap over 400 tokens across multiple blockchains including Gravity. Users can purchase cryptocurrencies using local payment methods, including bank transfers and mobile wallets, across more than 30 countries.

[Buy G on Onramp.money](https://onramp.money/)

***

### Alchemy Pay

Alchemy Pay is a global payment gateway that bridges fiat and crypto economies, supporting payments in 173 countries. It enables users to purchase cryptocurrencies using Visa, Mastercard, Apple Pay, Google Pay, regional mobile wallets, and domestic bank transfers. Alchemy Pay also offers off-ramping capabilities, allowing users to convert crypto back to fiat currencies.

[Buy G on Alchemy Pay](https://alchemypay.org/)


# Smart Contract Wallets

## Overview

Smart contract wallets are blockchain-based applications that manage digital assets through programmable smart contracts. Unlike traditional wallets, they offer enhanced functionalities like multi-signature approvals, customizable access controls, and automated transaction processes. These features provide users with increased security, flexibility, and control over their assets.

## Smart Contract Wallets

### Safe

Safe Wallet is a leading smart contract wallet offering advanced security features such as multi-signature authorization, transaction simulation, and account recovery. It provides users with secure and customizable asset management solutions.

[Get Started with Safe on Gravity](https://safe.gravity.xyz/welcome?chain=gravity) — hosted UI for Gravity Alpha L2 (`?chain=gravity`) and Gravity Mainnet L1 (`?chain=grav`).

Canonical Safe v1.4.1 contracts are deployed on:

* [Gravity Mainnet (L1)](/developer-resources/deployed-contracts#safe-wallet-smart-account-suite-v1-4-1)
* [Longevity Testnet (L1)](/developer-resources/deployed-contracts-testnet#safe-wallet-smart-account-suite-v1-4-1) — contracts live; create/execute via SDK or Foundry (testnet is not yet in the hosted UI)

When creating a Safe on Gravity, use the **SafeL2** singleton (`0x29fcB43b46531BcA003ddC8FCB67FFE91900C762`).


# Data Analytics Platforms

## Overview

Data analytics platforms are essential tools that provide insights into blockchain activities, enabling developers, investors, and users to make informed decisions. For the Gravity network, several platforms offer comprehensive analytics, tracking metrics such as Total Value Locked (TVL), decentralized application (dApp) performance, user engagement, and more.

## Data Analytics Platforms

### DappRadar

DappRadar is a leading dApp discovery and analytics platform that tracks user activity, volume, and rankings across multiple blockchains, including Gravity. It provides insights into decentralized applications, Non-Fungible Tokens (NFTs), and DeFi projects, helping users explore and analyze the Gravity ecosystem.

[Explore Gravity on DappRadar](https://dappradar.com/chain/gravity)

***

### DefiLlama

DefiLlama is an open-source DeFi analytics platform providing TVL data, protocol metrics, and fee tracking for Gravity and other chains. It offers transparent and accurate data without ads or sponsored content, making it a reliable source for DeFi analytics.

[Explore Gravity on DefiLlama](https://defillama.com/chain/gravity-by-galxe)

***

### Footprint Analytics

Footprint Analytics is a comprehensive blockchain data platform offering customizable dashboards, multi-chain data analysis, and AI-driven insights, with dedicated support for Gravity. It simplifies complex data analysis, enabling users to visualize and understand on-chain activities effectively.

[Explore Gravity on Footprint Analytics](https://www.footprint.network/@Higi/Gravity-Overview?chain=Gravity)

***

### L2BEAT

L2BEAT is an analytics and research platform focused on Ethereum Layer 2 scaling solutions. It provides in-depth comparisons of major protocols live on Ethereum, including Gravity, offering insights into their design, security, and performance.

[Explore Gravity on L2BEAT](https://l2beat.com/scaling/projects/galxegravity)

***

### Messari

Messari is a crypto market intelligence platform that provides data insights, research, and news on various blockchain projects. It offers comprehensive information on Gravity's G token, including market data, governance, and project updates.

[Explore G Token on Messari](https://messari.io/project/g-token)

***

### Nansen

Nansen is a blockchain analytics platform that combines on-chain data with a massive and growing database of wallet labels. It provides insights into the Gravity blockchain, helping users track transactions, identify trends, and make informed decisions.

[Explore Gravity on Nansen](https://app.nansen.ai/macro/blockchains?chain=gravity)

***

### Chainlyze

Chainlyze is a platform designed to identify and monitor smart money flows, uncover new trade opportunities, and trace transaction histories. It offers real-time on-chain intelligence services, supporting the Gravity blockchain.

[Explore Gravity on Chainlyze](https://app.chainlyze.ai/)

***

### Growthepie

Growthepie provides comprehensive data and insights across Ethereum Layer 1 and Layer 2 networks. It allows users to visualize usage, economics, and growth of the Gravity ecosystem through interactive dashboards.

[Explore Gravity on Growthepie](https://www.growthepie.xyz/chains/gravity)

***

### Token Terminal

Token Terminal is a crypto analytics platform that measures and evaluates blockchains and dApps through traditional financial metrics. It offers detailed dashboards for Gravity, enabling users to analyze revenue, user activity, and other key performance indicators.

[Explore Gravity on Token Terminal](https://tokenterminal.com/explorer/studio/dashboards/904b9b42-f751-44ba-b11a-9e55166ec137)

***

### Chainspect

Chainspect provides real-time data on blockchain performance metrics such as transactions per second (TPS), block time, and finality. It offers detailed analytics for Gravity, helping users monitor network efficiency and scalability.

[Explore Gravity on Chainspect](https://chainspect.app/chain/gravity)

***

### DeBank

DeBank is a comprehensive Web3 portfolio tracker that allows users to monitor their token assets, DeFi positions, and NFT holdings across multiple blockchains, including Gravity. It provides real-time data on wallet balances, transaction history, and protocol interactions, offering a holistic view of user assets within the Gravity ecosystem.

[Explore Gravity on DeBank](https://debank.com/)


# Overview

Reference material for Gravity Alpha Mainnet (L2) — the 2024 Arbitrum Nitro rollup that preceded Gravity L1.

{% hint style="danger" %}
**Action required — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) users should move **all** assets back to Ethereum before **November 1, 2026**. See [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

Gravity launched in 2024 as **Gravity Alpha Mainnet**, an Ethereum rollup built on the Arbitrum Nitro stack with chain ID `1625`. Alpha Mainnet is still operational, but new development should target [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) (chain ID `127001`), which is the canonical production chain.

The pages in this section preserve the original L2 documentation:

* **Network references** — Alpha Mainnet & Alpha Sepolia Testnet network parameters and node-setup guides.
* **Bridging on L2** — how to bridge G, DAI, and WBTC to/from Alpha Mainnet through the native canonical bridge and LI.FI.
* **L2 token contracts** — ERC-20 addresses for G, wG, WBTC, DAI, USDT, USDC on Alpha Mainnet.
* **L2 system contracts** — rollup, inbox, outbox, sequencer, and gateway addresses.
* **Verify a Smart Contract (L2)** — Blockscout verification flow for contracts deployed on Alpha Mainnet.

## Migrating to L1

Holders of G on Alpha Mainnet can move to L1 by first withdrawing G as ERC-20 back to Ethereum through the [L2 canonical bridge](/legacy-alpha-mainnet-l2/bridge-to-gravity), then bridging from Ethereum to L1 — see [How to Get G](/the-g-token/how-to-get-g) for the L1 side of the flow.


# Alpha Mainnet & Sepolia Testnet (L2)

Gravity Alpha Mainnet & Sepolia Testnet Information

{% hint style="danger" %}
**Action required — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) users should move **all** assets back to Ethereum before **November 1, 2026**. See [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

**Gravity Mainnet (L1)** is now live and is the canonical production chain — see [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet). This page documents the legacy **Gravity Alpha Mainnet (L2)**, an Ethereum rollup using the Arbitrum Nitro stack that preceded it and remains operational.

Gravity Alpha Mainnet can be added as a custom network to any EVM-compatible wallet (i.e. MetaMask).

## Network

### Gravity Alpha Mainnet

[*Add Gravity Alpha Mainnet to Metamask*](https://chainlist.org/chain/1625)

* Chain ID: 1625, `0x659`
* Currency Symbol / Native Token: `G`
* RPC Endpoint: [https://rpc.gravity.xyz](https://rpc.gravity.xyz/)
* Canonical Bridge: <https://bridge.gravity.xyz>
* Block Explorer:
  * [OKX Explorer](https://web3.okx.com/explorer/gravity-alpha)
  * [OKLink](https://www.oklink.com/gravity-alpha)
  * [Blockscout](https://explorer.gravity.xyz)
* Logo: <https://assets.gravity.xyz/chain_logo.png>, or [visit this link](https://gal.xyz/brand) for different versions

### Gravity Alpha Testnet Sepolia

{% hint style="info" %}
Gravity Alpha Testnet Sepolia was reset (pruned the state and started over with block height 0) on March 24th 2025 for testing Celestia DA.
{% endhint %}

[*Add Gravity Alpha Testnet Sepolia to Metamask*](https://chainlist.org/chain/13505)

* Chain ID: 13505, `0x34c1`
* Currency Symbol / Native Token: `G`
* RPC Endpoint: <https://rpc-sepolia.gravity.xyz>
* Canonical Bridge: [https://bridge-sepolia.gravity.xyz](https://bridge-sepolia.gravity.xyz/)
* Block Explorer: <https://explorer-sepolia.gravity.xyz>
* Logo: <https://assets.gravity.xyz/chain_logo.png>, or [visit this link](https://gal.xyz/brand) for different versions

## Chain Parameters

| Param                | Description                                                                                               | G Alpha Mainnet             | G Sepolia Testnet          |
| -------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------- |
| Dispute window       | Time for assertions to get confirmed during which validators can issue a challenge                        | 45818 blocks (\~ 6.4 days ) | 20 blocks (\~ 4.0 minutes) |
| Force-include period | Period after which a delayed message can be included into the inbox without any action from the Sequencer | 5760 blocks / 24 hours      | 5760 blocks / 24 hours     |
| Gas speed limit      | Target gas/sec, over which the congestion mechanism activates                                             | 20,000,000 gas/sec          | 7,000,000 gas/sec          |
| Gas price floor      | Minimum gas price                                                                                         | 1800 gwei                   | 0.1 gwei                   |
| Block gas limit      | Maximum amount of gas that all the transactions inside a block are allowed to consume                     | 32,000,000                  | 32,000,000                 |

NOTE: The parameters, including gas price and gas fee, will take effect at 12:00 PM on August 20, 2024, PDT. Until that time, the chain will operate using experimental parameters for internal testing purposes.\
NOTE: We lowered the gas price floor from 3600 gwei to 1800 gwei, effective from 12:00 PM on August 22, 2024, PDT.


# Alpha Mainnet (L2) Archive Node Setup

Run a Gravity Alpha Mainnet (L2) archive node with full historical state for eth\_call, debug\_traceTransaction, and trace APIs against any block.

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

## ArbOS 51 (Dia) Upgrade Notice

Gravity Alpha Mainnet has been upgraded to ArbOS 51 (Dia). This upgrade brings important improvements from the Ethereum Fusaka upgrade and more.

### What's Included

* Features from the ArbOS 40 (Callisto) upgrade
* Unlocks the path to Permissionless Fault Proofs in the future with the new BoLD dispute protocol
* Unlocks the path to enabling Native Token Mint/Burn capabilities
* EIP-7825 — Transaction gas limit cap for more efficient gas usage
* Precompile and opcode changes that make cryptographic operations cheaper and more efficient in the EVM

For a full breakdown, see the [ArbOS 51 upgrade notice](https://docs.arbitrum.io/run-a-node/arbos-releases/arbos51).

### Required Actions for Existing Node Operators

**No action required** if you are not running external nodes.

If you are running external nodes, you need to:

1. Upgrade your Nitro node to **at least v3.9.3**, but **v3.9.5** ([release link](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.5)) is recommended.
2. Make sure the flag `--node.staker.enable=false` is configured on your node.

If you have already downloaded a snapshot previously, you only need to upgrade the node version — simply update the Docker image to `offchainlabs/nitro-node:v3.9.5-66e42c4` and restart.

### Key Changes from Previous Version

* **Docker image**: `ghcr.io/celestiaorg/nitro:v3.6.8` → `offchainlabs/nitro-node:v3.9.5-66e42c4`
* **Celestia DAS server is no longer required** — DA is now handled via the REST aggregator
* **HTTP API**: Added `trace` and `debug` endpoints
* **New flags**:
  * `--node.data-availability.enable=true`
  * `--node.data-availability.rest-aggregator.enable=true`
  * `--node.data-availability.rest-aggregator.urls=https://das-gravity-mainnet-0.t.conduit.xyz`
  * `--execution.caching.archive=true`
  * `--node.staker.enable=false`
* **Removed flags**:
  * `--node.data-availability.enable=false`
  * `--node.da-provider.enable=true`
  * `--node.da-provider.rpc.url=<CELESTIA_DAS_URL>`

***

## Archive Node Setup Guide

This guide sets up an **archive node** — it retains the full historical state trie so you can run `eth_call`, `debug_traceTransaction`, and `trace_*` RPCs against any block height. If you only need to follow the chain tip and don't require historical state access, use the lighter [Alpha Mainnet (L2) Full Node from Snapshot](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-full-node-from-snapshot) guide instead.

### Prerequisites

1. A local directory for storing node data
2. An Ethereum mainnet RPC endpoint with unlimited rate limit for eth\_getLogs
3. An Ethereum beacon chain RPC endpoint

### Download Snapshot (Required)

Downloading the latest snapshot is **required** before running the node. Due to historical data availability format changes, syncing from genesis without a snapshot is not supported.

1. [Download Gravity L2 Node Snapshot](https://storage.googleapis.com/conduit-networks-snapshots/gravity-mainnet-0/latest.tar)
2. Extract the snapshot to your local directory before running the node.

If you have already downloaded a snapshot previously, there is no need to download it again.

#### Health Check

After your node is running, verify that it has successfully synced past the historical Celestia DA batches by checking the latest block number:

```bash
curl -s -X POST http://localhost:8547 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
  | python3 -c "import sys,json; r=int(json.load(sys.stdin)['result'],16); print(f'Block: {r:,}'); print('Status: HEALTHY - past Celestia DA batches' if r > 119700000 else 'Status: STUCK - node has not passed Celestia DA batch 65604, re-download the snapshot')"
```

If the output shows `STUCK`, your node is unable to process historical Celestia-format batches. You need to re-download the latest snapshot and restart.

### Running the Node

Save the following script as `run-gravity-node.sh`, make it executable with `chmod +x run-gravity-node.sh`, and update the TODO variables:

{% code overflow="wrap" %}

```bash
#!/bin/bash

# Define dependent variables
LOCAL_DIR="TODO"                # Replace with your local directory path
ETH_MAINNET_RPC="TODO"          # Replace with your Ethereum mainnet RPC endpoint
ETH_BEACON_RPC="TODO"           # Replace with your Ethereum beacon chain RPC endpoint

# mkdir ${LOCAL_DIR}
# sudo chmod -R a+rwx ${LOCAL_DIR}

# Run the Docker container
docker run --rm -it -d \
    --add-host=host.docker.internal:host-gateway \
    -v "$LOCAL_DIR:/home/user/.arbitrum" \
    -p 0.0.0.0:8547:8547 \
    -p 0.0.0.0:8548:8548 \
    offchainlabs/nitro-node:v3.9.5-66e42c4 \
    --parent-chain.connection.url="$ETH_MAINNET_RPC" \
    --chain.id=1625 \
    --chain.name=conduit-orbit-deployer \
    --http.api=net,web3,eth,trace,debug \
    --http.corsdomain="*" \
    --http.addr=0.0.0.0 \
    --http.vhosts="*" \
    --chain.info-json='[
        {
            "chain-id": 1625,
            "parent-chain-id": 1,
            "chain-name": "conduit-orbit-deployer",
            "chain-config": {
                "chainId": 1625,
                "homesteadBlock": 0,
                "daoForkBlock": null,
                "daoForkSupport": true,
                "eip150Block": 0,
                "eip150Hash": 
                "0x0000000000000000000000000000000000000000000000000000000000000000",
                "eip155Block": 0,
                "eip158Block": 0,
                "byzantiumBlock": 0,
                "constantinopleBlock": 0,
                "petersburgBlock": 0,
                "istanbulBlock": 0,
                "muirGlacierBlock": 0,
                "berlinBlock": 0,
                "londonBlock": 0,
                "clique": {
                    "period": 0,
                    "epoch": 0
                },
                "arbitrum": {
                    "EnableArbOS": true,
                    "AllowDebugPrecompiles": false,
                    "DataAvailabilityCommittee": true,
                    "InitialArbOSVersion": 11,
                    "InitialChainOwner": "0xd65776c5F9fA552cB5C9556B3e86bF6c376b233b",
                    "GenesisBlockNum": 0
                }
            },
            "rollup": {
                "bridge": "0x7983403dDA368AA7d67145a9b81c5c517F364c42",
                "inbox": "0x7AD2a94BefF3294a31894cFb5ba4206957a53c19",
                "sequencer-inbox": "0x8D99372612e8cFE7163B1a453831Bc40eAeb3cF3",
                "rollup": "0x2807B1d5d94ca823ca7d8642A5F5DDac120ce48f",
                "validator-utils": "0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF",
                "validator-wallet-creator": "0x9CAd81628aB7D8e239F1A5B497313341578c5F71",
                "deployed-at": 19898364
            }
        }
    ]' \
    --execution.forwarding-target="https://rpc.gravity.xyz" \
    --node.feed.input.url="wss://relay-gravity-mainnet-0.t.conduit.xyz" \
    --parent-chain.blob-client.beacon-url="$ETH_BEACON_RPC" \
    --node.data-availability.enable=true \
    --node.data-availability.rest-aggregator.enable=true \
    --node.data-availability.rest-aggregator.urls=https://das-gravity-mainnet-0.t.conduit.xyz \
    --execution.caching.archive=true \
    --node.staker.enable=false
```

{% endcode %}

### Additional Information

* The chain info is obtained from Conduit:&#x20;

```bash
curl https://api.conduit.xyz/file/v1/arbitrum/chaininfo/gravity-mainnet-0
```

* Relay endpoint is provided by Conduit as `wss://relay-gravity-mainnet-0.t.conduit.xyz`
* Gravity Alpha Mainnet uses Anytrust DA, with aggregator URL: `https://das-gravity-mainnet-0.t.conduit.xyz`

### References

For more information, please check out the following guides:

1. <https://docs.arbitrum.io/node-running/how-tos/running-an-orbit-node>
2. <https://docs.conduit.xyz/guides/run-a-node/arbitrum-node>


# Alpha Mainnet (L2) Full Node from Snapshot

Bootstrap a Gravity Alpha Mainnet (L2) full node by downloading a public GCS chaindata snapshot and starting nitro in non-archive mode.

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

This guide is for operators who want to run a **full node** (non-archive) against Gravity Alpha Mainnet (L2) and would like to skip the multi-day catch-up from the Conduit snapshot. It walks through downloading a public Google Cloud Storage (GCS) snapshot of the chaindata and starting nitro in full-node mode.

If you instead want an archive node — required for full historical `eth_call` / `debug_traceTransaction` against old blocks — follow [Alpha Mainnet (L2) Archive Node Setup](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-archive-node) instead. The two flows share the same image, chain config, parent-chain URLs, DA committee URL, feed URL, and forwarder; only the snapshot source and a couple of `--execution.caching` flags differ.

## Snapshot

A public, anonymously-readable snapshot of the Gravity Alpha Mainnet (L2) chaindata is hosted on Google Cloud Storage.

| Property                   | Value                                                                                                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| GCS bucket path            | `gs://gravity-public-bucket/nitro-data-20260526/`                                                                                                                        |
| Anonymous HTTPS listing    | [`https://storage.googleapis.com/gravity-public-bucket/?prefix=nitro-data-20260526/`](https://storage.googleapis.com/gravity-public-bucket/?prefix=nitro-data-20260526/) |
| Anonymous file URL pattern | `https://storage.googleapis.com/gravity-public-bucket/nitro-data-20260526/<path>`                                                                                        |
| Total size                 | \~350 GB across 4,803 objects                                                                                                                                            |
| Contents                   | `conduit-orbit-deployer/nitro/` chaindata only — no logs, no keys, no `jwtsecret`                                                                                        |
| Snapshot label / date      | `20260526` (snapshot taken 2026-05-26)                                                                                                                                   |

The bucket is publicly readable. **No Google account is required**, and the snapshot is reachable from `gcloud storage`, `gsutil`, plain `curl`/`wget`, or any S3/GCS-compatible mirror tool.

## Prerequisites

1. A local directory with at least \~400 GB of free space for the chaindata (the snapshot is \~350 GB before nitro's pebble overhead).
2. An Ethereum mainnet RPC endpoint with unlimited rate limit for `eth_getLogs`.
3. An Ethereum beacon chain RPC endpoint.

## Step 1 — Download the snapshot

Pick whichever transfer tool you already have. The `gcloud storage` client is recommended because it parallelises transfers and is resumable; plain `wget` works if you don't want to install `gcloud`.

### Option A — `gcloud storage` (recommended)

```bash
# Install: https://cloud.google.com/sdk/docs/install
# No authentication required for this bucket.
gcloud storage rsync --recursive \
    gs://gravity-public-bucket/nitro-data-20260526/ \
    /path/to/your/datadir/
```

`rsync` is idempotent and safe to re-run if the transfer is interrupted.

### Option B — `gsutil`

```bash
gsutil -m rsync -r \
    gs://gravity-public-bucket/nitro-data-20260526/ \
    /path/to/your/datadir/
```

### Option C — plain HTTPS with `wget`

Anonymous HTTPS works for every object. List the bucket via the XML listing URL, then `wget` each key. Example one-liner using `curl` + `xmllint` to enumerate keys:

```bash
LIST_URL="https://storage.googleapis.com/gravity-public-bucket/?prefix=nitro-data-20260526/"
DEST=/path/to/your/datadir

# Fetch the first page; for full traversal you must also follow <NextMarker> pages.
curl -s "$LIST_URL" \
    | xmllint --xpath '//*[local-name()="Key"]/text()' - \
    | tr ' ' '\n' \
    | while read key; do
        rel="${key#nitro-data-20260526/}"
        mkdir -p "$DEST/$(dirname "$rel")"
        wget -c -O "$DEST/$rel" \
            "https://storage.googleapis.com/gravity-public-bucket/$key"
      done
```

`gcloud storage` is strongly preferred over this loop — it handles pagination, retries, and parallelism for you.

## Step 2 — Post-rsync fixups

Two things need to be fixed up after the rsync, both because `gcloud storage rsync` does not carry over filesystem metadata that nitro relies on.

### Recreate the `geth/chaindata` symlink

The source filesystem has `conduit-orbit-deployer/nitro/geth/chaindata` as a symlink pointing to `../l2chaindata`. `gcloud storage` does not preserve symbolic links and skips otherwise-empty directories, so after the rsync both the symlink and the `geth/` directory that holds it are missing. Recreate both:

```bash
DATADIR=/path/to/your/datadir
cd "$DATADIR/conduit-orbit-deployer/nitro"
mkdir -p geth
cd geth
ln -s ../l2chaindata chaindata
```

### Match the in-container uid

The `offchainlabs/nitro-node` image runs as the in-image user `user` (uid 1000). The rsync wrote the snapshot as the operator's uid, so unless that uid happens to be 1000 the container will exit within a second of launch with `Failed to prepare jwt secret file ... permission denied` when it tries to create `jwtsecret` and `nodekey` under the mounted volume. Match the owning uid:

```bash
sudo chown -R 1000:1000 "$DATADIR"
```

Alternatively, add `--user $(id -u):$(id -g)` to the `docker run` in Step 3 so the container runs as your operator uid instead.

No other fixups are needed — the snapshot does not include `nodekey`, `jwtsecret`, or pebble log files, so nitro will generate them on first start.

## Step 3 — Run the full node

Save the following as `run-gravity-fullnode.sh`, make it executable with `chmod +x run-gravity-fullnode.sh`, and update the TODO variables. The image, chain config, DA committee, and feed are identical to the archive-mode setup.

{% code overflow="wrap" %}

```bash
#!/bin/bash

# Define dependent variables
LOCAL_DIR="TODO"                # Replace with your local directory path (the one you rsynced the snapshot into)
ETH_MAINNET_RPC="TODO"          # Replace with your Ethereum mainnet RPC endpoint
ETH_BEACON_RPC="TODO"           # Replace with your Ethereum beacon chain RPC endpoint
# Also fill in <YOUR_GRAVITY_ALPHA_MAINNET_RPC> below — the upstream Gravity L2 RPC
# to which write transactions submitted to this node are forwarded.

# Run the Docker container
docker run --rm -it -d \
    --add-host=host.docker.internal:host-gateway \
    --name gravity-fullnode \
    -v "$LOCAL_DIR:/home/user/.arbitrum" \
    -p 0.0.0.0:8547:8547 \
    -p 0.0.0.0:8548:8548 \
    offchainlabs/nitro-node:v3.9.5-66e42c4 \
    --parent-chain.connection.url="$ETH_MAINNET_RPC" \
    --chain.id=1625 \
    --chain.name=conduit-orbit-deployer \
    --http.api=net,web3,eth,debug,arb \
    --http.corsdomain="*" \
    --http.addr=0.0.0.0 \
    --http.vhosts="*" \
    --chain.info-json='[
        {
            "chain-id": 1625,
            "parent-chain-id": 1,
            "chain-name": "conduit-orbit-deployer",
            "chain-config": {
                "chainId": 1625,
                "homesteadBlock": 0,
                "daoForkBlock": null,
                "daoForkSupport": true,
                "eip150Block": 0,
                "eip150Hash": 
                "0x0000000000000000000000000000000000000000000000000000000000000000",
                "eip155Block": 0,
                "eip158Block": 0,
                "byzantiumBlock": 0,
                "constantinopleBlock": 0,
                "petersburgBlock": 0,
                "istanbulBlock": 0,
                "muirGlacierBlock": 0,
                "berlinBlock": 0,
                "londonBlock": 0,
                "clique": {
                    "period": 0,
                    "epoch": 0
                },
                "arbitrum": {
                    "EnableArbOS": true,
                    "AllowDebugPrecompiles": false,
                    "DataAvailabilityCommittee": true,
                    "InitialArbOSVersion": 11,
                    "InitialChainOwner": "0xd65776c5F9fA552cB5C9556B3e86bF6c376b233b",
                    "GenesisBlockNum": 0
                }
            },
            "rollup": {
                "bridge": "0x7983403dDA368AA7d67145a9b81c5c517F364c42",
                "inbox": "0x7AD2a94BefF3294a31894cFb5ba4206957a53c19",
                "sequencer-inbox": "0x8D99372612e8cFE7163B1a453831Bc40eAeb3cF3",
                "rollup": "0x2807B1d5d94ca823ca7d8642A5F5DDac120ce48f",
                "validator-utils": "0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF",
                "validator-wallet-creator": "0x9CAd81628aB7D8e239F1A5B497313341578c5F71",
                "deployed-at": 19898364
            }
        }
    ]' \
    --execution.forwarding-target="<YOUR_GRAVITY_ALPHA_MAINNET_RPC>" \
    --node.feed.input.url="wss://relay-gravity-mainnet-0.t.conduit.xyz" \
    --parent-chain.blob-client.beacon-url="$ETH_BEACON_RPC" \
    --node.data-availability.enable=true \
    --node.data-availability.rest-aggregator.enable=true \
    --node.data-availability.rest-aggregator.urls=https://das-gravity-mainnet-0.t.conduit.xyz \
    --node.staker.enable=false
```

{% endcode %}

### What's different from the archive-mode script

Compared to the archive-mode setup in [Alpha Mainnet (L2) Archive Node Setup](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-archive-node), this command:

* **Removes** `--execution.caching.archive=true` — full nodes only retain recent state.
* **Omits** `--execution.rpc.max-recreate-state-depth=-1` — that flag is only meaningful in archive mode for unlimited historical state recreation.
* Leaves `--execution.rpc.gas-cap=0` off; you may add it back if you want to lift the default RPC gas cap.
* Replace `<YOUR_GRAVITY_ALPHA_MAINNET_RPC>` with whatever upstream RPC you want write transactions forwarded to — the public `https://rpc.gravity.xyz` works (this is what the archive-mode setup hardcodes), or any other Gravity Alpha Mainnet (L2) RPC you operate. This flag is only consulted for outbound write transactions; reads served by this full node never touch the forwarder.
* Everything else — Docker image (`offchainlabs/nitro-node:v3.9.5-66e42c4`), `--chain.id=1625`, `--chain.info-json`, parent-chain URL, blob-client beacon URL, DA committee REST aggregator, and sequencer feed URL — is **identical** to the archive setup.

## Step 4 — Verify the node is healthy

1. Watch the container logs for pebble bringing the cache up:

   ```bash
   docker logs -f gravity-fullnode | grep -E "Allocated cache|created block"
   ```

   The first useful line is `Allocated cache and file handles ... cache=2.00GiB`. Shortly after, `created block l2Block=...` lines should begin scrolling several times per second while the node catches up to tip.
2. Query the local RPC for the head block:

   ```bash
   curl -s -X POST -H "Content-Type: application/json" \
       --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' \
       http://127.0.0.1:8547
   ```

   The returned block number should increase on each call until it converges with the public tip.
3. Confirm there are no `MissingTrieNode` errors during catch-up:

   ```bash
   docker logs gravity-fullnode 2>&1 | grep -i MissingTrieNode || echo "clean"
   ```

   Validated against this snapshot, the node catches up cleanly at roughly seven blocks per second with no `MissingTrieNode` errors.

## Notes

* The snapshot only contains chaindata. The container will generate its own `nodekey`, `jwtsecret`, and logs on first boot.
* The snapshot was prepared in full-node shape; archive-only state tries that would otherwise pad the dataset are not included, so this snapshot is **not** suitable for an archive node. Use the Conduit-hosted snapshot referenced in [Alpha Mainnet (L2) Archive Node Setup](/legacy-alpha-mainnet-l2/run-a-gravity-alpha-mainnet-l2-archive-node) if you need archive mode.
* Once started, this node participates in the standard Gravity Alpha Mainnet (L2) Anytrust DA committee and reads ordering from the Conduit sequencer feed — there is no operational difference at the network level from a node bootstrapped via the archive-mode flow.


# Sepolia Testnet (L2) Node Setup

Instructions about how to run a Gravity Alpha Testnet Sepolia node.

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

{% hint style="warning" %}
We'd like to inform you that ArbOS32 will be activated on Gravity chain in the new year, and we are migrating from AnyTrust to Celestia for data availability.

Prior to April 18th, 2025, please do the following:

* Upgrade to Node version nitro-node >= v3.3.2 (Celestia fork)
* Configure your node to support both data availability sources
  {% endhint %}

### Guide

#### Prerequisites

1. A local directory for storing node data
2. An Ethereum Sepolia RPC endpoint with unlimited rate limit for eth\_getLogs
3. An Ethereum Sepolia beacon chain RPC endpoint
4. Connection to a Celestia lightnode or public testnet RPC endpoint

#### Node & DAS Server Setup

1. **Setup the Celestia DAS Server**

   * Repository: [https://github.com/celestiaorg/nitro-das-celestia/](https://github.com/celestiaorg/nitro-das-celestia/tree/main)
   * Configuration for testnet:

   ```bash
   docker run -d --rm --name celestia-das-server \
       -p 9876:9876 \
       --entrypoint /bin/celestia-server \
       ghcr.io/celestiaorg/nitro-das-celestia:v0.4.1 \
       --enable-rpc --rpc-addr=0.0.0.0 --rpc-port=9876 \
       --celestia.rpc=<YOUR_CELESTIA_TESTNET_ENDPOINT>\
       --celestia.namespace-id=<TESTNET_NAMESPACE_ID> 
   ```
2. **Connect to a Celestia testnet RPC endpoint**
   * Use [testnet RPC endpoints](https://docs.celestia.org/how-to-guides/mocha-testnet#production-rpc-endpoints)

#### Download Snapshot (Recommended)

Syncing a node from scratch can be extremely time-consuming and resource-intensive. We strongly recommend downloading our latest snapshot:

1. [Download Gravity L2 Sepolia Testnet Node Snapshot](https://storage.googleapis.com/conduit-networks-snapshots/gravity/testnet/latest.tar)

#### Running the node

Save the following script as `run-gravity-testnet-node.sh`, make it executable with `chmod +x run-gravity-node.sh`, and update the TODO variables:

```bash
#!/bin/bash

# Define dependent variables
LOCAL_DIR="TODO"                      # Replace with your local directory path
ETH_SEPOLIA_RPC="TODO"                 # Replace with your Ethereum Sepolia testnet RPC endpoint
ETH_SEPOLIA_BEACON_RPC="TODO"          # Replace with your Ethereum Sepolia beacon RPC endpoint
CELESTIA_DAS_URL="TODO"                # Replace with your Celestia DAS server URL (e.g., http://localhost:9876)

# Run the Docker container
docker run --rm -it \
    --add-host=host.docker.internal:host-gateway \
    -v "$LOCAL_DIR:/home/user/.arbitrum" \
    -p 0.0.0.0:8547:8547 \
    -p 0.0.0.0:8548:8548 \
    ghcr.io/celestiaorg/nitro:v3.3.2 \
    --parent-chain.connection.url="$ETH_SEPOLIA_RPC" \
    --chain.id=13505 \
    --chain.name=conduit-orbit-deployer \
    --http.api=net,web3,eth \
    --http.corsdomain="*" \
    --http.addr=0.0.0.0 \
    --http.vhosts="*" \
    --persistent.db-engine="pebble" \
    --chain.info-json='[
        {
            "chain-id": 13505,
            "parent-chain-id": 11155111,
            "chain-name": "conduit-orbit-deployer",
            "chain-config": {
                "chainId": 13505,
                "homesteadBlock": 0,
                "daoForkBlock": null,
                "daoForkSupport": true,
                "eip150Block": 0,
                "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                "eip155Block": 0,
                "eip158Block": 0,
                "byzantiumBlock": 0,
                "constantinopleBlock": 0,
                "petersburgBlock": 0,
                "istanbulBlock": 0,
                "muirGlacierBlock": 0,
                "berlinBlock": 0,
                "londonBlock": 0,
                "clique": {
                    "period": 0,
                    "epoch": 0
                },
                "arbitrum": {
                    "EnableArbOS": true,
                    "AllowDebugPrecompiles": false,
                    "DataAvailabilityCommittee": true,
                    "InitialArbOSVersion": 11,
                    "InitialChainOwner": "0x218a4534C699CE35dc929ff4ca845C05Af9A57a2",
                    "GenesisBlockNum": 0
                }
            },
            "rollup": {
                "bridge": "0x946CF7F3238537e51B017369E523425A18996C23",
                "inbox": "0xe50eBd835F5f17fdEC0A547c37343F080B664357",
                "sequencer-inbox": "0x3eb7334755Fb41dC01400B15C8cC0C64B36E5969",
                "rollup": "0xDE145C4Ef9699D130848167d512dD1D09f173066",
                "validator-utils": "0xb33Dca7b17c72CFC311D68C543cd4178E0d7ce55",
                "validator-wallet-creator": "0x75500812ADC9E51b721BEa31Df322EEc66967DDF",
                "deployed-at": 5979967
            }
        }
    ]' \
    --node.data-availability.enable \
    --node.data-availability.rest-aggregator.enable \
    --node.data-availability.rest-aggregator.urls=https://das-gravity-testnet-sepolia-34ow2embsc.t.conduit.xyz \
    --node.celestia-cfg.enable=true \
    --node.celestia-cfg.url="$CELESTIA_DAS_URL" \
    --execution.forwarding-target=https://rpc-sepolia.gravity.xyz \
    --node.feed.input.url=wss://relay-gravity-testnet-sepolia-34ow2embsc.t.conduit.xyz \
    --parent-chain.blob-client.beacon-url="$ETH_SEPOLIA_BEACON_RPC"
```

### References

For more information, please check out the following guides:

1. <https://docs.arbitrum.io/node-running/how-tos/running-an-orbit-node>
2. <https://docs.conduit.xyz/guides/run-a-node/arbitrum-node>
3. <https://docs.celestia.org/how-to-guides/arbitrum-full-node>


# How to Get G (Gravity Alpha, L2)

Learn the different methods to acquire G tokens through bridges, exchanges, and direct purchases on Gravity Alpha Mainnet (L2).

{% hint style="danger" %}
**Action required — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) users should move **all** assets back to Ethereum before **November 1, 2026**. See [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

{% hint style="info" %}
This page covers bridging and acquiring G on the legacy **Gravity Alpha Mainnet (L2, chainId `1625`)**. The onboarding flow for Gravity Chain (L1) will be documented separately once it is available.
{% endhint %}

### Option 1: [Gravity Bridge Solutions](https://bridge.gravity.xyz/)

The Gravity Bridge offers cross-chain solutions for seamless asset transfers between different blockchains and the Gravity Alpha Mainnet. You can transfer assets to Gravity Alpha Mainnet through two options: our native bridge, which provides optimized transfers specifically for G, DAI, and WBTC tokens; or through our integration with LI.FI as a routing provider, which supports a wider range of ERC-20 tokens.

1. **Native Canonical Bridge**: Our purpose-built bridge optimized specifically for G, DAI, and WBTC tokens, providing efficient and secure transfers.
2. **LiFi-Powered Multi-Token Bridge**: An extended bridging solution supporting a wide range of ERC-20 tokens beyond our core assets, leveraging LiFi's cross-chain infrastructure.

#### Native Canonical Bridge

The native canonical bridge is designed to connect **Gravity Alpha Mainnet with Ethereum**. This bridge supports specific tokens:

| Token | Ethereum Address                           | Gravity Address                            |
| ----- | ------------------------------------------ | ------------------------------------------ |
| WBTC  | 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599 | 0x729ed87bbE7B7e4B7F09BCb9c668580818d98BB9 |
| DAI   | 0x6B175474E89094C44Da98b954EedeAC495271d0F | 0xBFBBc4dA47508e85AC18DFC961fa182194E85f9a |
| G     | 0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649 | Native Gas Token of Gravity                |

***Important Timeframes:***

* **Ethereum to Gravity**: When bridging tokens from Ethereum Mainnet to Gravity Alpha Mainnet, you will need to wait at least 10 minutes for the bridging process to complete.
* **Gravity to Ethereum**: When bridging tokens from Gravity Alpha Mainnet to Ethereum Mainnet, after submitting the transaction, you will need to wait 7 days to claim the funds on the Ethereum Mainnet.

***Why do I have to wait 7 days for withdrawing funds to Ethereum mainnet?***

This is how all optimistic rollups work. Optimistic rollups use a mechanism called fraud proofs to ensure participants in the network remain honest. There is a "challenge period" for these proofs, where, when one party submits a claim about the state of the chain, another party has approximately 7 days to challenge that claim.

***Why do I need G tokens on Ethereum mainnet when I bridge other assets to Gravity Alpha Mainnet?***

Bridging assets from the Ethereum mainnet to Gravity Alpha Mainnet involves two transactions. The first transaction is initiated on the Ethereum mainnet, and the second is a system transaction on the Gravity Alpha Mainnet that distributes funds to the recipient. Since Gravity Alpha Mainnet is an Arbitrum Nitro rollup, the cost of the system transaction on the Gravity Alpha Mainnet must be covered by the initiating transaction on the Ethereum mainnet. Additionally, since the Gravity Alpha Mainnet uses G tokens, the initial deposit transaction also requires some G tokens. To learn more about how canonical bridges work in general, [read this article](https://li.fi/knowledge-hub/the-evolution-of-native-bridges/).

#### LiFi Bridge Integration

For tokens other than G, DAI, and WBTC, our interface integrates with[ LI.FI](https://li.fi/) as a routing provider. This allows for a wider range of supported tokens and source networks.

#### Using the Bridge Interface

Visit this website: <https://bridge.gravity.xyz/>

Step 1: Configure Source Token

* Connect your wallet
* Select your source blockchain network
* Choose the token you want to bridge
* Enter the amount you wish to exchange

Step 2: Review Destination Details

* Destination will be default set to G Token on Gravity Alpha Mainnet
* View the estimated amount you'll receive
* Check current exchange rate and price impact

Step 3: Select Bridge Route

* Compare available routes based on:
  * 💰 Expected return amount
  * ⚡ Transaction speed
  * 🏷️ Gas fees
  * ⏱️ Estimated completion time
* Choose between "Best Return" or "Fastest" options
* When you select G, DAI, or WBTC for transfer between Ethereum Mainnet and Gravity Alpha Mainnet, it will automatically use the native bridge route

Step 4: Gas Management

* Check for "Get Gravity gas" notification
* If prompted, enable this option to:
  * Automatically include required G tokens
  * Ensure sufficient gas for bridge completion
  * Cover future transactions on Gravity Alpha Mainnet

Step 5: Configure Settings (Optional)

* Click the ⚙️ icon besides the wallet button
* Adjust route priority if needed
* Select gas price (Slow/Normal/Fast)
* Choose slippage tolerance (Auto/0.5%)

#### Methods to Bridge Assets

In the [website](https://bridge.gravity.xyz/), you can also choose from three methods to acquire G tokens on Gravity Alpha Mainnet:

1\. ONCHAIN Bridge: Directly bridge tokens from other networks using our cross-chain bridge powered by LIFI protocol.

2\. CEX Trading: Purchase through supported centralized exchanges

3\. FIAT Purchase: Buy directly using traditional currencies

### Option 2: [Stargate V2 Hydra](https://stargate.finance/bridge)

For USDC/USDT/wETH, Gravity chain adopted the [Stargate V2 Hydra system](https://stargateprotocol.gitbook.io/stargate/v/v2-user-docs/whats-new-in-stargate-v2/hydra) for better user experience. With Hydra, users can bridge these tokens between any supported chain and Gravity Alpha Mainnet.

<table><thead><tr><th width="168">Token</th><th>Contract on Ethereum Mainnet</th><th>Contract on Gravity</th></tr></thead><tbody><tr><td>ETH/WETH</td><td>Native token of Ethereum Mainnet</td><td>0xf6f832466Cd6C21967E0D954109403f36Bc8ceaA</td></tr><tr><td>USDT</td><td>0xdac17f958d2ee523a2206206994597c13d831ec7</td><td>0x816E810f9F787d669FB71932DeabF6c83781Cd48</td></tr><tr><td>USDC</td><td>0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48</td><td>0xFbDa5F676cB37624f28265A144A48B0d6e87d3b6</td></tr></tbody></table>

### Option 3: [Symbiosis](https://app.symbiosis.finance/swap?chainIn=Gravity\&chainOut=Gravity\&tokenIn=0xFbDa5F676cB37624f28265A144A48B0d6e87d3b6\&tokenOut=G)

For ***quick*** bridging G token using existing liquidity pools between **Gravity Alpha Mainnet <> BNB Chain <> Ethereum <> Base**

<table><thead><tr><th width="100">Token</th><th width="385">Contract on Ethereum, BNB Chain, and Base</th><th>Contract on Gravity</th></tr></thead><tbody><tr><td>G</td><td>0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649</td><td>Native token of Gravity Alpha Mainnet</td></tr></tbody></table>

### Option 4: Bridge Programmatically with Arbitrum SDK

We have created a demo to guide you through the process of bridging assets between Ethereum and Gravity programmatically using the Arbitrum SDK. You can access the demo and follow along with the code and steps provided in the [GitHub repository](https://github.com/Galxe/gravity-bridge-demo).

​


# Bridge Assets back to Ethereum (Gravity Alpha, L2)

Move G and other assets from Gravity Alpha Mainnet (L2) back to Ethereum mainnet.

{% hint style="danger" %}
**Action required — bridge out before November 1, 2026.** Please move **all** of your assets off Gravity Alpha Mainnet (L2) back to Ethereum before **November 1, 2026**. The network is unsettled in **December 2026**.

**Different assets use different routes, and they are not interchangeable** — see [Which route does my asset use?](#which-route-does-my-asset-use) below before you start.
{% endhint %}

{% hint style="info" %}
This page covers **withdrawing** assets from the legacy **Gravity Alpha Mainnet (L2, chainId `1625`)** to Ethereum mainnet. To bring assets in, see [How to Get G (on Gravity Alpha Mainnet, L2)](/legacy-alpha-mainnet-l2/bridge-to-gravity).
{% endhint %}

## Which route does my asset use?

Gravity Alpha Mainnet holds two different kinds of tokens, and each kind has exactly one way out.

| Asset          | How it got here                                | Exit route                                           | Can the canonical bridge withdraw it? |
| -------------- | ---------------------------------------------- | ---------------------------------------------------- | ------------------------------------- |
| **G**          | native token                                   | [Gravity Bridge](https://bridge.gravity.xyz/)        | ✅ Yes                                 |
| **DAI**        | Arbitrum standard ERC-20 gateway               | [Gravity Bridge](https://bridge.gravity.xyz/)        | ✅ Yes                                 |
| **WBTC**       | Arbitrum standard ERC-20 gateway               | [Gravity Bridge](https://bridge.gravity.xyz/)        | ✅ Yes                                 |
| **USDC**       | Stargate (issued as `Bridged USDC (Stargate)`) | [Stargate](https://stargate.finance/bridge) **only** | ❌ **No**                              |
| **USDT**       | Stargate                                       | [Stargate](https://stargate.finance/bridge) **only** | ❌ **No**                              |
| **ETH / WETH** | Stargate                                       | [Stargate](https://stargate.finance/bridge) **only** | ❌ **No**                              |

{% hint style="danger" %}
**USDC, USDT and ETH/WETH cannot be withdrawn through the canonical bridge.** These tokens were issued on Gravity Alpha Mainnet by Stargate, not by the Arbitrum standard gateway — the rollup's canonical bridge has no record of them and cannot process them. [**Stargate**](https://stargate.finance/bridge) **is the only way to move them off this network.** Do not wait for another route to appear.
{% endhint %}

## Bridge G (and DAI, WBTC) back to Ethereum — official Gravity bridge

Use the official [Gravity Bridge](https://bridge.gravity.xyz/) (native canonical route) to move **G** from Gravity Alpha Mainnet back to Ethereum mainnet.

1. Open <https://bridge.gravity.xyz/> and connect your wallet.
2. Set the **source** network to **Gravity Alpha Mainnet** and the **destination** to **Ethereum**.
3. Select **G**, enter the amount, and submit the withdrawal transaction — the native canonical route is used automatically for G.

The native canonical bridge also handles **DAI** and **WBTC** the same way.

{% hint style="warning" %}
**7-day withdrawal delay.** Like all optimistic rollups, native withdrawals from Gravity Alpha Mainnet to Ethereum have a \~7-day challenge period before the funds can be claimed on Ethereum. Start well before the November 1, 2026 deadline so your withdrawal has time to complete. If you need G on Ethereum sooner, a liquidity-pool route such as [Symbiosis](https://app.symbiosis.finance/swap) can bridge G in minutes instead of the 7-day wait.
{% endhint %}

## Bridge USDC, USDT and ETH/WETH back to Ethereum — Stargate

For **USDC, USDT and ETH/WETH**, use [Stargate](https://stargate.finance/bridge). Stargate uses liquidity pools (Stargate V2 Hydra), so transfers settle in minutes — there is no 7-day rollup wait.

1. Open <https://stargate.finance/bridge> and connect your wallet.
2. Set **From** to **Gravity** (Alpha Mainnet) and **To** to **Ethereum** — or any other chain Stargate supports.
3. Select the asset, enter the amount, and confirm.

{% hint style="warning" %}
**On Stargate, USDC is listed as `USDC.e`** — not `USDC`. If you search for "USDC" you may not find your balance. The three assets appear as **`USDC.e`**, **`USDT`** and **`WETH`** with **Gravity** as the source network.
{% endhint %}

Stargate can also send these assets directly to chains other than Ethereum — including BNB Chain, Base, Arbitrum, Polygon, Avalanche, OP Mainnet and others — so you do not have to route through Ethereum if your destination is elsewhere.

| Asset      | Symbol on Stargate | Contract on Gravity Alpha Mainnet          | Contract on Ethereum                       |
| ---------- | ------------------ | ------------------------------------------ | ------------------------------------------ |
| USDC       | `USDC.e`           | 0xFbDa5F676cB37624f28265A144A48B0d6e87d3b6 | 0xA0b86991c6218b36c1D19D4a2e9Eb0cE3606eB48 |
| USDT       | `USDT`             | 0x816E810f9F787d669FB71932DeabF6c83781Cd48 | 0xdAC17F958D2ee523a2206206994597C13D831ec7 |
| ETH / WETH | `WETH`             | 0xf6f832466Cd6C21967E0D954109403f36Bc8ceaA | Native ETH                                 |

{% hint style="info" %}
Keep a small amount of **G** on Gravity Alpha Mainnet to cover gas for the bridge transaction.
{% endhint %}

## See also

* [How to Get G (on Gravity Alpha Mainnet, L2)](/legacy-alpha-mainnet-l2/bridge-to-gravity) — bringing assets **in**.
* [Token Contracts on Gravity Alpha Mainnet (L2)](/legacy-alpha-mainnet-l2/token-contracts-on-gravity) — full address list.
* [Gravity Bridge](https://bridge.gravity.xyz/) · [Stargate](https://stargate.finance/bridge) · [Symbiosis](https://app.symbiosis.finance/swap)


# Token Contracts on Gravity Alpha (L2)

Explore a list of available ERC20 tokens on Gravity Alpha Mainnet (L2) Bridge.

{% hint style="danger" %}
**Action required — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).

**USDC, USDT and ETH/WETH can only exit via** [**Stargate**](https://stargate.finance/bridge) — they are Stargate-issued tokens and the canonical bridge cannot withdraw them.
{% endhint %}

{% hint style="info" %}
Addresses below are on the legacy **Gravity Alpha Mainnet (L2, chainId `1625`)**. For Gravity Mainnet (L1) token addresses, see [Token Contracts on Gravity](/the-g-token/token-contracts).
{% endhint %}

Gravity token list can be found on [**this github repo**](https://github.com/Galxe/gravity-token-list/blob/main/src/tokenlist.json). Submit the request to add yours.

<table><thead><tr><th width="139">Token</th><th width="199">Contract on Gravity</th><th width="202">Contract on Ethereum</th><th>Official Supported Bridge</th></tr></thead><tbody><tr><td>G</td><td>Native Token</td><td>0x9C7BEBa8F6eF6643aBd725e45a4E8387eF260649</td><td><a href="https://app.symbiosis.finance/swap?chainIn=Gravity&#x26;chainOut=Gravity&#x26;tokenIn=0xFbDa5F676cB37624f28265A144A48B0d6e87d3b6&#x26;tokenOut=G">Symbiosis</a></td></tr><tr><td>wG</td><td>0xBB859E225ac8Fb6BE1C7e38D87b767e95Fef0EbD</td><td>N/A</td><td></td></tr><tr><td>WBTC</td><td>0x729ed87bbE7B7e4B7F09BCb9c668580818d98BB9</td><td>0x2260fac5e5542a773aa44fbcfedf7c193bc2c599</td><td><a href="https://bridge.gravity.xyz">Canonical Bridge</a> (Arbitrum Nitro standard ERC20 gateway)</td></tr><tr><td>DAI</td><td>0xBFBBc4dA47508e85AC18DFC961fa182194E85f9a</td><td>0x6B175474E89094C44Da98b954EedeAC495271d0F</td><td><a href="https://bridge.gravity.xyz">Canonical Bridge</a> (Arbitrum Nitro standard ERC20 gateway)</td></tr><tr><td>ETH/WETH</td><td>0xf6f832466Cd6C21967E0D954109403f36Bc8ceaA</td><td>Native Token</td><td><a href="https://stargate.finance/bridge">Stargate V2 Hydra</a></td></tr><tr><td>USDT</td><td>0x816E810f9F787d669FB71932DeabF6c83781Cd48</td><td>0xdac17f958d2ee523a2206206994597c13d831ec7</td><td><a href="https://stargate.finance/bridge">Stargate V2 Hydra</a></td></tr><tr><td>USDC</td><td>0xFbDa5F676cB37624f28265A144A48B0d6e87d3b6</td><td>0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48</td><td><a href="https://stargate.finance/bridge">Stargate V2 Hydra</a></td></tr></tbody></table>


# Gravity Alpha Mainnet (L2) Contracts

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

{% hint style="info" %}
These are the rollup and gateway addresses for the legacy **Gravity Alpha Mainnet (L2, Arbitrum Nitro, chainId `1625`)**. Addresses for Gravity Chain (L1) are published separately.
{% endhint %}

### Core Contracts

| **Contract**           | **Address**                                |
| ---------------------- | ------------------------------------------ |
| rollup                 | 0xf993AF239770932A0EDaB88B6A5ba3708Bd58239 |
| inbox                  | 0x7AD2a94BefF3294a31894cFb5ba4206957a53c19 |
| outbox                 | 0x1153a1e4B1523DFf36f77d696bd6eBF2B0e7DAbF |
| adminProxy             | 0xBbc3872E30C91ef69336937838c2a283F79f7E68 |
| sequencerInbox         | 0x8D99372612e8cFE7163B1a453831Bc40eAeb3cF3 |
| bridge                 | 0x7983403dDA368AA7d67145a9b81c5c517F364c42 |
| utils                  | 0x2b0E04Dc90e3fA58165CB41E2834B44A56E766aF |
| validatorWalletCreator | 0x9CAd81628aB7D8e239F1A5B497313341578c5F71 |
| l3UpgradeExecutor      | 0xef8e170Ba5e43746213887DF50C186fB6Cc431FB |

### L2 Contracts

| **Contract**    | **Address**                                |
| --------------- | ------------------------------------------ |
| customGateway   | 0xa26Fd1c23634870303e42311E114D5cc8301Ed1E |
| multicall       | 0x7cdCB0Cc61f47B8Dd8f47C5A29edaDd84a1BDf5e |
| proxyAdmin      | 0xBbc3872E30C91ef69336937838c2a283F79f7E68 |
| router          | 0x8713569d016f981D956715e9EE2795382168b5c0 |
| standardGateway | 0xb23988D9728EF147EAa02D602D7e067B6131A1bB |
| weth            | 0x0000000000000000000000000000000000000000 |
| wethGateway     | 0x0000000000000000000000000000000000000000 |

### L3 Contracts

| **Contract**    | **Address**                                |
| --------------- | ------------------------------------------ |
| customGateway   | 0xC18EADE2B2CdA6AcFAc4fd2226C724a1008b02Ab |
| multicall       | 0xABF31e3A13528082cE5bb05D6E88749556DAFD5F |
| proxyAdmin      | 0xB881cf085a78491AaA71Bf22bc87E67865a4409a |
| router          | 0xf1cA401FB474520EbaBb285670891dEbd7C505Bc |
| standardGateway | 0xD330E617270F375Bd476896f3A8AE9041264E13d |
| weth            | 0x0000000000000000000000000000000000000000 |
| wethGateway     | 0x0000000000000000000000000000000000000000 |


# Gravity Alpha Sepolia Testnet (L2) Contracts

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

{% hint style="info" %}
These are the rollup and gateway addresses for the legacy **Gravity Alpha Sepolia Testnet (L2, Arbitrum Nitro, chainId `13505`)**. For the Gravity Chain (L1) testnet, see [Gravity Longevity Testnet (L1)](/gravity-networks/l1-longevity-testnet).
{% endhint %}

### Core Contracts

| **Contract**           | **Address**                                |
| ---------------------- | ------------------------------------------ |
| rollup                 | 0x68103ED1d4E25C2f92707c82d5e420268A4F5Bf8 |
| inbox                  | 0xAaFb8764055A5CF534F40A3C2b96F51cc2736E27 |
| outbox                 | 0x24f7796702124E6cfe3Ee95BaC5Dc3D85dc9f2BF |
| adminProxy             | 0xE02283CC2a52837b4218427F3B1c20b086df0E18 |
| sequencerInbox         | 0xAEfA8B6aB59c0cd098cbBEA234434946d154a7A5 |
| bridge                 | 0x04e9f0f84C1EB8ad8b42861DD4ee349F126cdeAE |
| utils                  | 0x617DF25FeeC04E1Fc7c031e146229Dadd16758f3 |
| validatorWalletCreator | 0x3D23095e9fC3FdB373F1Ba2777f2E6e9a3644321 |
| l3UpgradeExecutor      | 0x81844D7915b389faFe938CA156CFD6998af26c90 |

### L2 Contracts

| **Contract**    | **Address**                                |
| --------------- | ------------------------------------------ |
| customGateway   | 0xe909715E3eEC9fBE4675245FF37B2Cba5231630F |
| multicall       | 0x73465577E9FD7Cd585E4270F23A9eBa99B92b6eD |
| proxyAdmin      | 0x0000000000000000000000000000000000000000 |
| router          | 0x648103e7bF7DD0465DE0F5302E18C4FD46A82777 |
| standardGateway | 0x399CD8C927F657FA371C425EF1d063F301659788 |
| weth            | 0x0000000000000000000000000000000000000000 |
| wethGateway     | 0x0000000000000000000000000000000000000000 |

### L3 Contracts

| **Contract**    | **Address**                                |
| --------------- | ------------------------------------------ |
| customGateway   | 0x730EcA29f7A17952Fe8B44e324083944f73e4544 |
| multicall       | 0xf1A7Ff9a701b1d47b3020b7b90EfF8650B53D5Bb |
| proxyAdmin      | 0x44A4aBC26cEef42B09D67743f2680bF7aE5f82e2 |
| router          | 0x4E78fAB9C8e6E8BDDf80330F5523116FA8484826 |
| standardGateway | 0x8c82825b115ba53A77b1d6b6c72D14C6D95a2AB1 |
| weth            | 0x0000000000000000000000000000000000000000 |
| wethGateway     | 0x0000000000000000000000000000000000000000 |


# Verify a Smart Contract (Gravity Alpha, L2)

Verify your smart contract on Gravity Alpha Mainnet (L2).

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

{% hint style="info" %}
This guide applies to the legacy **Gravity Alpha Mainnet (L2, Arbitrum Nitro rollup, chainId `1625`)**. A separate guide will be published for Gravity Chain (L1) once its explorer verification flow is available.
{% endhint %}

## [OKLink](https://www.oklink.com/gravity-alpha)

There are four major ways to verify contracts on OKLink:

### 1. Explorer Interface

You can verify a deployed contract directly through the [OKLink interface](https://web3.okx.com/explorer/gravity-alpha/verify-contract-preliminary).

### 2. Contract Verification APIs

OKLink provides a set of [contract verification APIs](https://www.oklink.com/docs/en/#developer-tools-contract-verification).

### 3. Verify Using Foundry

**Prerequisite: Get an OKLink API Key**

Apply for an API key:\
<https://www.oklink.com/account/my-api>

**Run `forge verify-contract`**

To verify a contract, you need to provide:

* The deployed contract address
* The contract path and name (e.g., `src/MyToken.sol:MyToken`)
* The OKLink `verify-url` for your target chain
* Your OKLink API key

Command format:

```bash
forge verify-contract <contract_address> \
  src/MyToken.sol:MyToken \
  --verifier oklink \
  --verifier-url https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity \
  --api-key <Your_OKLink_API_Key> \
  --watch
```

**Check Verification Status**

It is recommended to use the `--watch` flag to continuously poll for verification status.

If you didn’t use `--watch`, you can manually check the result using:

```bash
forge verify-check <contract_address> --verifier oklink
```

### 4. Verify Using Hardhat

#### Method 1 (Recommended): Using `@okxweb3/hardhat-explorer-verify` Plugin

This method uses an official Hardhat plugin provided by OKX. It provides a CLI command (`npx hardhat okverify`) to automate contract verification.

**1. Install the Plugin**

```bash
npm install @okxweb3/hardhat-explorer-verify
```

**2. Configure `hardhat.config.ts`**

Here is a sample configuration for Gravity Chain:

```ts
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@okxweb3/hardhat-explorer-verify";

const config: HardhatUserConfig = {
  solidity: "0.8.24",
  sourcify: {
    enabled: true,
  },
  networks: {
    gravity: {
      url: "https://rpc.gravity.xyz",
      accounts: ["<Your Private Key>"],
    },
  },
  okxweb3explorer: {
    apiKey: "<Your OKLink API Key>",
    customChains: [
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL:
            "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity",
          browserURL: "https://www.oklink.com",
        },
      },
    ],
  },
};

export default config;
```

**3. Verify the Contract**

After deployment, verify with:

```bash
npx hardhat okverify --network gravity <ContractAddress>
```

**4. Verifying Proxy Contracts**

For contracts deployed via `TransparentUpgradeableProxy`, use:

```bash
npx hardhat okverify --network gravity --contract contracts/MyContract.sol:MyContract --proxy <ProxyAddress>
```

If you're using the 897 proxy standard, omit `--proxy` and just run the command as normal

#### Method 2: Manually Configuring `etherscan.customChains` for OKLink

You can also verify contracts using Hardhat's native Etherscan integration by overriding the default verification endpoint.

**Configuration Example:**

```js
module.exports = {
  etherscan: {
    apiKey: "<Your OKLink API Key>",
    customChains: [
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL:
            "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity",
          browserURL: "https://www.oklink.com",
        },
      },
    ],
  },
};
```

This enables Hardhat’s built-in `verify` task to interact with OKLink:

```bash
npx hardhat verify --network gravity <ContractAddress> <ConstructorArguments...>
```

> ⚠️ You’ll still need to ensure your contract metadata matches what OKLink expects (e.g., compiler version, optimization settings, source flattening if needed).

***

## [Blockscout](https://explorer.gravity.xyz)

{% hint style="info" %}
Blockscout uses the global blockscout verifier (so that similar contracts get automatically verified), it can sometimes be flaky. Please try again a bit later.

For contracts deployed by `create2,` you may ran into *Fail - Unable to verify.* You will have to visit the contract address page after deployment first. Then blockscout will fetch it from the RPC and see that it is a contract, then verification should work.\
Contract address page: `https://explorer.gravity.xyz/address/***`
{% endhint %}

For [hardhat](https://hardhat.org/) users, you will need to change your `hardhat.config.ts` to something like the following example:

```
  etherscan: {
    apiKey: {
      // ...
      // Not required. Can be any non-empty string
      gravity: "abc",
    },
    customChains: [
      // ...
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL: "https://gscan.xyz/api",
          browserURL: "https://gscan.xyz",
          // For Blockscout
          // apiURL: "https://explorer.gravity.xyz/api",
          // browserURL: "https://explorer.gravity.xyz",
        },
      }
    ],
  },
  networks: {
    // ...
    gravity: {
      url: "https://rpc.gravity.xyz",
      chainId: 1625,
      accounts,
    },
  },
```

For [foundry](https://book.getfoundry.sh/) users, we recommend you to use [scripts](https://book.getfoundry.sh/tutorials/solidity-scripting) to deploy your contracts. You will need to configure the `foundry.toml` file as the following:

```
[etherscan]
# Gravity explorer does not require an API key, any non-empty string will do.
# gscan
gravity = { key = "abc", url="https://gscan.xyz/api", chain = 1625 }
# Blockscout
# gravity = { key = "abc", url="https://explorer.gravity.xyz/api", chain = 1625 }
```

Then you when you run your scripts, you can verify contracts deployed with `--verify` option.

```
forge script --chain 1625 script/YOUR_SCRIPT.s.sol:YOUR_SCRIPT --rpc-url $GRAVITY_RPC_URL --broadcast --verify -vvvv
```

NOTE: If contracts were deployed successfully but verification failed, DO NOT delete the `broadcast/` directory. You can resume the verification process by removing the `--broadcast` option and providing the deployment transaction sender's key like below: (or you can configure it in cast):

```
forge script --chain 1625 script/YOUR_SCRIPT.s.sol:YOUR_SCRIPT --private-key $PRIVATE_KEY --rpc-url  $GRAVITY_RPC_URL --verify -vvvv
```


# Oracles (legacy L2)

Third-party oracle integrations from the legacy Gravity Alpha Mainnet (L2). Gravity Mainnet (L1) is integrating a range of oracle services; Native Oracle is supported by default for now.

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

> **Legacy.** This page documents third-party oracle integrations from the legacy **Gravity Alpha Mainnet (L2)**. **Gravity Mainnet (L1)** is integrating a range of oracle services; for now the protocol-level [**Native Oracle**](/research-and-development/native-oracle) — validator-attested external data with consensus-grade security — is supported by default.

## Overview

Blockchain oracles act as bridges between smart contracts and real-world data. They provide essential off-chain information such as price feeds, random numbers, and event outcomes that blockchains cannot access natively. Oracles vary in design, with some using push models (regular on-chain updates) and others using pull models (on-demand data requests). The quality of an oracle is measured by its speed, accuracy, cost-efficiency, and security against manipulation.

## Third-Party Oracles

### Pyth

The [Pyth Network](https://pyth.network/) is the largest first-party Oracle network, delivering real-time data across [a vast number of chains](https://docs.pyth.network/price-feeds/contract-addresses). Pyth introduces an innovative low-latency [pull oracle design](https://docs.pyth.network/documentation/pythnet-price-feeds/on-demand), where users can pull price updates on-chain when needed, enabling everyone in the blockchain environment to access that data point most efficiently. Pyth network updates the prices every 400ms, making Pyth the fastest on-chain oracle.

Users can also opt to use push model oracles through Pyth by running a [scheduler](https://docs.pyth.network/price-feeds/schedule-price-updates/using-scheduler).

Pyth Oracle Features:

* 400ms latency
* Most efficient and cost-effective Oracle
* [First-party](https://pyth.network/publishers) data sourced directly from financial institutions
* [Price feeds ranging from Crypto, Stock, FX, Metals](https://pyth.network/developers/price-feed-ids)
* [Available on all the largest chains](https://docs.pyth.network/price-feeds/contract-addresses)

Check out the following links to get started with Pyth.

* [Pyth EVM Integration Guide](https://docs.pyth.network/price-feeds/use-real-time-data/evm)
* [Pyth Docs](https://docs.pyth.network/home)
* [Pyth API Reference](https://api-reference.pyth.network/price-feeds/evm/getPrice)
* [Pyth Examples](https://github.com/pyth-network/pyth-examples)
* [Pyth Price Feed Ids](https://pyth.network/developers/price-feed-ids)
* [Website](https://pyth.network/)
* [Twitter](https://x.com/PythNetwork)


# Indexers (legacy L2)

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

> **Legacy.** This page documents The Graph on the legacy **Gravity Alpha Mainnet (L2)** — the `gravity-mainnet` subgraph listed below. It does not apply to Gravity Mainnet (L1).

## Overview

Blockchain indexers are specialized tools or services that extract, process, and organize data from blockchain networks, transforming it into formats that are easily queryable and accessible for developers and applications. Given that blockchain data is inherently decentralized and stored in a sequential manner, retrieving specific information can be challenging. Indexers address this by creating structured databases or APIs, enabling efficient data retrieval and analysis.

## Indexers

### The Graph

The Graph is a decentralized indexing protocol that allows developers to build and publish open APIs, known as subgraphs, which applications can query using GraphQL. Indexers in The Graph Network operate nodes that index these subgraphs and serve queries, earning rewards for their services.

#### Supported Networks

| Network                           | ID                | Documentation                                       |
| --------------------------------- | ----------------- | --------------------------------------------------- |
| Gravity Alpha Mainnet (legacy L2) | `gravity-mainnet` | [View Documentation](https://thegraph.com/docs/en/) |


# Gravity Name Service (legacy L2)

SPACE ID Web3 Name SDK (legacy Gravity Alpha Mainnet, L2)

{% hint style="danger" %}
**Legacy network — bridge out before November 1, 2026.** Gravity Alpha Mainnet (L2) is being deprecated in favor of [Gravity Mainnet (L1)](/gravity-networks/l1-mainnet) and will be unsettled in **December 2026**. Move all assets back to Ethereum before **November 1, 2026** — see [Bridge Assets back to Ethereum](/legacy-alpha-mainnet-l2/bridge-back-to-ethereum).
{% endhint %}

> **Legacy.** This page documents the SPACE ID `.g` name service on the legacy **Gravity Alpha Mainnet (L2, chain ID `1625`)** — the chain ID used in the resolution examples below.

### Overview[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#overview)

The primary capabilities of the SDK include:

1. Domain Name Resolution: It resolves domain names to obtain essential information about the domain, including its associated conventional address, various records (such as avatars, IPFS links, social data), and metadata, etc.
2. Reverse Resolution: The SDK facilitates reverse address resolution. This feature makes it possible to determine the primary domain name associated with a given address, even across different blockchains or TLDs, returning Chain Primary Name or TLD Primary Name.

#### Key Terminology:

TLD Primary Name:

* Every address is able to set TLD Primary Name to configure a reverse resolution domain for each Top-Level Domain, regardless of whether it has been verified or not on SPACE ID.
* Examples include setting "charles.eth" as TLD Primary Name for .eth, "charles.g" for .g, "charles.bnb" for .bnb.

Chain Primary Name:

* Each address is permitted to have only one unique Chain Primary Name for each blockchain or network.
* Specifically, when multiple TLDs verified on a single chain exist, only one domain name can be chosen as such reverse resolution domain for that particular chain.
* For instance, "charles.eth" could serve as Chain Primary Name for Ethereum, and "charles.g" might function as the primary name for Gravity Chain.

By default, all EVM-based domain names are supported for domain resolution in the Web3 Name SDK. Reverse resolution returns a Chain Primary Name for each EVM chain. Project administrators have the flexibility to choose whether to integrate support for all or only specific chains and TLDs. They can also configure custom settings for reverse resolution as needed. This adaptability allows projects to tailor the SDK's functionality to their specific requirements.

## Get Started[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#get-started)

Developers can resolve web3 domain name or reverse resolve conventional address with Web3 Name SDK with zero configuration.

### Install[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#install)

npm install @web3-name-sdk/core viem@^1.20

If you are using next.js, please add the following configuration in your next.config.js in order to transpile commonjs dependencies:

```
const nextConfig = {
   transpilePackages: ["@web3-name-sdk/core"],
};

```

#### 1. Setup client

```
import { createWeb3Name } from "@web3-name-sdk/core";

const web3Name = createWeb3Name();
```

#### 2. Resolve a domain name[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#2resolve-a-domain-name)

You can get address from domain name with a single request:

```
const address = await web3name.getAddress("gravity.g");

const address = await web3name.getAddress("bts_official.lens");

const address = await web3name.getAddress("beresnev.crypto");

const address = await web3name.getAddress("registry.g");
```

#### 3. Resolve an address[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#3-resolve-an-address)

There are optional parameters in the method to select your target chain or TLD (top-level Domain).

By providing chain IDs, you can resolve addresses on selected chains and get an available domain name from all TLDs deployed on these chains.

```
// Resolve an address from Gravity Chain
const name = await web3name.getDomainName({
   address: "0x2886d6792503e04b19640c1f1430d23219af177f",
   queryChainIdList: [1625],
});

```

By providing TLDs, address can be resolved from the selected TLDs and get an available TLD primary name.

```
// Resolve an address from .g TLD
const name = await web3name.getDomainName({
   address: "0x2886d6792503e04b19640c1f1430d23219af177f",
   queryTldList: ["g"],
});

```

#### 4. Record[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#4-record)

Domain text records can be fetched by providing domain name and the key. For example, the avatar record of gravity.g is returned from this method given key name avatar:

```
// const record = await sid.getDomainRecord({
   name: "gravity.g",
   key: "avatar",
});
```

#### 5. Metadata[​](https://docs.manta.network/docs/manta-pacific/Space%20ID#5-metadata)

Domain metadata can be fetched by SDK directly.

```
// requesting
const metadata = await web3Name.getMetadata({ name: "public.g" });
```


